import { ITEM_TYPES } from "../constants.js"
import { CARACS } from "../rdd-carac.js"
import { ROLL_TYPE_CUISINE, RollConstants } from "./roll-constants.mjs"
import { PART_CARAC } from "./roll-part-carac.mjs"
import { PART_COMP } from "./roll-part-comp.mjs"
import { RollPartSelect } from "./roll-part-select.mjs"
import { ROLLDIALOG_SECTION, RollPart } from "./roll-part.mjs"

export const PART_CUISINE = "cuisine"

export class RollPartCuisine extends RollPartSelect {
  onReady(rollParts) {
    foundry.applications.handlebars.loadTemplates({ 'roll-oeuvre-recettecuisine': `systems/foundryvtt-reve-de-dragon/templates/roll/roll-oeuvre-recettecuisine.hbs` })
  }

  get code() { return PART_CUISINE }
  get section() { return ROLLDIALOG_SECTION.CHOIX }

  prepareContext(rollData) {
    const current = this.getCurrent(rollData)
    current.cuisineDiffOptions = Array.from(
      { length: 11 },
      (_, i) => ({ value: -10 + i, label: String(-10 + i) })
    )
  }

  get rollTypes() { return [ROLL_TYPE_CUISINE] }

  isValid(rollData) {
    return rollData.active.actor.isPersonnage()
      && RollConstants.findCompetence(rollData, 'Cuisine')
  }

  visible(rollData) { return RollPart.isRollType(rollData, ROLL_TYPE_CUISINE) }

  restore(rollData) {
    super.restore(rollData)
    this.$restoreSavedOptions(rollData)
  }

  store(rollData, targetData) {
    const current = this.getCurrent(rollData)
    this.setSaved(targetData, {
      key: current.key,
      fabriquer: current.fabriquer,
      proportions: current.proportions,
      value: current.value,
    })
  }

  loadRefs(rollData) {
    const refs = this.getRefs(rollData)
    refs.cuisine = RollConstants.findCompetence(rollData, 'Cuisine')

    if (!refs.cuisine) {
      refs.preparations = []
      return
    }

    const recettes = rollData.active.actor.items
      .filter(it => it.type == ITEM_TYPES.recettecuisine)
      .map(it => RollPartCuisine.$extractPreparationRecette(refs.cuisine, it))

    const ingredientsBruts = rollData.active.actor.items
      .filter(it => it.getUtilisationCuisine() == 'brut')
      .map(it => RollPartCuisine.$extractPreparationBrut(refs.cuisine, it))

    refs.preparations = [RollPartCuisine.$preparationBasique(refs.cuisine), ...recettes, ...ingredientsBruts]
    if (refs.preparations.length > 0) {
      this.$selectPreparation(rollData)
      this.$restoreSavedOptions(rollData)
    }
  }

  $restoreSavedOptions(rollData) {
    const saved = this.getSaved(rollData)
    const current = this.getCurrent(rollData)
    if (saved.fabriquer != undefined) {
      current.fabriquer = saved.fabriquer
    }
    if (saved.proportions != undefined) {
      current.proportions = saved.proportions
    }
    if (saved.value != undefined) {
      current.value = saved.value
    }
  }

  choices(refs) { return refs.preparations }

  static $preparationBasique(cuisine) {
    return {
      key: '',
      label: "Improvisation du moment",
      img: RollPartCuisine.$getImgIngredient(),
      sust: 1,
      exotisme: 0,
      ingredients: "Ce qu'il y a sous la main",
      proportions: 8,
      proportionsMax: 50,
      value: 0,
      fabriquer: false,
      qualite: cuisine.system.niveau,
      comp: cuisine,
    }
  }

  static $extractPreparationRecette(cuisine, recette) {
    const proportions = recette.system.sust ?? 1
    return {
      key: recette.id,
      label: recette.name,
      img: 'systems/foundryvtt-reve-de-dragon/icons/cuisine/ragout.svg',
      sust: 1,
      exotisme: recette.system.exotisme,
      ingredients: recette.system.ingredients,
      proportions: proportions,
      proportionsMax: proportions * 10,
      value: -recette.system.niveau,
      recette: recette,
      fabriquer: true,
      qualite: recette.system.niveau,
      comp: cuisine,
    }
  }

  static $extractPreparationBrut(cuisine, ingredient) {
    return {
      key: ingredient.id,
      label: ingredient.name + ' cuisiné',
      img: RollPartCuisine.$getImgIngredient(ingredient.type),
      sust: ingredient.system.sust ?? 1,
      exotisme: ingredient.system.exotisme,
      ingredients: ingredient.name,
      proportions: Math.min(10, ingredient.system.quantite),
      proportionsMax: Math.min(50, ingredient.system.quantite),
      value: 0,
      ingredient: ingredient,
      fabriquer: true,
      qualite: cuisine.system.niveau,
      comp: cuisine,
    }
  }

  static $getImgIngredient(type = ITEM_TYPES.ingredient) {
    switch (type) {
      case ITEM_TYPES.herbe:
      case ITEM_TYPES.plante:
        return `systems/foundryvtt-reve-de-dragon/icons/cuisine/${type}.svg`
      case ITEM_TYPES.faune:
        return 'systems/foundryvtt-reve-de-dragon/icons/cuisine/gibier.svg'
    }
    return 'systems/foundryvtt-reve-de-dragon/icons/cuisine/ragout.svg'
  }

  $selectPreparation(rollData, key) {
    this.selectByKey(rollData, key, 0)
  }

  async _onRender(rollDialog, context, options) {
    const current = this.getCurrent(rollDialog.rollData)

    const selectPreparation = rollDialog.element.querySelector(`roll-section[name="${this.code}"] select[name="select-preparation"]`)
    const inputDiff = rollDialog.element.querySelector(`roll-section[name="${this.code}"] [name="diff-var"]`)
    const checkboxFabriquer = rollDialog.element.querySelector(`roll-section[name="${this.code}"] input[name="fabriquer"]`)
    const inputProportions = rollDialog.element.querySelector(`roll-section[name="${this.code}"] input[name="proportions"]`)

    selectPreparation.addEventListener("change", e => {
      const selectOptions = e.currentTarget.options
      const index = selectOptions.selectedIndex
      this.$selectPreparation(rollDialog.rollData, selectOptions[index]?.value)
      rollDialog.render()
    })

    checkboxFabriquer?.addEventListener("change", e => {
      current.fabriquer = e.currentTarget.checked
    })
    inputDiff?.addEventListener("change", e => {
      current.value = parseInt(e.currentTarget.value)
      rollDialog.render()
    })
    inputProportions?.addEventListener("change", e => {
      current.proportions = parseInt(e.currentTarget.value)
    })

  }

  impactOtherPart(part, rollData) {
    if (this.visible(rollData)) {
      switch (part.code) {
        case PART_CARAC: return part.filterCaracs(rollData, [CARACS.ODORATGOUT])
        case PART_COMP: return part.filterComps(rollData, [this.getRefs(rollData).cuisine.name])
      }
    }
    return undefined
  }

}
