import { RdDBaseActor } from "../actor/base-actor.js";
import { ChatUtility } from "../chat-utility.js";
import { renderTemplate } from "../constants.js";
import { MORAL } from "../moral/apprecier.mjs";

const INFO_COEUR = 'info-coeur';

export class RdDCoeur {
  static registerChatCallbacks(html) {
    $(html).on("click", 'a.accepter-tendre-moment', event => {
      RdDCoeur.accepterTendreMoment(RdDCoeur.extractInfoCoeur(event))
    })
    $(html).on("click", 'a.refuser-tendre-moment', event => {
      RdDCoeur.refuserTendreMoment(RdDCoeur.extractInfoCoeur(event))
    })
    $(html).on("click", 'a.perdre-point-coeur-douceur', event => {
      RdDCoeur.perdreEnDouceur(
        RdDCoeur.extractInfoCoeur(event),
        event.currentTarget.attributes['data-actor-id'].value)
    })
  }

  static addTagsInfoCoeur(infoCoeur, chatMessage = undefined) {
    if (chatMessage) {
      infoCoeur.chatMessageId = chatMessage.id
    }
    else {
      chatMessage = game.messages.get(infoCoeur.chatMessageId)
    }
    ChatUtility.setMessageData(chatMessage, INFO_COEUR, infoCoeur);
  }

  static extractInfoCoeur(event) {
    const chatMesage = ChatUtility.getChatMessage(event);
    return ChatUtility.getMessageData(chatMesage, INFO_COEUR)
  }

  static getInfoCoeur(sourceActorId, targetActorId) {
    const sourceActor = game.actors.get(sourceActorId)
    const targetActor = game.actors.get(targetActorId)
    if (sourceActor && targetActor) {
      return {
        source: {
          actor: RdDBaseActor.extractActorMin(sourceActor),
          coeur: sourceActor.getPointsCoeur(targetActorId),
        },
        target: {
          actor: RdDBaseActor.extractActorMin(targetActor),
          coeur: targetActor.getPointsCoeur(sourceActorId),
        }
      }
    }
    return {}
  }

  static async toggleSubActeurCoeur(actorId, subActorId, toggleCoeur) {
    const actor = game.actors.get(actorId)
    const amoureux = actor.getSuivant(subActorId)
    if (toggleCoeur <= amoureux.coeur) {
      if (toggleCoeur > amoureux.prochainCoeur) {
        toggleCoeur = amoureux.coeur
      }
      else {
        toggleCoeur = amoureux.coeur - 1
      }
    }
    else if (toggleCoeur <= amoureux.prochainCoeur) {
      toggleCoeur = Math.max(amoureux.coeur, toggleCoeur - 1)
    }
    actor.setPointsCoeur(subActorId, Math.max(0, Math.min(toggleCoeur, 4)))
  }

  static async applyCoeurChateauDormant(actor, message) {
    let count = 0
    let ajustMoral = 0
    const newSuivants = actor.system.subacteurs.suivants.filter(link => game.actors.get(link.id) != undefined)
      .map(link => {
        const suivant = game.actors.get(link.id)
        const prochainCoeur = link.prochainCoeur ?? 0
        const coeurCourant = link.coeur ?? 0
        const diff = prochainCoeur - coeurCourant
        if (diff < 0) {
          ajustMoral -= 4
          link.coeur = Math.max(0, coeurCourant - 1)
          link.prochainCoeur = link.coeur
          message.content += `<br>Votre c&oelig;ur brisé pour ${suivant.name} vous fait perdre 4 points de moral, il vous reste  ${link.coeur} points de C&oelig;ur.`
          count++
        }
        if (diff > 0) {
          link.coeur = Math.min(prochainCoeur, 4)
          message.content += `<br>Votre c&oelig;ur bat fort, vous avez maintenant ${link.coeur} points de C&oelig;ur pour ${suivant.name}.`
          link.prochainCoeur = link.coeur
          count++
        }
        return foundry.utils.deepClone(link)
      })
    if (ajustMoral != 0) {
      await actor.moralIncDec(ajustMoral, 'Coeur')
    }
    if (count > 0) {
      await actor.update({ 'system.subacteurs.suivants': newSuivants });
    }
  }

  static async startSubActeurTendreMoment(actorId, subActeurId) {
    const infoCoeur = RdDCoeur.getInfoCoeur(actorId, subActeurId)
    if (infoCoeur.target?.actor?.id) {
      // TODO: passer par une fenêtre pour saisir sa proposition (lieu, heure, ...)
      const chatMessage = await ChatMessage.create({
        whisper: ChatUtility.getOwners(infoCoeur.target.actor),
        content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/coeur/chat-proposer-tendre-moment.hbs`, infoCoeur)
      })
      RdDCoeur.addTagsInfoCoeur(infoCoeur, chatMessage)
    }
  }

  static async accepterTendreMoment(infoCoeur) {
    const target = game.actors.get(infoCoeur.target.actor.id)
    if (!target.isOwner) {
      ui.notifications.warn(`vous ne pouvez pas accepter pour ${infoCoeur.target.actor.name}`)
      return
    }
    ChatUtility.removeChatMessageId(infoCoeur.chatMessageId)

    infoCoeur.target.jetTendre = (await (new Roll('1d6').evaluate())).total
    infoCoeur.source.jetTendre = (await (new Roll('1d6').evaluate())).total
    const diff = Math.abs(infoCoeur.source.jetTendre - infoCoeur.target.jetTendre)
    for (let amoureux of [infoCoeur.source, infoCoeur.target]) {
      const actorAmoureux = game.actors.get(amoureux.actor.id);
      amoureux.situation = diff <= amoureux.coeur ? MORAL.HEUREUX : MORAL.NEUTRE
      amoureux.gainMoral = await actorAmoureux.jetDeMoral(amoureux.situation)
    }
    const chatHtml = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/coeur/chat-accepter-tendre-moment.hbs`, infoCoeur)
    const chatMessage = await ChatMessage.create({
      whisper: ChatUtility.getMultipleActorsOwners(infoCoeur.source?.actor, infoCoeur.target?.actor),
      content: chatHtml
    })
    RdDCoeur.addTagsInfoCoeur(infoCoeur, chatMessage)
  }

  static async refuserTendreMoment(infoCoeur) {
    const target = game.actors.get(infoCoeur.target.actor.id)
    if (!target.isOwner) {
      ui.notifications.warn(`vous ne pouvez pas refuser pour ${infoCoeur.target.actor.name}`)
      return
    }
    ChatUtility.removeChatMessageId(infoCoeur.chatMessageId)
    const chatHtml = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/coeur/chat-refuser-tendre-moment.hbs`, infoCoeur)
    await ChatMessage.create({
      whisper: ChatUtility.getMultipleActorsOwners(infoCoeur.source?.actor, infoCoeur.target?.actor),
      content: chatHtml
    });
  }

  static async perdreEnDouceur(infoCoeur, actorId) {
    const [amoureux, partenaire] = (infoCoeur.source.actor.id == actorId
      ? [infoCoeur.source, infoCoeur.target]
      : (infoCoeur.target.actor.id == actorId
        ? [infoCoeur.target, infoCoeur.source]
        : [undefined, undefined]))

    if (amoureux.perteCoeur) {
      ui.notifications.warn(`Le point de c&oelig;ur a déjà été perdu`)
    }
    else if (amoureux.coeur > 0) {
      const actor = game.actors.get(actorId)
      if (actor.isOwner) {
        await actor.setPointsCoeur(partenaire?.actor.id, amoureux.coeur - 1, { immediat: true })
        amoureux.perteCoeur = true
        RdDCoeur.addTagsInfoCoeur(infoCoeur)
      }
    }
  }
}