import { ChatUtility } from "../chat-utility.js"
import { ITEM_TYPES } from "../constants.js"
import { RdDItemCompetence } from "../item-competence.js"
import { Misc } from "../misc.js"
import { CARACS } from "../rdd-carac.js"
import { RdDUtility } from "../rdd-utility.js"
import { DIFF, ROLL_TYPE_COMP } from "../roll/roll-constants.mjs"
import RollDialog from "../roll/roll-dialog.mjs"

export const MORAL = {
  MALHEUREUX: "malheureux",
  NEUTRE: "neutre",
  HEUREUX: "heureux",
  TRESHEUREUX: "très heureux"
}
export const SITUATION_MORAL = {
  [MORAL.MALHEUREUX]: "malheureuse",
  [MORAL.NEUTRE]: "neutre",
  [MORAL.HEUREUX]: "heureuse",
  [MORAL.TRESHEUREUX]: "très heureuse",
}
export const APPRECIATION = {
  CUISINE: {
    bonmoment: "Cuisine", carac: CARACS.ODORATGOUT, competence: "Cuisine",
    moral: MORAL.HEUREUX, jetComp: false, jetQualite: false, compMinimum: true
  },
  MUSIQUE: {
    bonmoment: "Musique", carac: CARACS.OUIE, competence: "Musique",
    moral: MORAL.HEUREUX, jetComp: false, jetQualite: false, compMinimum: true
  },
  CHANT: {
    bonmoment: "Musique", carac: CARACS.OUIE, competence: "Chant",
    moral: MORAL.HEUREUX, jetComp: false, jetQualite: false, compMinimum: true
  },
  DANSE: {
    bonmoment: "Spectacle", carac: CARACS.EMPATHIE, competence: "Danse",
    moral: MORAL.HEUREUX, jetComp: false, jetQualite: false, compMinimum: true
  },
  JEU: {
    bonmoment: "Jeu", carac: CARACS.EMPATHIE, competence: "Jeu",
    moral: MORAL.HEUREUX, jetComp: false, jetQualite: false, compMinimum: true
  },
  OEUVRE: {
    bonmoment: "Spectacle", carac: CARACS.EMPATHIE, competence: "",
    moral: MORAL.HEUREUX, jetComp: false, jetQualite: false, compMinimum: true
  },
  SERVICE: {
    bonmoment: "Confort", carac: CARACS.EMPATHIE, competence: "",
    moral: MORAL.HEUREUX, jetComp: false, jetQualite: false, compMinimum: false
  },
}


export class Apprecier {

  static isAppreciable(item) {
    switch (item.type) {
      case ITEM_TYPES.nourritureboisson:
      case ITEM_TYPES.service:
        return item.system.qualite > 0
      case ITEM_TYPES.chant:
      case ITEM_TYPES.musique:
      case ITEM_TYPES.danse:
      case ITEM_TYPES.oeuvre:
      case ITEM_TYPES.jeu:
        return true
    }
    return false
  }

  static qualite(qualite, roll = undefined, comp = undefined) {
    if (roll && comp) {
      return roll.rolled.isSuccess ? qualite : Math.min(qualite, comp.system.niveau)
    }
    return
  }

  static getAppreciation(qualite, appreciable, roll = undefined, comp = undefined) {
    return {
      qualite: (roll?.rolled.ptQualite ?? 0) + Apprecier.qualite(qualite, roll, comp),
      appreciation: foundry.utils.deepClone(appreciable.system.appreciation),
      messages: []
    }
  }

  static onClickApprecier(roll) {
    const appreciation = roll.result.appreciation
    if (appreciation.moral == "") {
      return
    }
    RdDUtility.doWithSelectedActor(
      actor => new Apprecier(actor, appreciation, roll.result.qualite).apprecier(),
      actor => actor.isPersonnage())
  }

  constructor(actor, appreciation, qualite) {
    this.actor = actor
    this.appreciation = foundry.utils.deepClone(appreciation)
    this.appreciation.situation = SITUATION_MORAL[appreciation.moral]
    this.qualite = qualite
    this.raisons = []
  }

  apprecier(callbacks = []) {
    if (this.qualite <= 0) {
      this.raisons.push(`la qualité ${this.qualite} est insuffisante.`)
    }
    if (this.qualite <= this.actor.getMoralTotal()) {
      this.raisons.push(`la qualité de ${this.qualite} est inférieure au moral de ${this.actor.getMoralTotal()}.`)
    }
    const competence = this.getCompetenceAppreciation()
    if (this.appreciation.compMinimum && this.qualite <= competence.system.niveau && competence.system.niveau > 0 && competence.id) {
      this.raisons.push(`la qualité ${this.qualite} est insuffisante pour le niveau ${competence.system.niveau} en ${competence.name}`)
    }
    const bonmoment = this.appreciation.bonmoment
    if (!["", undefined].includes(bonmoment) && this.actor.system.compteurs.bonmoments.includes(bonmoment)) {
      this.raisons.push(`du moral a déjà été gagné pour cause de ${bonmoment}`)
    }

    if (this.appreciation.carac != "") {
      this.rollAppreciation(callbacks)
    }
    else {
      this.rollMoral()
    }
  }

  getCompetenceAppreciation() {
    return [RdDItemCompetence.SANS_COMPETENCE.name, ""].includes(this.appreciation.competence) ? RdDItemCompetence.SANS_COMPETENCE : this.actor.getCompetence(this.appreciation.competence)
  }

  rollAppreciation(rollCallbacks = []) {
    const competence = (this.appreciation.jetComp && this.appreciation.competence) ? this.appreciation.competence : ""
    const rollData = {
      ids: { actorId: this.actor.id },
      type: { allowed: [ROLL_TYPE_COMP], current: ROLL_TYPE_COMP, appreciation: true },
      selected: {
        carac: { key: this.appreciation.carac, forced: true },
        comp: { key: competence, forced: true },
        diff: { type: DIFF.IMPOSEE },
        apprecier: {
          appreciation: this.appreciation,
          qualite: this.qualite,
          raisons: this.raisons
        }
      }
    }
    RollDialog.create(rollData, {
      callbacks: [
        async r => await this.onRollAppreciation(r),
        ...rollCallbacks
      ],
      onRollDone: RollDialog.onRollDoneClose
    })
  }

  async onRollAppreciation(roll) {
    if (roll.rolled.isSuccess) {
      await this.rollMoral()
    }
    else {
      if (this.appreciation.moral == MORAL.TRESHEUREUX) {
        await this.rollMoral(MORAL.HEUREUX)
      }
    }
  }

  async rollMoral(moral = undefined) {
    if (this.raisons.length > 0) {
      await ChatMessage.create({
        whisper: ChatUtility.getOwners(this.actor),
        content: 'Pas de jet de moral:' + Misc.concat(this.raisons.map(r => `<br> - ${r}`))
      })
      return
    }

    moral = moral ?? this.appreciation.moral
    await this.actor.jetDeMoral(moral, this.appreciation.bonmoment)
  }
}