const { HandlebarsApplicationMixin } = foundry.applications.api;

/**
 * Dialogue du meneur pour ouvrir une phase d'Expérience.
 * Permet d'attribuer les Dés d'Expérience collectifs (Danger, Découvertes,
 * Durée) au Groupe et aux personnages, ainsi que les Dés individuels
 * (Implication, Influence, Interprétation), les récompenses d'Objectifs et
 * la récompense de Traumatisme choisi.
 */
export default class ExperiencePhaseDialog extends HandlebarsApplicationMixin(foundry.applications.api.ApplicationV2) {

  static DEFAULT_OPTIONS = {
    classes: ["vermine-roll"],
    tag: "form",
    window: {
      icon: "fas fa-star",
      resizable: true
    },
    position: {
      width: 620,
      height: 700
    },
    actions: {
      apply: ExperiencePhaseDialog.#onApply,
      cancel: ExperiencePhaseDialog.#onCancel
    }
  };

  static PARTS = {
    main: { template: "systems/vermine2047/templates/dialogs/experience-phase-dialog.hbs", scrollable: [""] }
  };

  static async create() {
    return new ExperiencePhaseDialog();
  }

  get title() {
    return game.i18n.localize("VERMINE.experience_phase");
  }

  async _prepareContext() {
    const characters = game.actors.filter(a => a.type === "character");
    const groups = game.actors.filter(a => a.type === "group");
    // Associe chaque personnage à son premier groupe (même logique que RollDialog.#findGroup)
    const memberOf = new Map();
    for (const g of groups) {
      for (const id of g.system?.members || []) {
        if (!memberOf.has(id)) memberOf.set(id, g.id);
      }
    }
    const groupById = new Map(groups.map(g => [g.id, g]));
    return {
      characters: characters.map(a => {
        const groupId = memberOf.get(a.id) || "";
        return {
          id: a.id,
          name: a.name,
          dice: a.system?.experience?.dice || 0,
          groupId,
          groupName: groupId ? groupById.get(groupId)?.name : ""
        };
      }),
      groups: groups.map(a => ({
        id: a.id,
        name: a.name,
        dice: a.system?.experience?.dice || 0
      })),
      rewards: [
        { value: 0, label: game.i18n.localize("VERMINE.reward_anecdotic") },
        { value: 1, label: game.i18n.localize("VERMINE.reward_minor") },
        { value: 2, label: game.i18n.localize("VERMINE.reward_major") },
        { value: 3, label: game.i18n.localize("VERMINE.reward_exceptionnal") }
      ]
    };
  }

  async _onRender(context, options) {
    this.element.querySelectorAll("[data-roll]").forEach(inp => inp.addEventListener("change", () => this.#updateUI()));
    this.element.querySelector("#group-select")?.addEventListener("change", () => this.#updateGroupFilter());
    this.element.querySelectorAll("[name^='include-']").forEach(cb =>
      cb.addEventListener("click", event => event.stopPropagation())
    );
    this.#updateUI();
    this.#updateGroupFilter();
  }

  #updateUI() {
    const danger = parseInt(this.element.querySelector("#collective-danger")?.value, 10) || 0;
    const discoveries = parseInt(this.element.querySelector("#collective-discoveries")?.value, 10) || 0;
    const duration = parseInt(this.element.querySelector("#collective-duration")?.value, 10) || 0;
    const el = this.element.querySelector("#collective-total");
    if (el) el.textContent = `${danger + discoveries + duration}D`;
  }

  /** Filtre les personnages selon le groupe sélectionné (vide = tous, "none" = sans groupe). */
  #updateGroupFilter() {
    const groupId = this.element.querySelector("#group-select")?.value || "";
    for (const row of this.element.querySelectorAll("[data-character-id]")) {
      const rowGroupId = row.dataset.groupId || "";
      const show = groupId === ""
        ? true
        : groupId === "none"
          ? rowGroupId === ""
          : rowGroupId === groupId;
      row.hidden = !show;
    }
  }

  static async #onCancel(event, target) {
    this.close();
  }

  static async #onApply(event, target) {
    const collective = (parseInt(this.element.querySelector("#collective-danger")?.value, 10) || 0)
      + (parseInt(this.element.querySelector("#collective-discoveries")?.value, 10) || 0)
      + (parseInt(this.element.querySelector("#collective-duration")?.value, 10) || 0);

    const groupId = this.element.querySelector("#group-select")?.value || "";
    if (groupId && groupId !== "none") {
      const group = game.actors.get(groupId);
      if (group && collective > 0) {
        const current = group.system?.experience?.dice || 0;
        const phase = (group.system?.experience?.phase || 0) + 1;
        await group.update({
          "system.experience.dice": current + collective,
          "system.experience.phase": phase,
          "system.experience.learned.phase": phase,
          "system.experience.learned.level": false,
          "system.experience.learned.reserve": false,
          "system.experience.learned.ability": false
        });
      }
    }

    const results = [];
    for (const row of this.element.querySelectorAll("[data-character-id]")) {
      // Filtre par groupe sélectionné (vide = tous, "none" = sans groupe)
      const rowGroupId = row.dataset.groupId || "";
      if (groupId === "none" ? rowGroupId !== "" : groupId !== "" && rowGroupId !== groupId) continue;
      // Case « Inclure » décochée → personnage exclu de cette phase
      if (!row.querySelector(`[name="include-${row.dataset.characterId}"]`)?.checked) continue;
      const id = row.dataset.characterId;
      const actor = game.actors.get(id);
      if (!actor) continue;
      const implication = parseInt(row.querySelector(`[name="implication-${id}"]`)?.value, 10) || 0;
      const influence = parseInt(row.querySelector(`[name="influence-${id}"]`)?.value, 10) || 0;
      const interpretation = parseInt(row.querySelector(`[name="interpretation-${id}"]`)?.value, 10) || 0;
      const objectiveMinor = row.querySelector(`[name="objective-minor-${id}"]`)?.checked ? 3 : 0;
      const objectiveMajor = row.querySelector(`[name="objective-major-${id}"]`)?.checked ? 5 : 0;
      const trauma = row.querySelector(`[name="trauma-${id}"]`)?.checked ? 5 : 0;

      const individual = implication + influence + interpretation;
      const bonus = objectiveMinor + objectiveMajor + trauma;
      const gained = collective + individual + bonus;

      const ex = actor.system?.experience;
      const nextPhase = (ex?.phase || 0) + 1;
      const update = {
        "system.experience.phase": nextPhase,
        "system.experience.dice": (ex?.dice || 0) + gained,
        "system.experience.collective.danger": parseInt(this.element.querySelector("#collective-danger")?.value, 10) || 0,
        "system.experience.collective.discoveries": parseInt(this.element.querySelector("#collective-discoveries")?.value, 10) || 0,
        "system.experience.collective.duration": parseInt(this.element.querySelector("#collective-duration")?.value, 10) || 0,
        "system.experience.individual.implication": implication,
        "system.experience.individual.influence": influence,
        "system.experience.individual.interpretation": interpretation,
        "system.experience.traumaReward": trauma > 0,
        "system.experience.learned.phase": nextPhase,
        "system.experience.learned.skill": false,
        "system.experience.learned.specialty": false,
        "system.experience.learned.reserve": false,
        "system.experience.learned.characteristic": false,
        "system.experience.learned.evolution": false,
        "system.experience.learned.ability": false,
        "system.experience.learned.background": false,
        "system.experience.learned.reputation": false
      };
      await actor.update(update);
      results.push({ name: actor.name, gained });
    }

    const lines = [`${game.i18n.localize("VERMINE.experience_phase")} +1`];
    if (groupId && groupId !== "none") {
      const group = game.actors.get(groupId);
      lines.push(`${group?.name ?? ""} (${game.i18n.localize("VERMINE.collective")}): +${collective}D`);
    }
    for (const r of results) {
      lines.push(`${r.name}: +${r.gained}D`);
    }
    await ChatMessage.create({
      user: game.user?._id,
      speaker: ChatMessage.getSpeaker(),
      content: `<div class="vermine-roll-message"><h3>${game.i18n.localize("VERMINE.experience_rewards")}</h3><div class="roll-context flexrow flex-wrap">${lines.map(l => `<span class="context-item">${l}</span>`).join("")}</div></div>`
    });

    this.close();
  }
}
