'use strict';

/**
 * Integração modular das ferramentas de cerco no planeador de ataque.
 * O planeador mantém apenas pequenos pontos de extensão para este módulo.
 */
(() => {
  const VERSION = 1;
  let activeDraft = null;

  const toolsApi = () => globalThis.ReinosSiegeTools;

  function initializeDraft(draft) {
    activeDraft = draft;
    const empty = toolsApi()?.emptyToolMap?.() || {};
    draft?.waves?.forEach(wave => {
      Object.values(wave.flanks || {}).forEach(flank => {
        flank.tools = toolsApi()?.normalizeToolMap?.(flank.tools) || { ...empty };
      });
    });
    toolsApi()?.ensureState?.(draft?.context?.getProfile?.());
  }

  function releaseDraft(draft = null) {
    if (!draft || activeDraft === draft) activeDraft = null;
  }

  function cloneTools(source) {
    return toolsApi()?.normalizeToolMap?.(source) || {};
  }

  function assignedByType(type, excluded = null, waves = activeDraft?.waves) {
    let total = 0;
    (waves || []).forEach((wave, waveIndex) => {
      Object.entries(wave.flanks || {}).forEach(([flankId, flank]) => {
        if (excluded && excluded.waveIndex === waveIndex && excluded.flankId === flankId) return;
        total += Math.max(0, Math.floor(Number(flank?.tools?.[type]) || 0));
      });
    });
    return total;
  }

  function totalAssigned(waves = activeDraft?.waves) {
    return Object.keys(toolsApi()?.CATALOG || {}).reduce((sum, type) => sum + assignedByType(type, null, waves), 0);
  }

  function toolRow(type, tool, waveIndex, flankId, flank, context) {
    const profile = context.getProfile();
    toolsApi().ensureState(profile);
    const centerLocked = Boolean(tool.centerOnly && flankId !== 'center');
    const disabled = !flank.enabled || centerLocked;
    const selected = Math.max(0, Math.floor(Number(flank.tools?.[type]) || 0));
    const assignedOther = assignedByType(type, { waveIndex, flankId });
    const stock = Math.max(0, Number(profile.siegeTools[type]) || 0);
    const remaining = Math.max(0, stock - assignedOther);
    const effect = `${tool.effectLabel} −${tool.effectPerUnit}%`;
    return `<label class="attack-tool-row ${disabled ? 'is-disabled' : ''}" title="${context.escapeHtml(centerLocked ? 'O Ariete só pode ser usado no ataque frontal.' : tool.description)}">
      <span class="attack-tool-name">${toolsApi().icon(type, 'normal')}<span><b>${context.escapeHtml(tool.shortName)}</b><small>${context.escapeHtml(effect)}</small></span></span>
      <input class="attack-tool-input" data-wave="${waveIndex}" data-flank="${flankId}" data-type="${type}" type="number" min="0" max="${remaining}" step="1" value="${selected}" ${disabled ? 'disabled' : ''} />
      <em>de <span data-tool-remaining="${type}">${context.format(Math.max(0, stock - assignedByType(type)))}</span></em>
    </label>`;
  }

  function renderFlankTools(waveIndex, flankId, context) {
    const flank = activeDraft?.waves?.[waveIndex]?.flanks?.[flankId];
    if (!flank) return '';
    flank.tools = cloneTools(flank.tools);
    const rows = Object.entries(toolsApi()?.CATALOG || {}).map(([type, tool]) => toolRow(type, tool, waveIndex, flankId, flank, context)).join('');
    return `<div class="attack-tools-section"><div class="attack-tools-heading"><span>Ferramentas de cerco</span><small>Produzidas na Oficina</small></div>${rows}</div>`;
  }

  function summaryHtml(context) {
    const profile = context.getProfile();
    toolsApi()?.ensureState?.(profile);
    const inventory = Object.entries(toolsApi()?.CATALOG || {}).map(([type, tool]) => {
      const used = assignedByType(type);
      const stock = Math.max(0, Number(profile.siegeTools[type]) || 0);
      return `<div class="attack-tool-summary-row">${toolsApi().icon(type, 'normal')}<span>${context.escapeHtml(tool.name)}</span><strong>${context.format(Math.max(0, stock - used))}/${context.format(stock)}</strong></div>`;
    }).join('');
    return `<div class="attack-tools-summary"><h4>Ferramentas disponíveis</h4>${inventory}<div class="attack-tools-total"><span>Total colocado</span><strong data-attack-tools-total>${context.format(totalAssigned())}</strong></div></div>`;
  }

  function updateSummaries(context) {
    if (!activeDraft) return;
    const profile = context.getProfile();
    Object.keys(toolsApi()?.CATALOG || {}).forEach(type => {
      const remaining = Math.max(0, (Number(profile.siegeTools?.[type]) || 0) - assignedByType(type));
      document.querySelectorAll(`[data-tool-remaining="${type}"]`).forEach(element => { element.textContent = context.format(remaining); });
    });
    const total = document.querySelector('[data-attack-tools-total]');
    if (total) total.textContent = context.format(totalAssigned());
  }

  function clearFlank(waveIndex, flankId) {
    const flank = activeDraft?.waves?.[waveIndex]?.flanks?.[flankId];
    if (!flank) return;
    flank.tools = toolsApi().emptyToolMap();
  }

  function clearWave(waveIndex) {
    const wave = activeDraft?.waves?.[waveIndex];
    if (!wave) return;
    Object.keys(wave.flanks || {}).forEach(flankId => clearFlank(waveIndex, flankId));
  }

  function clearAll() {
    activeDraft?.waves?.forEach((_wave, index) => clearWave(index));
  }

  function validatePlan(waves, context) {
    const profile = context.getProfile();
    toolsApi()?.ensureState?.(profile);
    for (const [type, tool] of Object.entries(toolsApi()?.CATALOG || {})) {
      const requested = assignedByType(type, null, waves);
      const available = Math.max(0, Number(profile.siegeTools[type]) || 0);
      if (requested > available) return { ok: false, message: `Já não tens ${tool.name} suficientes na Oficina.` };
    }
    for (const wave of waves || []) {
      for (const [flankId, flank] of Object.entries(wave.flanks || {})) {
        if (flankId !== 'center' && Number(flank.tools?.ram) > 0) return { ok: false, message: 'O Ariete só pode ser colocado no ataque frontal.' };
      }
    }
    return { ok: true };
  }

  function consumePlan(profile, waves) {
    toolsApi()?.ensureState?.(profile);
    for (const type of Object.keys(toolsApi()?.CATALOG || {})) {
      const amount = assignedByType(type, null, waves);
      profile.siegeTools[type] = Math.max(0, (Number(profile.siegeTools[type]) || 0) - amount);
    }
  }

  function addToolMap(target, source) {
    for (const type of Object.keys(toolsApi()?.CATALOG || {})) {
      target[type] = (Number(target[type]) || 0) + Math.max(0, Math.floor(Number(source?.[type]) || 0));
    }
    return target;
  }

  function summarizePlan(waves) {
    const summary = toolsApi()?.emptyToolMap?.() || {};
    (waves || []).forEach(wave => Object.values(wave.flanks || {}).forEach(flank => addToolMap(summary, flank.tools)));
    return summary;
  }

  function applyToSector(sector, flankTools, flankId) {
    return toolsApi()?.applyToSector?.(sector, flankTools, flankId) || {
      reductions: { wall: 0, gate: 0, ranged: 0 },
      wallBonus: Number(sector?.wallBonus) || 0,
      gateBonus: Number(sector?.gateBonus) || 0,
      rangedBonus: Number(sector?.rangedBonus) || 0
    };
  }

  document.addEventListener('input', event => {
    const input = event.target.closest?.('.attack-tool-input');
    if (!input || !activeDraft) return;
    const waveIndex = Number(input.dataset.wave);
    const flankId = input.dataset.flank;
    const type = input.dataset.type;
    const flank = activeDraft.waves?.[waveIndex]?.flanks?.[flankId];
    const tool = toolsApi()?.CATALOG?.[type];
    if (!flank?.enabled || !tool || (tool.centerOnly && flankId !== 'center')) return;
    const profile = activeDraft.context.getProfile();
    toolsApi().ensureState(profile);
    const other = assignedByType(type, { waveIndex, flankId });
    const maximum = Math.max(0, (Number(profile.siegeTools[type]) || 0) - other);
    const value = Math.max(0, Math.min(maximum, Math.floor(Number(input.value) || 0)));
    flank.tools[type] = value;
    if (String(value) !== input.value) input.value = String(value);
    updateSummaries(activeDraft.context);
  });

  globalThis.ReinosAttackTools = Object.freeze({
    VERSION,
    initializeDraft,
    releaseDraft,
    cloneTools,
    renderFlankTools,
    summaryHtml,
    updateSummaries,
    clearFlank,
    clearWave,
    clearAll,
    validatePlan,
    consumePlan,
    summarizePlan,
    addToolMap,
    applyToSector
  });
})();
