'use strict';

/**
 * Comparação modular dos benefícios de melhoria dos edifícios.
 *
 * Responsabilidades:
 * - calcular os benefícios atuais e do nível seguinte;
 * - apresentar a diferença de forma uniforme em todos os edifícios;
 * - fornecer o bónus real de velocidade de recrutamento do Quartel;
 * - não executar melhorias nem alterar recursos, filas ou construção.
 */
(() => {
  const VERSION = 1;
  const PRODUCTION_GROWTH = 1.45;
  const BARRACKS_SPEED_PER_LEVEL = 5;

  function safeLevel(value) {
    return Math.max(1, Math.floor(Number(value) || 1));
  }

  function formatNumber(value, context) {
    return context?.format ? context.format(value) : Math.round(Number(value) || 0).toLocaleString('pt-PT');
  }

  function formatTime(value, context) {
    return context?.formatTime ? context.formatTime(value) : `${Math.max(0, Math.round(Number(value) || 0))} ms`;
  }

  function esc(value, context) {
    return context?.escapeHtml ? context.escapeHtml(value) : String(value ?? '');
  }

  function resourceIcon(type) {
    return globalThis.ReinosResourceIcons?.icon?.(type) || '';
  }

  function rawProduction(definition, level, resource) {
    const base = Number(definition?.production?.[resource]) || 0;
    return Math.round(base * Math.pow(PRODUCTION_GROWTH, safeLevel(level) - 1));
  }

  function cloneWithLevel(profile, buildingId, nextLevel) {
    const clone = {
      ...(profile || {}),
      buildings: (profile?.buildings || []).map(building => building.id === buildingId
        ? { ...building, level: safeLevel(nextLevel) }
        : { ...building })
    };
    clone.castleState = profile?.castleState ? { ...profile.castleState } : undefined;
    return clone;
  }

  function keepLevel(profile) {
    return safeLevel(profile?.buildings?.find(building => building.type === 'keep')?.level || 1);
  }

  function warehouseCapacity(profile) {
    const levels = (profile?.buildings || [])
      .filter(building => building.type === 'warehouse')
      .reduce((sum, building) => sum + safeLevel(building.level), 0);
    return 9000 + levels * 6000 + keepLevel(profile) * 1200;
  }

  function watchtowerDefense(profile) {
    return (profile?.buildings || [])
      .filter(building => building.type === 'watchtower' && building.status !== 'constructing')
      .reduce((sum, building) => sum + safeLevel(building.level) * 180, 0);
  }

  function publicOrder(profile) {
    if (globalThis.ReinosCastleSystem?.publicOrder) return globalThis.ReinosCastleSystem.publicOrder(profile);
    let value = 100;
    for (const building of profile?.buildings || []) {
      const level = safeLevel(building.level);
      if (building.type === 'decoration') value += 35 * level;
      if (building.type === 'house') value -= 10 * level;
      if (building.status === 'burning') value -= 25 * level;
    }
    value += (Number(profile?.castleState?.expansionLevel) || 0) * 8;
    return Math.max(0, Math.round(value));
  }

  function productivity(profile) {
    if (globalThis.ReinosCastleSystem?.productivityMultiplier) return globalThis.ReinosCastleSystem.productivityMultiplier(profile);
    return Math.max(0.65, Math.min(1.6, 1 + (publicOrder(profile) - 100) / 400));
  }

  function barracksSpeedBonus(level) {
    return Math.min(100, safeLevel(level) * BARRACKS_SPEED_PER_LEVEL);
  }

  function barracksTrainingMultiplier(level) {
    return 1 + barracksSpeedBonus(level) / 100;
  }

  function barracksTrainingTimeMs(baseTimeMs, level) {
    return Math.max(1000, Math.round((Number(baseTimeMs) || 0) / barracksTrainingMultiplier(level)));
  }

  function stablesMount(level) {
    const safe = safeLevel(level);
    if (safe >= 3) return { name: 'Corcel', reduction: 41 };
    if (safe >= 2) return { name: 'Cavalo de guerra', reduction: 30 };
    return { name: 'Cavalo', reduction: 20 };
  }

  function stablesCostDiscount(level) {
    return Math.min(30, Math.max(0, safeLevel(level) - 3) * 5);
  }

  function row(label, current, next, difference, options = {}) {
    return {
      label,
      current: String(current),
      next: String(next),
      difference: String(difference),
      tone: options.tone || 'positive',
      icon: options.icon || '',
      note: options.note || ''
    };
  }

  function numberDelta(current, next, suffix, context, options = {}) {
    const delta = Number(next) - Number(current);
    const sign = delta > 0 ? '+' : '';
    return `${sign}${formatNumber(delta, context)}${suffix || ''}`;
  }

  function percentDelta(current, next) {
    const delta = Number(next) - Number(current);
    return `${delta > 0 ? '+' : ''}${Math.round(delta)} p.p.`;
  }

  function benefitRows(building, context = {}) {
    const profile = context.profile || context.getProfile?.();
    const definitions = context.definitions || context.getBuildingsMeta?.() || {};
    const definition = definitions[building?.type] || {};
    const currentLevel = safeLevel(building?.level);
    const nextLevel = currentLevel + 1;
    const rows = [];

    rows.push(row('Nível do edifício', currentLevel, nextLevel, '+1', { icon: '⬆' }));

    if (definition.production) {
      for (const resource of Object.keys(definition.production)) {
        const current = rawProduction(definition, currentLevel, resource);
        const next = rawProduction(definition, nextLevel, resource);
        const resourceName = context.resourceMeta?.[resource]?.name || context.getResourceMeta?.()?.[resource]?.name || resource;
        rows.push(row(
          `Produção de ${resourceName}`,
          `${formatNumber(current, context)}/h`,
          `${formatNumber(next, context)}/h`,
          numberDelta(current, next, '/h', context),
          { icon: resourceIcon(resource) }
        ));
      }
    }

    const nextProfile = profile ? cloneWithLevel(profile, building.id, nextLevel) : null;

    if (building.type === 'keep' && profile && nextProfile) {
      const currentCapacity = warehouseCapacity(profile);
      const nextCapacity = warehouseCapacity(nextProfile);
      rows.push(row('Capacidade máxima de recursos', formatNumber(currentCapacity, context), formatNumber(nextCapacity, context), numberDelta(currentCapacity, nextCapacity, '', context), { icon: '📦' }));
      rows.push(row('Nível máximo dos outros edifícios', currentLevel + 2, nextLevel + 2, '+1', { icon: '🏗️' }));
    }

    if (building.type === 'warehouse' && profile && nextProfile) {
      const currentCapacity = warehouseCapacity(profile);
      const nextCapacity = warehouseCapacity(nextProfile);
      rows.push(row('Capacidade total do armazém', formatNumber(currentCapacity, context), formatNumber(nextCapacity, context), numberDelta(currentCapacity, nextCapacity, '', context), { icon: '📦' }));
    }

    if (building.type === 'barracks') {
      const current = barracksSpeedBonus(currentLevel);
      const next = barracksSpeedBonus(nextLevel);
      const baseExample = 100 * 2 * 1000;
      const currentTime = barracksTrainingTimeMs(baseExample, currentLevel);
      const nextTime = barracksTrainingTimeMs(baseExample, nextLevel);
      rows.push(row('Bónus de velocidade de recrutamento', `+${current}%`, `+${next}%`, percentDelta(current, next), { icon: '⚔️' }));
      rows.push(row('Tempo para 100 Lanceiros', formatTime(currentTime, context), formatTime(nextTime, context), `−${formatTime(currentTime - nextTime, context)}`, { icon: '⏳' }));
    }

    if (building.type === 'stables') {
      const currentMount = stablesMount(currentLevel);
      const nextMount = stablesMount(nextLevel);
      rows.push(row('Montada mais rápida disponível', currentMount.name, nextMount.name, currentMount.name === nextMount.name ? 'Mantida' : 'Nova', { icon: '🐎' }));
      rows.push(row('Redução máxima do tempo de viagem', `−${currentMount.reduction}%`, `−${nextMount.reduction}%`, `${nextMount.reduction > currentMount.reduction ? '+' : ''}${nextMount.reduction - currentMount.reduction} p.p.`, { icon: '⏳' }));
      const currentDiscount = stablesCostDiscount(currentLevel);
      const nextDiscount = stablesCostDiscount(nextLevel);
      if (currentLevel >= 3 || nextLevel > 3) {
        rows.push(row('Desconto no custo das montadas', `${currentDiscount}%`, `${nextDiscount}%`, `${nextDiscount > currentDiscount ? '+' : ''}${nextDiscount - currentDiscount} p.p.`, { icon: '🪙' }));
      }
    }

    if (building.type === 'workshop' && globalThis.ReinosSiegeTools) {
      const currentMultiplier = globalThis.ReinosSiegeTools.speedMultiplier(currentLevel);
      const nextMultiplier = globalThis.ReinosSiegeTools.speedMultiplier(nextLevel);
      const currentSpeed = Math.round(currentMultiplier * 100);
      const nextSpeed = Math.round(nextMultiplier * 100);
      const currentTime = globalThis.ReinosSiegeTools.unitTimeMs('ladder', currentLevel);
      const nextTime = globalThis.ReinosSiegeTools.unitTimeMs('ladder', nextLevel);
      rows.push(row('Velocidade de produção', `${currentSpeed}%`, `${nextSpeed}%`, percentDelta(currentSpeed, nextSpeed), { icon: '⚒️' }));
      rows.push(row('Tempo por Escada', formatTime(currentTime, context), formatTime(nextTime, context), `−${formatTime(currentTime - nextTime, context)}`, { icon: '⏳' }));
      const newlyUnlocked = Object.values(globalThis.ReinosSiegeTools.CATALOG || {})
        .filter(tool => Number(tool.workshopLevel) === nextLevel)
        .map(tool => tool.name);
      if (newlyUnlocked.length) rows.push(row('Novo desbloqueio', '—', newlyUnlocked.join(', '), 'Novo', { icon: '🔓' }));
    }

    if (building.type === 'watchtower' && profile && nextProfile) {
      const currentDefense = watchtowerDefense(profile);
      const nextDefense = watchtowerDefense(nextProfile);
      rows.push(row('Força defensiva total das torres', formatNumber(currentDefense, context), formatNumber(nextDefense, context), numberDelta(currentDefense, nextDefense, '', context), { icon: '🛡️' }));
    }

    if ((building.type === 'decoration' || building.type === 'house') && profile && nextProfile) {
      const currentOrder = publicOrder(profile);
      const nextOrder = publicOrder(nextProfile);
      const currentProductivity = Math.round(productivity(profile) * 100);
      const nextProductivity = Math.round(productivity(nextProfile) * 100);
      rows.push(row('Ordem pública do castelo', formatNumber(currentOrder, context), formatNumber(nextOrder, context), numberDelta(currentOrder, nextOrder, '', context), {
        icon: '🌿',
        tone: nextOrder >= currentOrder ? 'positive' : 'negative'
      }));
      rows.push(row('Produtividade geral', `${currentProductivity}%`, `${nextProductivity}%`, percentDelta(currentProductivity, nextProductivity), {
        icon: '⚙️',
        tone: nextProductivity >= currentProductivity ? 'positive' : 'negative'
      }));
    }

    return rows;
  }

  function rowsHtml(rows, context = {}) {
    return rows.map(item => `<div class="upgrade-benefit-row ${item.tone === 'negative' ? 'is-negative' : ''}">
      <div class="upgrade-benefit-name"><span>${item.icon || '•'}</span><div><strong>${esc(item.label, context)}</strong>${item.note ? `<small>${esc(item.note, context)}</small>` : ''}</div></div>
      <div class="upgrade-benefit-current">${item.current}</div>
      <div class="upgrade-benefit-arrow">→</div>
      <div class="upgrade-benefit-next">${item.next}</div>
      <div class="upgrade-benefit-difference">${item.difference}</div>
    </div>`).join('');
  }

  function comparisonHtml(building, context = {}, options = {}) {
    if (!building) return '';
    const definitions = context.definitions || context.getBuildingsMeta?.() || {};
    const definition = definitions[building.type] || {};
    const level = safeLevel(building.level);
    const maxLevel = Number(definition.maxLevel) || 0;
    if (maxLevel && level >= maxLevel) {
      return `<section class="upgrade-benefits-panel is-maxed"><header><div><small>Benefícios do edifício</small><h3>Nível máximo atingido</h3></div><span class="upgrade-level-badge">Nv. ${level}</span></header><p>Este edifício já não pode ser melhorado.</p></section>`;
    }

    const rows = benefitRows(building, context);
    const compactClass = options.compact ? ' is-compact' : '';
    return `<section class="upgrade-benefits-panel${compactClass}">
      <header><div><small>Comparação da melhoria</small><h3>Benefícios atuais e após a melhoria</h3></div><span class="upgrade-level-badge">Nv. ${level} → ${level + 1}</span></header>
      <div class="upgrade-benefit-head"><span>Benefício</span><span>Atual</span><span></span><span>Próximo</span><span>Diferença</span></div>
      <div class="upgrade-benefit-list">${rowsHtml(rows, context)}</div>
    </section>`;
  }

  function fortificationRows(kind, level, context = {}) {
    const current = safeLevel(level);
    const next = current + 1;
    if (kind === 'wall') return [row('Proteção dos flancos', `${current * 8}%`, `${next * 8}%`, '+8 p.p.', { icon: '🧱' })];
    if (kind === 'gate') return [row('Proteção da frente', `${current * 10}%`, `${next * 10}%`, '+10 p.p.', { icon: '🚪' })];
    return [row('Capacidade defensiva', formatNumber(current * 12, context), formatNumber(next * 12, context), '+12', { icon: '🗼' })];
  }

  function fortificationComparisonHtml(kind, level, context = {}) {
    const names = { wall: 'Muralha', gate: 'Portão', tower: 'Torres' };
    return `<div class="upgrade-benefits-panel is-fortification is-compact">
      <header><div><small>${names[kind] || 'Defesa'}</small><h3>Nível ${safeLevel(level)} → ${safeLevel(level) + 1}</h3></div></header>
      <div class="upgrade-benefit-list">${rowsHtml(fortificationRows(kind, level, context), context)}</div>
    </div>`;
  }

  globalThis.ReinosBuildingUpgradeBenefits = Object.freeze({
    VERSION,
    BARRACKS_SPEED_PER_LEVEL,
    barracksSpeedBonus,
    barracksTrainingMultiplier,
    barracksTrainingTimeMs,
    benefitRows,
    comparisonHtml,
    fortificationComparisonHtml
  });
})();
