export const ROLLDIALOG_SECTION = {
  ACTION: 'action',
  CARAC: 'carac',
  COMP: 'comp',
  CHOIX: 'choix',
  CONDITIONS: 'conditions',
  AJUSTEMENTS: 'ajustements',
}  

export class RollPart {
  static settingKey(rollPart, key) { return `roll-part-${rollPart.code}.${key}` }
  
  get code() { throw new Error(`Pas dse code définie pour ${this}`) }
  get name() { return this.code }
  /** la section de la fenêtre ou le paramêtre apparaît */
  get section() { return undefined }
  get priority() { return 0 /* TODO */ }
  /** le template handlebars pour affichage */
  get template() { return `systems/foundryvtt-reve-de-dragon/templates/roll/roll-part-${this.code}.hbs` }
  
  static getSelectedPart(rollData, code) {
    return rollData.selected[code] ?? {}
  }  
  static setSelectedPart(rollData, code, saved) {
    rollData.selected[code] = saved
  }  
  
  /** l'acteur actif du jet */
  getActor(rollData) { return rollData.active.actor }
  /** le conteneur de données du RollPart */
  getRefs(rollData) {
    return rollData.refs[this.code]
  }  

  /** les informations de sélection du paramètre */
  getCurrent(rollData) {
    return rollData.current[this.code]
  }  
  setCurrent(rollData, current) {
    rollData.current[this.code] = current
  }  

  /** les informations minimales représentant la sélection dans le rollData permettant de restaurer la fenêtre */
  getSelected(rollData) { return this.getSaved(rollData) }
  getSaved(rollData) {
    return RollPart.getSelectedPart(rollData, this.code)
  }  
  setSaved(rollData, saved) {
    RollPart.setSelectedPart(rollData, this.code, saved)
  }  

  restore(rollData) { }

  storeClean(rollData, targetData) {
    this.store(rollData, targetData)
    if (rollData.selected[this.code]) {
      const toDelete = Object.entries(rollData.selected[this.code])
        .map(([k, v]) => v == undefined ? k : undefined)
        .filter(k => k != undefined)
      toDelete.forEach(k => delete rollData.selected[this.code][k])
      if (Object.keys(rollData.selected[this.code]).length == 0) {
        delete rollData.selected[this.code]
      }
    }
  }

  store(rollData, targetData) {
    this.setSaved(targetData, { key: this.getCurrent(rollData).key })
  }

  /**
   * le texte à ajouter dans la barre de titre
   * @returns une chaîne vide si rien ne doit être affiché
  */
  title() { return '' }
  static isRollType(rollData, ...type) { return type.includes(rollData.type.current) }
  get rollTypes() { return undefined }
  isActive(rollData) { return this.isValid(rollData) && this.visible(rollData) }
  isValid(rollData) { return true }
  visible(rollData) { return true }

  onReady(rollParts) { }
  loadRefs(rollData) { }

  prepareContext(rollData) { }

  /** permet de sauvegarder dans rollData les informations (cas des champs edit) */
  validate(rollData) { }

  /** ---- cross roll-part filtering ---- */
  applyImpact(rollData, filter) { }
  getSpecialComp(rollData) { return [] }
  setSpecialComp(comps) { }

  impactOtherPart(partCode, rollData) { }

  applyExternalImpacts(rollParts, rollData) {
    rollParts.forEach(part => part.impactOtherPart(this, rollData))
  }

  toTemplateData() {
    return { code: this.code, name: this.name, template: this.template, section: this.section }
  }

  getAjustements(rollData) { return [] }

  async _onRender(rollDialog, context, options) { }

  getHooks() { return [] }

  onNumericInputChange(event, rollDialog, setValue = value => this.getCurrent(rollDialog.rollData).value = value) {
    if (isNaN(event.currentTarget.value) || event.currentTarget.value == "") {
      return
    }
    setValue(parseInt(event.currentTarget.value))
    rollDialog.render()
  }

}