import { VermineUtils } from '../roll.mjs';

const { HandlebarsApplicationMixin } = foundry.applications.api;

/**
 * Dialogue d'apprentissage de Groupe (phase d'Expérience).
 * Permet de dépenser des Dés d'Expérience du Groupe pour tenter d'améliorer
 * le Niveau de Groupe, la Réserve de Groupe ou de développer une Capacité
 * collective. La progression est appliquée automatiquement en cas de réussite.
 */
export default class GroupLearningDialog extends HandlebarsApplicationMixin(foundry.applications.api.ApplicationV2) {
  #actor;

  static DEFAULT_OPTIONS = {
    classes: ['vermine-roll'],
    tag: 'form',
    window: {
      icon: 'fas fa-graduation-cap',
      resizable: false,
    },
    position: {
      width: 560,
      height: 560,
    },
    actions: {
      roll: GroupLearningDialog.#onRoll,
      cancel: GroupLearningDialog.#onCancel,
    },
  };

  static PARTS = {
    main: { template: 'systems/vermine2047/templates/dialogs/group-learning-dialog.hbs', scrollable: [''] },
  };

  static async create({ actorId }) {
    const actor = await game.actors.get(actorId);
    if (!actor) {
      ui.notifications.warn(game.i18n.localize('VERMINE.error_no_actor_selected'));
      return null;
    }
    return new GroupLearningDialog({ actor });
  }

  constructor(options = {}) {
    super(options);
    this.#actor = options.actor;
  }

  get title() {
    return game.i18n.localize('VERMINE.open_learning');
  }

  _prepareContext() {
    const actor = this.#actor;
    return {
      actor,
      system: actor.system,
      dice: actor.system?.experience?.dice || 0,
      abilities: actor.itemTypes.ability
        .filter((i) => i.system.type !== 'totem' && !i.system.learned)
        .map((a) => ({
          id: a.id,
          name: a.name,
          threshold: a.system?.learn?.threshold ?? 5,
          level: a.system?.level?.value ?? 1,
        })),
    };
  }

  _onRender() {
    this.element.dataset.actorId = this.#actor.id;
    for (const inp of this.element.querySelectorAll('[data-roll]')) {
      inp.addEventListener('change', () => this.#updateUI());
    }
    this.element.querySelector('#learning-dice')?.addEventListener('input', () => this.#updateUI());
    this.#updateUI();
  }

  get #el() { return this.element; }

  #getType() {
    return this.#el.querySelector('input[name="learning-type"]:checked')?.value ?? 'level';
  }

  #getAbilityId() {
    return this.#el.querySelector('#learning-ability')?.value ?? '';
  }

  #getDiceSpent() {
    return Math.max(1, parseInt(this.#el.querySelector('#learning-dice')?.value, 10) || 1);
  }

  #compute() {
    const actor = this.#actor;
    const type = this.#getType();
    const key = type === 'ability' ? this.#getAbilityId() : '';
    let difficulty = 7;
    let handicap = 0;
    let targetLevel = null;
    let targetLabel = '';

    if (type === 'level') {
      const current = actor.system?.level?.value || 1;
      difficulty = actor.system?.members?.length || 0;
      handicap = current;
      targetLevel = current + 1;
    } else if (type === 'reserve') {
      const current = actor.system?.reserve?.value || 0;
      difficulty = current;
      handicap = 2;
      targetLevel = current + 1;
    } else {
      const ability = key ? actor.items.get(key) : null;
      if (ability) {
        difficulty = ability.system?.learn?.threshold ?? 5;
        handicap = ability.system?.level?.value ?? 1;
        targetLabel = ability.name;
      }
    }

    const labels = {
      level: 'VERMINE.learn_level',
      reserve: 'VERMINE.learn_group_reserve',
      ability: 'VERMINE.learn_ability',
    };
    return {
      type,
      key,
      targetLevel,
      difficulty,
      handicap,
      poolModifier: 0,
      label: game.i18n.localize(labels[type] || labels.level),
      targetLabel,
    };
  }

  #updateUI() {
    const type = this.#getType();
    const show = (id, visible) => {
      const el = this.#el.querySelector(id);
      if (el) el.style.display = visible ? '' : 'none';
    };
    show('#learning-level-section', type === 'level');
    show('#learning-reserve-section', type === 'reserve');
    show('#learning-ability-section', type === 'ability');

    const c = this.#compute();
    const set = (sel, txt) => {
      const el = this.#el.querySelector(sel);
      if (el) el.textContent = txt;
    };
    set('#diff-value', c.difficulty);
    set('#handicap-value', c.handicap);
    set('#required-value', 1 + c.handicap);
    const pool = Math.max(0, this.#getDiceSpent() + c.poolModifier);
    set('#pool-value', `${pool}D${c.poolModifier ? ` (${c.poolModifier >= 0 ? '+' : ''}${c.poolModifier}D)` : ''}`);
    const poolInput = this.#el.querySelector('#learning-dice');
    if (poolInput) poolInput.max = this.#actor.system?.experience?.dice || 0;
  }

  static #onCancel() {
    this.close();
  }

  /** Renvoie la clé i18n d'erreur si le jet est impossible, sinon null. */
  #getError(c) {
    const actor = this.#actor;
    const ex = actor.system?.experience;
    // Limite : un seul Niveau, une seule Réserve et une seule Capacité par phase.
    if (ex?.learned?.phase === ex?.phase && ex.learned[c.type]) {
      return 'VERMINE.error_learning_limit';
    }
    if (c.type === 'level' && c.targetLevel !== null && (actor.system?.level?.value || 0) >= 10) {
      return 'VERMINE.error_group_level_max';
    }
    if (c.type === 'reserve' && c.targetLevel !== null &&
      (actor.system?.reserve?.value || 0) >= (actor.system?.reserve?.max || 10)) {
      return 'VERMINE.error_group_reserve_max';
    }
    if (c.type === 'ability') {
      if (!c.key) {
        return 'VERMINE.no_group_ability';
      }
      const ability = c.key ? actor.items.get(c.key) : null;
      const requiredLevel = ability?.system?.level?.value ?? 1;
      if (ability && (actor.system?.level?.value || 1) < requiredLevel) {
        return 'VERMINE.error_group_level_requirement';
      }
    }
    return null;
  }

  static async #onRoll() {
    const actor = this.#actor;
    const ex = actor.system?.experience;
    const spent = Math.min(this.#getDiceSpent(), ex?.dice || 0);
    if (spent < 1) {
      ui.notifications.warn(game.i18n.localize('VERMINE.error_no_experience_dice'));
      return;
    }

    const c = this.#compute();
    const errorKey = this.#getError(c);
    if (errorKey) {
      ui.notifications.warn(game.i18n.localize(errorKey));
      return;
    }

    const pool = Math.max(0, spent + c.poolModifier);
    const rollLabel = `${game.i18n.localize('VERMINE.open_learning')} — ${c.label}${c.targetLabel ? ` (${c.targetLabel})` : ''}`;

    const roll = await VermineUtils.roll({
      actor,
      NoD: pool,
      Reroll: 0,
      difficulty: c.difficulty,
      handicap: c.handicap,
      rollLabel,
      poolBreakdown: { ability: 0, skill: 0, selfControl: 0, specialty: 0, help: 0, tooling: 0, group: 0, total: pool },
      messageFlags: { 'vermine-learning': { type: c.type, key: c.key, spent, success: false } },
    });

    const required = 1 + c.handicap;
    if ((roll._total ?? 0) >= required) {
      await this.#applySuccess(c);
    }
    // Les Dés d'Expérience sont perdus que le jet soit réussi ou raté.
    await actor.update({ "system.experience.dice": Math.max(0, (actor.system.experience.dice || 0) - spent) });
    this.close();
  }

  async #applySuccess(c) {
    const actor = this.#actor;
    const updates = {};
    if (c.type === 'level') {
      const current = actor.system.level.value || 1;
      updates['system.level.value'] = Math.min(10, current + 1);
      updates['system.experience.learned.level'] = true;
    } else if (c.type === 'reserve') {
      const current = actor.system.reserve.value || 0;
      updates['system.reserve.value'] = Math.min(actor.system.reserve.max || 10, current + 1);
      updates['system.experience.learned.reserve'] = true;
    } else {
      if (c.key) {
        await actor.updateEmbeddedDocuments('Item', [{ _id: c.key, 'system.learned': true }]);
      }
      updates['system.experience.learned.ability'] = true;
    }
    updates['system.experience.learned.phase'] = actor.system.experience.phase;
    await actor.update(updates);
    ui.notifications.info(game.i18n.localize('VERMINE.learning_success'));
  }
}
