import { DIFF } from "./roll-constants.mjs"
import { PART_DIFF } from "./roll-part-diff.mjs"

const DEFAULT_DIFF_TYPES = [DIFF.LIBRE, DIFF.IMPOSEE, DIFF.DEFAUT]

export class RollType {

  get code() { throw new Error(`Pas de code défini pour ${this}`) }
  get name() { return this.code }
  get icon() { return `systems/foundryvtt-reve-de-dragon/assets/actions/${this.code}.svg` }
  get chatResultTemplate() { return `systems/foundryvtt-reve-de-dragon/templates/roll/result/chat-${this.code}.hbs` }

  toTypeData(rollData) {
    return { code: this.code, name: this.name, icon: this.icon, section: 'type', template: this.template, selected: this.isSelected(rollData) }
  }

  prepare(rollData) {}
  isAllowed(rollData) { return rollData.type.allowed == undefined || rollData.type.allowed.includes(this.code) }
  visible(rollData) { return true }
  title(rollData) { return this.code }
  isSelected(rollData) { return rollData.type.current == this.code }
  isOpposed(rollData) { return false }
  
  setRollDataType(rollData) {
    rollData.type.opposed = this.isOpposed(rollData)
  }

  onSelect(rollData) {
    const possibleTypes = [
      rollData.current[PART_DIFF].type,
      this.typeFromOpponents(rollData),
      rollData.selected[PART_DIFF].type
    ]
    const type = possibleTypes.find(m => DEFAULT_DIFF_TYPES.includes(m)) ?? DIFF.DEFAUT
    this.setDiffType(rollData, type)
  }

  typeFromOpponents(rollData) {
    if (rollData.type.opposed) {
      if (rollData.type.resistance) {
        return DIFF.IMPOSEE
      }
      return DIFF.LIBRE
    }
    return undefined
  }

  setDiffType(rollData, type) {
    type = rollData.selected[PART_DIFF].type ?? type
    rollData.current[PART_DIFF].type = type
    this.setRollDataType(rollData)
  }

  callbacks(rollOptions) { return [] }

  /**
   * Préparation des résultats d'un jet pour ce type de jet
   * 
   * @param {*} rollData les données du jet, incluans la partie rolled
   * @param {*} impacts une structure composée de deux ActorImpacts {active, opponent}
   *  pour stocker les effets sur ces deux participants au jey
   * @returns undefined ou une structure contenant les informations requise pour afficher
   */
  getResult(rollData, impacts) { return { messages: [] } }
  onApplyImpacts(rollData, impacts) { }
}
