import { TeDeumUtility } from "../common/tedeum-utility.js";
import { TeDeumActor } from "../actors/tedeum-actor.js";
export class TeDeumCharacterCreator {

  /*--------------------------------------------*/
  async init() {
    this.stages = {}
    this.currentStage = "origineSociale"
    this.sexe = undefined
    this.origineSociale = undefined
    this.religion = undefined
    this.caracBonus = {}
    this.competenceBonus = {}
    this.suiviReponses = []
    this.competences = TeDeumUtility.getCompetencesForDropDown()
    this.choiceSummary = {}

    for (let k in game.system.tedeum.config.caracteristiques) {
      this.caracBonus[k] = { value: 0 }
    }

    for (let stage in game.system.tedeum.config.etapesEducation) {
      this.stages[stage] = { selectedItem: null, items: [] }
    }

    const educations = await TeDeumUtility.loadCompendium("fvtt-te-deum.education")
    for (let edu of educations) {
      this.stages[edu.system.etape].items.push(edu)
    }

    this.processStage()
  }

  /*--------------------------------------------*/
  increaseCompetence(compName) {
    if (compName === "" || compName == undefined || compName == "undefined") { return }
    compName = compName.toLowerCase()
    if (!this.competenceBonus[compName]) {
      this.competenceBonus[compName] = { value: 1 }
    } else {
      this.competenceBonus[compName].value += 1
    }
    this.choiceSummary[this.currentStage].competences[compName] = 1
  }

  /*--------------------------------------------*/
  processReponses(question) {
    let fullResponses = []
    for (let key in question.reponses) {
      let response = question.reponses[key]
      fullResponses.push({ id: key, label: `${response.reponse} (${TeDeumUtility.upperFirst( response.compName)} +1)` })
    }
    return fullResponses
  }

  /*--------------------------------------------*/
  processReponsesRadio(question) {
    let fullResponses = {}
    let selected = true
    for (let key in question.reponses) {
      let response = question.reponses[key]
      if (response.toSelect) {
        fullResponses[key] = { label: `${response.reponse}`, competences: response.compList, selected }
      } else {
        fullResponses[key] = { label: `${response.reponse} (${response.compName} +1)`, selected }
      }
      selected = false
    }
    return fullResponses
  }

  /*--------------------------------------------*/
  async askStageName(context) {
    const content = await foundry.applications.handlebars.renderTemplate("systems/fvtt-te-deum/templates/dialogs/character-creator-select-stage-name.hbs", context)
    const choiceResult = await foundry.applications.api.DialogV2.wait({
      window: { title: context.title },
      classes: ["fvtt-te-deum"],
      content,
      buttons: [
        {
          label: context.label,
          callback: (event, button, dialog) => {
            const output = Array.from(button.form.elements).reduce((obj, input) => {
              if (input.name) obj[input.name] = input.value
              return obj
            }, {})
            return output
          },
        },
      ],
      actions: {
      },
      rejectClose: false, // Click on Close button will not launch an error
      render: (event, dialog) => {
        $(".stage-selector").change(event => {
          let stageId = event.target.value
          let stage = context.choices.find(item => item.id === stageId)
          let link = `<a class="content-link" draggable="true" data-link=""
              data-uuid="Compendium.fvtt-te-deum.education.Item.${stageId}" data-id="${stageId}" data-type="Item"
              data-pack="fvtt-te-deum.education" data-tooltip="Education Objet"><i class="fas fa-suitcase"></i>${stage.name}</a>`
          $(".stage-main-details").html(`Voir le détail : ${link}`)
        })

        document.getElementById("stage-selector").dispatchEvent(new Event('change'))

      }
    })
    return choiceResult
  }

  /*--------------------------------------------*/
  processCompetences(compList) {
    for (let compName in compList) {
      this.increaseCompetence(compName)
    }
  }

  /*--------------------------------------------*/
  async askQuestionnaire(stage, context) {
    context.subtitle = "Questionnaire"
    this.choiceSummary[this.currentStage].questionnaire = {}

    for (let key in stage.system.questionnaire) {
      let question = stage.system.questionnaire[key]
      if (question.question === "") { break }

      context.question = question.question
      context.responses = this.processReponses(question)
      context.responsesRadio = this.processReponsesRadio(question)
      context.competences = {}
      context.responseKey = "reponse1" // By default

      const content = await foundry.applications.handlebars.renderTemplate("systems/fvtt-te-deum/templates/dialogs/character-creator-select-questions.hbs", context)
      const choiceResult = await foundry.applications.api.DialogV2.wait({
        window: { title: context.title },
        classes: ["fvtt-te-deum"],
        content,
        buttons: [
          {
            label: context.label,
            callback: (event, button, dialog) => {
              const output = Array.from(button.form.elements).reduce((obj, input) => {
                if (input.name) obj[input.name] = input.value
                return obj
              }, {})
              return output
            },
          },
        ],
        actions: {
        },
        rejectClose: false, // Click on Close button will not launch an error
        render: (event, dialog) => {
          $(".questionnaire-radio").click(event => {
            let responseKey = $(event.target).data("response-key")
            context.responseKey = responseKey
          })
          $(".questionnaire-select-competence").change(event => {
            // Get the responseKey data
            let responseKey = $(event.target).data("response-key")
            let compName = event.target.value
            console.log("Questionnaire Change", responseKey, compName)
            context.competences[responseKey] = compName.toLowerCase()
          })
        }
      })
      if (choiceResult == null) {
        this.currentStage = "cancelled"
        return
      }

      let selectedResponse = question.reponses[context.responseKey]
      let compName = context.competences[context.responseKey] || selectedResponse.compName
      this.increaseCompetence(compName)

      this.suiviReponses.push({ key: this.currentStage, etape: stage.name, question: question.question, reponse: selectedResponse.reponse, compName: compName })
    }
  }

  /*------------- -------------------------------*/
  async askCompetences(stage, context) {
    context.subtitle = "Choix des Compétences"
    this.choiceSummary[this.currentStage].competences = {}

    context.fixedCompetences = {}
    context.selectCompetences = {}
    for (let compKey in stage.system.competences) {
      let comp = stage.system.competences[compKey]
      if (comp.valid && comp.compName !== "") {
        if (comp.toSelect) {
          context.hasSelectCompetences = true
          context.selectCompetences[comp.compName] = TeDeumUtility.upperFirst(comp.compName)
        } else {
          context.fixedCompetences[comp.compName] = TeDeumUtility.upperFirst(comp.compName)
        }
      }
    }

    const content = await foundry.applications.handlebars.renderTemplate("systems/fvtt-te-deum/templates/dialogs/character-creator-select-competences.hbs", context)
    const choiceResult = await foundry.applications.api.DialogV2.wait({
      window: { title: context.title },
      classes: ["fvtt-te-deum"],
      content,
      buttons: [
        {
          label: context.label,
          callback: (event, button, dialog) => {
            const output = Array.from(button.form.elements).reduce((obj, input) => {
              if (input.name) obj[input.name] = input.value
              return obj
            }, {})
            return output
          },
        },
      ],
      actions: {
      },
      rejectClose: false, // Click on Close button will not launch an error
      render: (event, dialog) => {
      }
    })
    if (choiceResult == null) {
      this.currentStage = "cancelled"
      return
    }
    context.fixedCompetences[choiceResult.selectedCompetence] = choiceResult.selectedCompetence
    this.processCompetences(context.fixedCompetences)

    // Handle specific case when multiple skills can be selected (ie compagnon case)
    if ( stage.system.hasCompetencesOpt ) {
      context.fixedCompetences = []
      context.hasSelectCompetences = true
      for (let i = 0; i < stage.system.competencesOptNumber; i++) {
        context.competences = {}
        context.selectCompetences = {}
        for (let compKey in stage.system.competencesOpt) {
          let comp = stage.system.competencesOpt[compKey]
          if (comp.compName !== "") {
            context.selectCompetences[comp.compName] = TeDeumUtility.upperFirst(comp.compName)
          }
        }

        const content = await foundry.applications.handlebars.renderTemplate("systems/fvtt-te-deum/templates/dialogs/character-creator-select-competences.hbs", context)
        const choiceResult = await foundry.applications.api.DialogV2.wait({
          window: { title: context.title },
          classes: ["fvtt-te-deum"],
          content,
          buttons: [
            {
              label: context.label,
              callback: (event, button, dialog) => {
                const output = Array.from(button.form.elements).reduce((obj, input) => {
                  if (input.name) obj[input.name] = input.value
                  return obj
                }, {})
                return output
              },
            },
          ],
          actions: {
          },
          rejectClose: false, // Click on Close button will not launch an error
          render: (event, dialog) => {
          }
        })
        if (choiceResult == null) {
          this.currentStage = "cancelled"
          return
        }
        context.fixedCompetences[choiceResult.selectedCompetence] = choiceResult.selectedCompetence
        this.processCompetences(context.fixedCompetences)
      }
    }

  }

  /*------------- -------------------------------*/
  async askCarac(stage, context) {
    context.subtitle = "Choix des Caractéristiques"
    this.choiceSummary[this.currentStage] = {
      caracBonus : {},
      competences : {}
    }

    let selected = []
    for (let i = 0; i < stage.system.nbChoixCarac; i++) {
      context.caracList = []
      for (let caracKey in stage.system.caracteristiques) {
        let carac = stage.system.caracteristiques[caracKey]
        if (selected.includes(carac.caracId)) { continue }
        context.caracList.push(game.system.tedeum.config.caracteristiques[carac.caracId])
      }

      const content = await foundry.applications.handlebars.renderTemplate("systems/fvtt-te-deum/templates/dialogs/character-creator-select-carac.hbs", context)
      const choiceResult = await foundry.applications.api.DialogV2.wait({
        window: { title: context.title },
        classes: ["fvtt-te-deum"],
        content,
        buttons: [
          {
            label: context.label,
            callback: (event, button, dialog) => {
              const output = Array.from(button.form.elements).reduce((obj, input) => {
                if (input.name) obj[input.name] = input.value
                return obj
              }, {})
              return output
            },
          },
        ],
        actions: {
        },
        rejectClose: false, // Click on Close button will not launch an error
        render: (event, dialog) => {
        }
      })
      if (choiceResult == null) {
        this.currentStage = "cancelled"
        return
      }
      this.caracBonus[choiceResult.carac].value += 1
      selected.push(choiceResult.carac)
      this.choiceSummary[this.currentStage].caracBonus[choiceResult.carac] = 1
    }
  }

  /*--------------------------------------------*/
  async renderOrigineSociale(stage) {
    let context = {
      title: "Création de personnage",
      subtitle: "Origine Sociale",
      sexeChoice: { "Homme": "Homme", "Femme": "Femme" },
      religionChoice: { "catholique": "Catholique", "protestante": "Protestante" },
      origineChoice: game.system.tedeum.config.origineSociale
    }

    const content = await foundry.applications.handlebars.renderTemplate("systems/fvtt-te-deum/templates/dialogs/character-creator-origine.hbs", context)
    const label = "Valider le choix de l'Origine Sociale"
    const choiceResult = await foundry.applications.api.DialogV2.wait({
      window: { title: context.title },
      classes: ["fvtt-te-deum"],
      content,
      buttons: [
        {
          label: label,
          callback: (event, button, dialog) => {
            const output = Array.from(button.form.elements).reduce((obj, input) => {
              if (input.name) obj[input.name] = input.value
              return obj
            }, {})
            return output
          },
        },
      ],
      actions: {
      },
      rejectClose: false, // Click on Close button will not launch an error
      render: (event, dialog) => { }
    })

    if (choiceResult == null) {
      this.currentStage = "cancelled"
      return
    }

    this.sexe = choiceResult.sexe
    this.religion = choiceResult.religion
    this.origineSociale = foundry.utils.duplicate(game.system.tedeum.config.origineSociale[choiceResult.origineSociale])
    for (let key in this.origineSociale.caracteristiques) {
      this.caracBonus[key].value += this.origineSociale.caracteristiques[key]
    }
    this.choiceSummary['origineSociale'] = {
      sexe: this.sexe,
      religion: this.religion,
      origineSociale: this.origineSociale.label,
      caracBonus: this.caracBonus,
    }
    this.currentStage = "pouponniere"

  }

  /*--------------------------------------------*/
  async renderPouponniere(stage) {

    // Filter available pouponniere from origineSociale
    let pouponniereItems = stage.items.filter(item => item.system.accessible[this.origineSociale.id].isaccessible)

    let context = {
      title: "Création de personnage - La Pouponnière",
      subtitle: "Choix de la Pouponnière",
      label: "Valider le choix de la Pouponnière",
      hasGenre: false,
      choices: pouponniereItems,
      caracBonus: this.caracBonus,
      competenceBonus: this.competenceBonus
    }
    let choiceResult = await this.askStageName(context)
    if (choiceResult == null) {
      this.currentStage = "cancelled"
      return
    }

    this.pouponniere = foundry.utils.duplicate(stage.items.find(item => item.id === choiceResult.selectedItem))
    context.title = `La Pouponnière - ${this.pouponniere.name}`
    TeDeumUtility.prepareEducationContent(this.pouponniere);
    this.choiceSummary['pouponniere'] = {}

    context.label = "Valider l'augmentation de caracteristique"
    await this.askCarac(this.pouponniere, context)

    context.label = "Valider l'augmentation de compétences"
    await this.askCompetences(this.pouponniere, context)

    context.label = "Valider cette réponse"
    await this.askQuestionnaire(this.pouponniere, context)

    this.currentStage = "petitsgrimauds"
  }

  /*--------------------------------------------*/
  async renderPetitsGrimauds(stage) {
    // Filter available pouponniere from origineSociale
    let grimaudsItems = stage.items.filter(item => item.system.accessible[this.origineSociale.id].isaccessible && (item.system.genre === this.sexe || item.system.genre === "Mixte"))

    let context = {
      title: "Les Petits Grimauds",
      label: "Valider le choix des Petits Grimauds",
      hasGenre: true,
      choices: grimaudsItems,
      caracBonus: this.caracBonus,
      competenceBonus: this.competenceBonus
    }

    let choiceResult = await this.askStageName(context)
    if (choiceResult == null) {
      this.currentStage = "cancelled"
      return
    }

    this.grimauds = foundry.utils.duplicate(stage.items.find(item => item.id === choiceResult.selectedItem))
    context.title = `LesPetits Grimauds - ${this.grimauds.name}`
    TeDeumUtility.prepareEducationContent(this.grimauds);

    context.label = "Valider l'augmentation de caracteristique"
    await this.askCarac(this.grimauds, context)
    context.label = "Valider l'augmentation de compétences"
    await this.askCompetences(this.grimauds, context)

    context.label = "Valider cette réponse"
    await this.askQuestionnaire(this.grimauds, context)

    this.currentStage = "rosevie"
  }

  /*--------------------------------------------*/
  async renderRosesDeLaVie(stage) {
    // Filter available pouponniere from origineSociale
    let rosesItems = stage.items.filter(item => item.system.accessible[this.origineSociale.id].isaccessible && (item.system.genre === this.sexe || item.system.genre === "Mixte"))

    let context = {
      title: "Création de personnage - Les Roses de la Vie",
      label: "Valider le choix des Roses de la Vie",
      choices: rosesItems,
      hasGenre: true,
      caracBonus: this.caracBonus,
      competenceBonus: this.competenceBonus

    }

    let choiceResult = await this.askStageName(context)
    if (choiceResult == null) {
      this.currentStage = "cancelled"
      return
    }

    this.roses = foundry.utils.duplicate(stage.items.find(item => item.id === choiceResult.selectedItem))
    context.title = `Les Roses de la Vie - ${this.roses.name}`
    TeDeumUtility.prepareEducationContent(this.roses);

    context.label = "Valider l'augmentation de caracteristique"
    await this.askCarac(this.roses, context)
    context.label = "Valider l'augmentation de compétences"
    await this.askCompetences(this.roses, context)

    context.label = "Valider cette réponse"
    await this.askQuestionnaire(this.roses, context)

    this.currentStage = "ageviril"
  }

  /*--------------------------------------------*/
  async renderAgeViril(stage) {
    let virilDebouche = this.roses.system.debouches
    let ageVirilItems = []
    for (let key in virilDebouche) {
      let debouche = virilDebouche[key]
      if (debouche.debouche === "") { continue }
      let deboucheItem = stage.items.find(item => item.name.toLowerCase().includes(debouche.debouche.toLowerCase()))
      if (deboucheItem) {
        ageVirilItems.push(deboucheItem)
      } else {
        console.log(`Debouche ${debouche.debouche} not found !`)
      }
    }

    let context = {
      title: "Création de personnage - L'Age Viril",
      label: "Valider le choix de l'Age Viril",
      choices: ageVirilItems,
      hasGenre: false,
      caracBonus: this.caracBonus,
      competenceBonus: this.competenceBonus
    }

    let choiceResult = await this.askStageName(context)
    if (choiceResult == null) {
      this.currentStage = "cancelled"
      return
    }

    this.ageViril = foundry.utils.duplicate(stage.items.find(item => item.id === choiceResult.selectedItem))
    context.title = `L'Age Viril - ${this.ageViril.name}`
    TeDeumUtility.prepareEducationContent(this.ageViril);

    context.label = "Valider l'augmentation de caracteristique"
    await this.askCarac(this.ageViril, context)
    context.label = "Valider l'augmentation de compétences"
    await this.askCompetences(this.ageViril, context)

    this.currentStage = "finished"
  }

  /*--------------------------------------------*/
  async processStage() {
    while (this.currentStage !== "finished") {
      let stage = this.stages[this.currentStage]
      switch (this.currentStage) {
        case "origineSociale":
          await this.renderOrigineSociale(stage)
          break
        case "pouponniere":
          await this.renderPouponniere(stage)
          break
        case "petitsgrimauds":
          await this.renderPetitsGrimauds(stage)
          break
        case "rosevie":
          await this.renderRosesDeLaVie(stage)
          break
        case "ageviril":
          await this.renderAgeViril(stage)
          break
        case "cancelled":
          return
          break
      }
    }

    console.log("Carac Bonus", this.caracBonus)
    console.log("Competence Bonus", this.competenceBonus)
    let actor = await TeDeumActor.create({name: "Nouveau personnage", type: "pj"})
    let updates = {}
    for (let key in this.caracBonus) {
      updates[`system.caracteristiques.${key}.value`] = Number(this.caracBonus[key].value)+1
    }
    updates['system.genre'] = this.sexe
    updates['system.religion'] = TeDeumUtility.upperFirst(this.religion)
    updates['system.statutocial'] = this.origineSociale.label
    updates['system.equipmentfree'] = this.ageViril.system.trousseau
    actor.update( updates);

    // Process competences : increase know skills
    let updateComp = []
    let toAdd = []
    for (let compName in this.competenceBonus) {
      let comp = actor.items.find(  i => i.type == "competence" && i.name.toLowerCase() === compName.toLowerCase())
      if (comp) {
        updateComp.push({ _id: comp._id, "system.score": comp.system.score + this.competenceBonus[compName].value })
      } else {
        toAdd.push( compName)
      }
    }
    actor.updateEmbeddedDocuments("Item", updateComp)

    // Process adding skills
    let compendiumSkill = TeDeumUtility.getCompetences()
    let compToAdd = [ this.pouponniere, this.grimauds, this.roses, this.ageViril ]
    for (let compName of toAdd) {
      let comp = compendiumSkill.find( i => i.name.toLowerCase() === compName.toLowerCase())
      comp.system.score = this.competenceBonus[compName].value
      compToAdd.push(comp)
    }
    await actor.createEmbeddedDocuments('Item', compToAdd)

    let newArgent = this.origineSociale.cagnotte * this.ageViril.system.cagnotteMultiplier
    newArgent /= this.ageViril.system.cagnotteDivider
    await actor.update({ [`system.fortune.${this.origineSociale.cagnotteUnit}`]: newArgent})

    let histoire = ""
    for ( let key in this.choiceSummary) {
      let stageSummary = this.choiceSummary[key]
      if (stageSummary.sexe) {
        histoire += `<h3>Origine Sociale</h3>`
        histoire += `<p>${stageSummary.sexe} - ${stageSummary.religion} - ${stageSummary.origineSociale}</p>`
      } else {
        histoire += `<h3>${game.system.tedeum.config.etapesEducation[key].label}</h3>`
      }
      if (stageSummary.caracBonus) {
        histoire += `<p><strong>Caractéristiques : </strong><ul>`
        for (let caracKey in stageSummary.caracBonus) {
          histoire += `<li>${TeDeumUtility.upperFirst(caracKey)} +1</li>`
        }
        histoire += `</ul></p>`
      }
      if (stageSummary.competences) {
        histoire += `<p><strong>Compétences : </strong><ul>`
        for (let compName in stageSummary.competences) {
          histoire += `<li>${TeDeumUtility.upperFirst(compName)} +1</li>`
        }
        histoire += `</ul></p>`
      }
      let questions = this.suiviReponses.filter( r => r.key === key)
      if (questions.length > 0) {
        histoire += `<p><strong>Réponses au questionnaire : </strong><ul>`
        for (let question of questions) {
          histoire += `<li>${question.question} : <i>${question.reponse}</i> (${TeDeumUtility.upperFirst(question.compName)}+1)</li>`
        }
        histoire += `</ul></p>`
      }
    }
    await actor.update({ "system.histoire": histoire})
    actor.render(true)

    context.pointsCompetence = {
      "savoir": { score: actor.getCompetenceScore("Mémoriser"), label: "Savoir" },
      "sensibilite": { score: actor.getCompetenceScore("Perception"), label: "Sensibilité" },
      "entregent": { score: actor.getCompetenceScore("Charme"), label: "Entregent" },
      "puissance": { score: actor.getCompetenceScore("Effort"), label: "Puissance" },
      "complexion": { score: actor.getCompetenceScore("Endurance"), label: "Complexion" },
      "adresse": { score: actor.getCompetenceScore("Initiative"),   label: "Adresse" },
    }

    const content = await foundry.applications.handlebars.renderTemplate("systems/fvtt-te-deum/templates/dialogs/character-creator-finished.hbs", context)
    const label = "Terminer"
    const choiceResult = await foundry.applications.api.DialogV2.wait({
      window: { title: context.title },
      classes: ["fvtt-te-deum"],
      content,
      buttons: [
        {
          label: label,
          callback: (event, button, dialog) => {
            const output = Array.from(button.form.elements).reduce((obj, input) => {
              if (input.name) obj[input.name] = input.value
              return obj
            }, {})
            return output
          },
        },
      ],
      actions: {
      },
      rejectClose: false, // Click on Close button will not launch an error
      render: (event, dialog) => { }
    })

  }

}
