/* -------------------------------------------- */
import { RdDResolutionTable } from "./rdd-resolution-table.js";
import { RdDRoll } from "./rdd-roll.js";
import { RdDItemCompetenceCreature } from "./item-competencecreature.js";
import { ChatUtility } from "./chat-utility.js";
import { STATUSES } from "./settings/status-effects.js";

/* -------------------------------------------- */

/* -------------------------------------------- */
export class RdDEmpoignade {

  /* -------------------------------------------- */
  static init() {
  }

  /* -------------------------------------------- */
  static checkEmpoignadeEnCours(actor) {
    // TODO: autoriser la perception? la comédie/séduction?
    if (RdDEmpoignade.isEmpoignadeEnCours(actor)) {
      ui.notifications.warn("Une empoignade est en cours ! Normalement, vous ne pouvez rien faire d'autre que continuer l'empoignade ou la rompre.")
      return true;
    }
    return false;
  }

  /* -------------------------------------------- */
  static isEmpoignadeEnCours(actor) {
    return actor.itemTypes['empoignade'].find(it => it.system.pointsemp > 0)
  }

  /* -------------------------------------------- */
  static getEmpoignadeById(actor, id) {
    let emp = actor.itemTypes['empoignade'].find(it => it.system.empoignadeid == id)
    return emp && duplicate(emp) || undefined;
  }

  /* -------------------------------------------- */
  static getEmpoignade(attacker, defender) {
    let emp = attacker.itemTypes['empoignade'].find(it => it.system.empoigneurid == attacker.id && it.system.empoigneid == defender.id)
    if (!emp) {
      emp = attacker.itemTypes['empoignade'].find(it => it.system.empoigneurid == defender.id && it.system.empoigneid == attacker.id)
    }
    if (emp) {
      return duplicate(emp);
    }
    return undefined;
  }
  /* -------------------------------------------- */
  static getMalusTaille(emp, attacker, defender) {
    // Si pas empoigné, alors 0
    if (emp.system.pointsemp == 0) {
      return 0
    }
    // Malus de -1 si différence de taille de 2 ou plus (p 135)
    if (attacker.system.carac.taille.value < defender.system.carac.taille.value - 1) {
      return attacker.system.carac.taille.value - (defender.system.carac.taille.value - 1)
    }
    return 0
  }

  /* -------------------------------------------- */
  static async onAttaqueEmpoignadeValidee(attacker, defender) {
    let empoignade = RdDEmpoignade.getEmpoignade(attacker, defender)
    const isNouvelle = empoignade == undefined;
    empoignade = empoignade ?? (await RdDEmpoignade.createEmpoignade(attacker, defender))

    let mode = (empoignade && empoignade.system.empoigneurid == attacker.id) ? "empoigner" : "liberer"

    let rollData = {
      mode: mode,
      isEmpoignade: true,
      competence: attacker.getCompetence("Corps à corps"),
      selectedCarac: attacker.system.carac.melee,
      empoignade: empoignade,
      attackerId: attacker.id,
      attackerName: attacker.name,
      defenderName: defender.name,
      defenderId: defender.id,
      malusTaille: RdDEmpoignade.getMalusTaille(empoignade, attacker, defender)
    }
    if (attacker.isCreatureEntite()) {
      RdDItemCompetenceCreature.setRollDataCreature(rollData)
    }
    if (empoignade.system.pointsemp >= 2) {
      let msg = await RdDResolutionTable.displayRollData(rollData, attacker, 'chat-empoignade-actions.html');
      ChatUtility.setMessageData(msg, "empoignade-roll-data", rollData)
    } else {
      await RdDEmpoignade.$rollAttaqueEmpoignade(attacker, rollData, isNouvelle);
    }
  }

  /* -------------------------------------------- */
  static async onAttaqueEmpoignade(attacker, defender) {
    let empoignade = RdDEmpoignade.getEmpoignade(attacker, defender)
    const isNouvelle = empoignade == undefined;
    empoignade = empoignade ?? (await RdDEmpoignade.createEmpoignade(attacker, defender))
    //console.log("W.", empoignade, defender.hasArmeeMeleeEquipee())
    if ((isNouvelle || empoignade.system.pointsemp == 0) && defender.hasArmeeMeleeEquipee()) {
      ChatUtility.createChatWithRollMode(attacker.name, {
        content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-empoignade-valider.html`, { attacker: attacker, defender: defender })
      })
    } else {
      await this.onAttaqueEmpoignadeValidee(attacker, defender)
    }
  }

  /* -------------------------------------------- */
  static async onAttaqueEmpoignadeFromItem(empoignade) {
    let attacker = game.actors.get(empoignade.system.empoigneurid)
    let defender = game.actors.get(empoignade.system.empoigneid)
    await this.onAttaqueEmpoignadeValidee(attacker, defender)
  }

  /* -------------------------------------------- */
  static async $rollAttaqueEmpoignade(attacker, rollData, isNouvelle = false) {
    const dialog = await RdDRoll.create(attacker, rollData,
      { html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.html' },
      {
        name: 'jet-empoignade',
        label: 'Empoigner',
        callbacks: [
          { condition: r => (r.rolled.isSuccess), action: async (r) => await RdDEmpoignade.$onRollEmpoignade(r, true, isNouvelle) },
          { condition: r => (r.rolled.isEchec), action: async (r) => await RdDEmpoignade.$onRollEmpoignade(r, false, isNouvelle) },
        ]
      });
    dialog.render(true);
  }

  /* -------------------------------------------- */
  static async $onRollEmpoignade(rollData, isSuccess, isNouvelle = false) {
    let attacker = game.actors.get(rollData.attackerId)
    let defender = game.actors.get(rollData.defenderId)

    let empoignade = rollData.empoignade
    empoignade.isSuccess = isSuccess;

    if (isSuccess && isNouvelle) {
      // Creer l'empoignade sur attaquant/defenseur
      await attacker.createEmbeddedDocuments('Item', [empoignade.toObject()])
      await defender.createEmbeddedDocuments('Item', [empoignade.toObject()])
    }
    let msg = await RdDResolutionTable.displayRollData(rollData, attacker, 'chat-empoignade-resultat.html');
    ChatUtility.setMessageData(msg, "empoignade-roll-data", rollData)
  }

  /* -------------------------------------------- */
  static async onDefenseEmpoignade(rollData, defenseMode, competenceName = "Corps à corps", carac = "melee") {
    let attacker = game.actors.get(rollData.attackerId)
    let defender = game.actors.get(rollData.defenderId)
    let empoignade = this.getEmpoignade(attacker, defender)

    if (!empoignade) {
      ui.notifications.warn("Une erreur s'est produite : Aucune empoignade trouvée !!")
      return
    }

    empoignade = duplicate(empoignade)
    rollData.mode = defenseMode
    rollData.empoignade = empoignade
    rollData.competence = defender.getCompetence(competenceName),
      rollData.selectedCarac = defender.system.carac[carac],
      rollData.malusTaille = RdDEmpoignade.getMalusTaille(empoignade, defender, attacker)

    await RdDEmpoignade.$rollDefenseEmpoignade(defender, rollData);
  }

  /* -------------------------------------------- */
  static async $rollDefenseEmpoignade(defender, rollData) {
    const dialog = await RdDRoll.create(defender, rollData,
      { html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-defense-empoignade.html' },
      {
        name: 'empoignade',
        label: 'Contrer',
        callbacks: [
          { action: async (r) => await RdDEmpoignade.$onRollContrerLiberer(r) }
        ]
      }
    );
    dialog.render(true);
  }

  /* -------------------------------------------- */
  static async $onRollContrerLiberer(rollData) {
    let empoignade = rollData.empoignade

    if (rollData.mode == "contrer-empoigner" && !rollData.rolled.isSuccess) {
      empoignade.system.pointsemp++
      RdDEmpoignade.$updateEtatEmpoignade(empoignade)
    }
    if (rollData.mode == "contrer-liberer" && !rollData.rolled.isSuccess) {
      empoignade.system.pointsemp--
      RdDEmpoignade.$updateEtatEmpoignade(empoignade)
    }

    if (empoignade.system.pointsemp >= 2) {
      let attacker = game.actors.get(empoignade.system.empoigneurid)
      let msg = await RdDResolutionTable.displayRollData(rollData, attacker, 'chat-empoignade-actions.html');
      ChatUtility.setMessageData(msg, "empoignade-roll-data", rollData)
    }
    await RdDResolutionTable.displayRollData(rollData, rollData.defender, 'chat-empoignade-resultat.html')
  }

  /* -------------------------------------------- */
  static async $updateEtatEmpoignade(empoignade) {
    console.log("UPDATE Empoignade", empoignade)

    let defender = game.actors.get(empoignade.system.empoigneid)
    let emp = RdDEmpoignade.getEmpoignadeById(defender, empoignade.system.empoignadeid)
    let update = { _id: emp._id, "system.pointsemp": empoignade.system.pointsemp, "system.ausol": empoignade.system.ausol }
    await defender.updateEmbeddedDocuments('Item', [update])

    let attacker = game.actors.get(empoignade.system.empoigneurid)
    emp = RdDEmpoignade.getEmpoignadeById(attacker, empoignade.system.empoignadeid)
    update = { _id: emp._id, "system.pointsemp": empoignade.system.pointsemp, "system.ausol": empoignade.system.ausol }
    await attacker.updateEmbeddedDocuments('Item', [update])
  }

  /* -------------------------------------------- */
  static async $deleteEmpoignade(empoignade) {
    console.log("DELETE Empoignade", empoignade)

    let defender = game.actors.get(empoignade.system.empoigneid)
    let emp = RdDEmpoignade.getEmpoignadeById(defender, empoignade.system.empoignadeid)
    await defender.deleteEmbeddedDocuments('Item', [emp._id])

    //let attacker = game.actors.get(empoignade.system.empoigneurid)
    //emp = RdDEmpoignade.getEmpoignadeById(attacker, empoignade.system.empoignadeid)
    //await attacker.deleteEmbeddedDocuments('Item', [emp._id])
  }

  /* -------------------------------------------- */
  static async entrainerAuSol(rollData) {
    let attacker = game.actors.get(rollData.attackerId)
    let defender = game.actors.get(rollData.defenderId)
    let empoignade = this.getEmpoignade(attacker, defender)

    empoignade.system.ausol = true
    await this.$updateEtatEmpoignade(empoignade)

    await attacker.setEffect(STATUSES.StatusProne, true);
    await defender.setEffect(STATUSES.StatusProne, true);

    let msg = await RdDResolutionTable.displayRollData(rollData, attacker, 'chat-empoignade-entrainer-sol.html');
    ChatUtility.setMessageData(msg, "empoignade-roll-data", rollData)
  }

  /* -------------------------------------------- */
  static async projeterAuSol(rollData) {
    let attacker = game.actors.get(rollData.attackerId)
    let defender = game.actors.get(rollData.defenderId)
    let empoignade = this.getEmpoignade(attacker, defender)

    await defender.setEffect(STATUSES.StatusProne, true);
    await this.$deleteEmpoignade(empoignade)

    let msg = await RdDResolutionTable.displayRollData(rollData, attacker, 'chat-empoignade-projeter-sol.html');
    ChatUtility.setMessageData(msg, "empoignade-roll-data", rollData)
  }
  /* -------------------------------------------- */
  static async perteEndurance(rollData, perteMode) {
    let attacker = game.actors.get(rollData.attackerId)
    let defender = game.actors.get(rollData.defenderId)
    let empoignade = this.getEmpoignade(attacker, defender)

    //console.log("Perte d'endurance :!!!", perteMode)
    let endValue = defender.system.sante.endurance.value
    if (perteMode == "end0") {
      await defender.santeIncDec("endurance", -endValue);
    }
    if (perteMode == "end1") {
      await defender.santeIncDec("endurance", -(endValue - 1));
    }
    if (perteMode == "endmoitie") {
      await defender.santeIncDec("endurance", -Math.floor(endValue / 2));
    }
    if (perteMode == "endquart") {
      await defender.santeIncDec("endurance", -(3 * Math.floor(endValue / 4)));
    }
    let msg = await RdDResolutionTable.displayRollData(rollData, attacker, 'chat-empoignade-perte-endurance.html');
    ChatUtility.setMessageData(msg, "empoignade-roll-data", rollData)
  }

  /* -------------------------------------------- */
  static async deleteAllEmpoignades() {
    for (let actor of game.actors) {
      let empIds = actor.itemTypes["empoignade"].map(it => it.id)
      await actor.deleteEmbeddedDocuments('Item', empIds)
    }
  }

  /* -------------------------------------------- */
  static async deleteLinkedEmpoignade(actorId, empoignade) {
    let actorDeleteId = (actorId == empoignade.system.empoigneurid) ? empoignade.system.empoigneid : empoignade.system.empoigneurid
    let actor = game.actors.get(actorDeleteId)
    let emp = this.getEmpoignadeById(actor, empoignade.system.empoignadeid)
    if (emp) {
      await actor.deleteEmbeddedDocuments('Item', [emp._id])
    }
  }

  /* -------------------------------------------- */
  static async createEmpoignade(attacker, defender) {
    return await Item.create({
      name: "Empoignade en cours de " + attacker.name + ' sur ' + defender.name,
      type: 'empoignade',
      img: "systems/foundryvtt-reve-de-dragon/icons/entites/possession2.webp",
      system: { description: "", empoignadeid: randomID(16), compteempoigne: 0, empoigneurid: attacker.id, empoigneid: defender.id, ptsemp: 0, empoigneurname: attacker.name, empoignename: defender.name }
    },
      {
        temporary: true
      })
  }
}