'use strict';

/**
 * Sistema modular da Oficina.
 *
 * Responsabilidades:
 * - abrir a interface de produção ao clicar no edifício Oficina;
 * - gerir o inventário das ferramentas de cerco;
 * - gerir a fila de produção e os respetivos tempos;
 * - concluir produções durante o ciclo normal do jogo.
 */
(() => {
  const VERSION = 1;
  let selectedType = 'ladder';
  let selectedBuildingId = null;
  let quantity = 1;
  let currentContext = null;

  const api = () => globalThis.ReinosSiegeTools;

  function ensureState(profile) {
    return api()?.ensureState?.(profile) || false;
  }

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

  function toolUnlocked(tool, workshopLevel) {
    return Boolean(tool) && workshopLevel >= (Number(tool.workshopLevel) || 1);
  }

  function queueItemHtml(item, index, context, profile) {
    const tools = api();
    const tool = tools.CATALOG[item.type];
    const active = index === 0;
    const waiting = Number(item.startedAt) > context.now();
    const label = active && !waiting ? 'Em produção' : 'Em espera';
    return `<div class="workshop-queue-slot is-filled ${active && !waiting ? 'is-active' : ''}">
      <div class="workshop-slot-icon">${tools.icon(item.type, 'small')}</div>
      <div class="workshop-slot-data"><b>${context.escapeHtml(tool.name)} × ${context.format(item.count)}</b><small>${label}</small><span data-countdown="${item.endAt}">${context.formatTime(item.endAt - context.now())}</span></div>
      <button class="workshop-cancel-item" data-action="workshop-cancel" data-id="${context.escapeHtml(item.id)}" title="Cancelar produção">×</button>
    </div>`;
  }

  function emptyQueueSlot(index) {
    return `<div class="workshop-queue-slot is-empty"><span>${index + 1}</span><small>Fila livre</small></div>`;
  }

  function queueHtml(context, profile) {
    const tools = api();
    return Array.from({ length: tools.QUEUE_LIMIT }, (_, index) => profile.workshopQueue[index]
      ? queueItemHtml(profile.workshopQueue[index], index, context, profile)
      : emptyQueueSlot(index)).join('');
  }

  function stockBadge(type, context, profile) {
    return `<span class="workshop-stock-badge">Armazém <b>${context.format(profile.siegeTools[type] || 0)}</b></span>`;
  }

  function catalogCard(type, tool, context, profile, workshopLevel) {
    const unlocked = toolUnlocked(tool, workshopLevel);
    const selected = selectedType === type;
    const perUnit = api().unitTimeMs(type, workshopLevel);
    return `<button class="workshop-tool-card ${selected ? 'is-selected' : ''} ${unlocked ? '' : 'is-locked'}" data-action="workshop-select" data-type="${type}" ${unlocked ? '' : 'disabled'}>
      <div class="workshop-tool-card-icon">${api().icon(type, 'card')}</div>
      <strong>${context.escapeHtml(tool.name)}</strong>
      <small>${unlocked ? context.escapeHtml(tool.description) : `Desbloqueia na Oficina Nv. ${tool.workshopLevel}`}</small>
      <div class="workshop-tool-card-bottom">${stockBadge(type, context, profile)}<span>⏳ ${context.formatTime(perUnit)}</span></div>
    </button>`;
  }

  function costLine(type, count, context) {
    const cost = api().batchCost(type, count);
    if (context.costsHtml) return context.costsHtml(cost);
    return globalThis.ReinosResourceIcons?.list?.(cost, Object.keys(cost), context.format) || '';
  }

  function selectedDetails(context, profile, building) {
    const tools = api();
    const workshopLevel = Math.max(1, Number(building.level) || 1);
    const tool = tools.CATALOG[selectedType] || tools.CATALOG.ladder;
    const count = safeQuantity(quantity);
    const totalTime = tools.batchTimeMs(tool.id, count, workshopLevel);
    const effectSuffix = tool.centerOnly ? ' Apenas pode ser usado no ataque frontal.' : '';
    return `<section class="workshop-selected-panel">
      <div class="workshop-selected-visual">${tools.icon(tool.id, 'large')}<span>${stockBadge(tool.id, context, profile)}</span></div>
      <div class="workshop-selected-info">
        <h3>${context.escapeHtml(tool.name)}</h3>
        <p>${context.escapeHtml(tool.description)}${context.escapeHtml(effectSuffix)}</p>
        <div class="workshop-effect"><span>${context.escapeHtml(tool.effectLabel)}</span><strong>−${tool.effectPerUnit}% por unidade</strong></div>
        <div class="workshop-quantity-row">
          <button data-action="workshop-quantity-minus" aria-label="Diminuir quantidade">−</button>
          <label><span>Quantidade</span><input id="workshop-quantity" type="number" min="1" max="500" value="${count}" /></label>
          <button data-action="workshop-quantity-plus" aria-label="Aumentar quantidade">＋</button>
        </div>
        <div class="workshop-production-summary">
          <div><span>Tempo total</span><strong id="workshop-total-time">${context.formatTime(totalTime)}</strong></div>
          <div><span>Custo total</span><div class="costs" id="workshop-total-cost">${costLine(tool.id, count, context)}</div></div>
        </div>
        <button class="workshop-produce-btn" data-action="workshop-produce" data-type="${tool.id}">Produzir</button>
      </div>
    </section>`;
  }

  function bodyHtml(context, profile, building) {
    const tools = api();
    const level = Math.max(1, Number(building.level) || 1);
    const speed = Math.round(tools.speedMultiplier(level) * 100);
    const cards = Object.entries(tools.CATALOG).map(([type, tool]) => catalogCard(type, tool, context, profile, level)).join('');
    const comparison = globalThis.ReinosBuildingUpgradeBenefits?.comparisonHtml?.(building, {
      profile,
      definitions: context.getBuildingsMeta(),
      resourceMeta: context.getResourceMeta(),
      format: context.format,
      formatTime: context.formatTime,
      escapeHtml: context.escapeHtml
    }, { compact: true }) || '';
    const upgradeOrder = `<div class="building-upgrade-order"><div><span>Tempo da melhoria</span><strong>${context.formatTime(context.buildingTime('workshop', level + 1))}</strong></div><div><span>Custo da melhoria</span><div class="costs">${context.costsHtml(context.buildingCost('workshop', level + 1))}</div></div></div>`;
    return `<div id="workshop-system" class="workshop-shell">
      <header class="workshop-banner">
        <div class="workshop-banner-crest">⚒</div>
        <div><small>Edifício militar</small><h2>Oficina — Nível ${level}</h2><p>Produz ferramentas para reduzir as defesas inimigas durante os ataques.</p></div>
        <div class="workshop-speed"><span>Velocidade</span><strong>${speed}%</strong></div>
      </header>
      ${comparison}${upgradeOrder}
      <section class="workshop-queue-section">
        <div class="workshop-section-heading"><div><small>Produção</small><h3>Fila da oficina</h3></div><span>${profile.workshopQueue.length}/${tools.QUEUE_LIMIT} espaços ocupados</span></div>
        <div class="workshop-queue-grid">${queueHtml(context, profile)}</div>
      </section>
      <section class="workshop-catalog-section">
        <div class="workshop-section-heading"><div><small>Catálogo</small><h3>Ferramentas de cerco</h3></div><span>Seleciona o item que pretendes fabricar</span></div>
        <div class="workshop-tool-grid">${cards}</div>
      </section>
      ${selectedDetails(context, profile, building)}
    </div>`;
  }

  function footerHtml(building) {
    return `<button class="danger-btn" data-action="building-demolish" data-id="${building.id}">Demolir</button>
      <button class="secondary-btn" data-action="castle-move-start" data-id="${building.id}">Mover</button>
      <button class="secondary-btn" data-action="modal-close">Fechar</button>
      <button class="action-btn" data-action="building-upgrade" data-id="${building.id}">Melhorar oficina</button>`;
  }

  function open(buildingId, context) {
    const profile = context.getProfile();
    ensureState(profile);
    const building = profile.buildings?.find(item => item.id === buildingId && item.type === 'workshop');
    if (!building || building.status !== 'ready' || Number(building.level) < 1) return false;
    const level = Math.max(1, Number(building.level) || 1);
    if (!toolUnlocked(api().CATALOG[selectedType], level)) selectedType = Object.keys(api().CATALOG).find(type => toolUnlocked(api().CATALOG[type], level)) || 'ladder';
    selectedBuildingId = building.id;
    currentContext = context;
    quantity = safeQuantity(quantity);
    context.openModal('Oficina', bodyHtml(context, profile, building), footerHtml(building));
    document.querySelector('.modal')?.classList.add('workshop-modal');
    return true;
  }

  function reopen() {
    if (!currentContext || !selectedBuildingId) return;
    open(selectedBuildingId, currentContext);
  }

  function updateProductionPreview() {
    if (!currentContext || !selectedBuildingId) return;
    const profile = currentContext.getProfile();
    const building = profile.buildings?.find(item => item.id === selectedBuildingId);
    if (!building) return;
    const input = document.querySelector('#workshop-quantity');
    quantity = safeQuantity(input?.value ?? quantity);
    if (input && String(quantity) !== input.value) input.value = String(quantity);
    const time = api().batchTimeMs(selectedType, quantity, building.level);
    const timeEl = document.querySelector('#workshop-total-time');
    const costEl = document.querySelector('#workshop-total-cost');
    if (timeEl) timeEl.textContent = currentContext.formatTime(time);
    if (costEl) costEl.innerHTML = costLine(selectedType, quantity, currentContext);
  }

  async function produce(type, context) {
    const profile = context.getProfile();
    ensureState(profile);
    const building = profile.buildings?.find(item => item.id === selectedBuildingId && item.type === 'workshop');
    const tool = api().CATALOG[type];
    if (!building || building.status !== 'ready') return context.toast('A Oficina não está disponível.', 'error');
    if (!tool || !toolUnlocked(tool, building.level)) return context.toast('Esta ferramenta ainda não está desbloqueada.', 'error');
    if (profile.workshopQueue.length >= api().QUEUE_LIMIT) return context.toast('A fila da Oficina está cheia.', 'error');
    const count = safeQuantity(document.querySelector('#workshop-quantity')?.value ?? quantity);
    const cost = api().batchCost(type, count);
    if (!context.canAfford(cost)) return context.toast('Não tens recursos suficientes para esta produção.', 'error');
    context.spend(cost);
    const currentTime = context.now();
    const previousEnd = profile.workshopQueue.length ? Number(profile.workshopQueue.at(-1).endAt) || currentTime : currentTime;
    const startedAt = Math.max(currentTime, previousEnd);
    const endAt = startedAt + api().batchTimeMs(type, count, building.level);
    profile.workshopQueue.push({
      id: context.uid('wq'),
      type,
      count,
      workshopLevel: building.level,
      createdAt: currentTime,
      startedAt,
      endAt
    });
    profile.reports = Array.isArray(profile.reports) ? profile.reports : [];
    profile.reports.push({
      id: context.uid('r'),
      at: currentTime,
      title: `Produção iniciada: ${tool.name}`,
      result: 'info',
      text: `${count} unidade(s) de ${tool.name} foram adicionadas à fila da Oficina.`
    });
    await context.persist(true);
    context.renderGame();
    context.toast(`${count} ${tool.name}(s) adicionadas à fila.`, 'success');
    reopen();
  }

  async function cancel(itemId, context) {
    const profile = context.getProfile();
    ensureState(profile);
    const index = profile.workshopQueue.findIndex(item => item.id === itemId);
    if (index < 0) return;
    const item = profile.workshopQueue[index];
    const tool = api().CATALOG[item.type];
    const originalCost = api().batchCost(item.type, item.count);
    const refundFactor = context.now() < Number(item.startedAt) ? 0.50 : 0.25;
    const refund = Object.fromEntries(Object.entries(originalCost).map(([resource, value]) => [resource, Math.floor(value * refundFactor)]));
    if (context.addResources) context.addResources(refund);
    else Object.entries(refund).forEach(([resource, value]) => { profile.resources[resource] = (Number(profile.resources[resource]) || 0) + value; });
    profile.workshopQueue.splice(index, 1);
    let cursor = context.now();
    profile.workshopQueue.forEach(queueItem => {
      const duration = api().batchTimeMs(queueItem.type, queueItem.count, queueItem.workshopLevel || 1);
      queueItem.startedAt = Math.max(cursor, context.now());
      queueItem.endAt = queueItem.startedAt + duration;
      cursor = queueItem.endAt;
    });
    await context.persist(true);
    context.renderGame();
    context.toast(`Produção de ${tool.name} cancelada. Recuperaste parte dos materiais.`, 'info');
    reopen();
  }

  function process(profile, time, context = {}) {
    ensureState(profile);
    const completed = profile.workshopQueue.filter(item => Number(item.endAt) <= time);
    if (!completed.length) return false;
    profile.reports = Array.isArray(profile.reports) ? profile.reports : [];
    completed.forEach(item => {
      const tool = api().CATALOG[item.type];
      profile.siegeTools[item.type] = (Number(profile.siegeTools[item.type]) || 0) + item.count;
      profile.reports.push({
        id: context.uid?.('r') || `r_${Date.now()}_${Math.random().toString(36).slice(2)}`,
        at: time,
        title: `Produção concluída: ${tool.name}`,
        result: 'info',
        text: `${item.count} unidade(s) de ${tool.name} estão disponíveis no armazém da Oficina.`
      });
      context.toast?.(`${item.count} ${tool.name}(s) prontas na Oficina.`, 'success');
    });
    profile.workshopQueue = profile.workshopQueue.filter(item => Number(item.endAt) > time);
    return true;
  }

  async function handleAction(action, element, context) {
    const profile = context.getProfile?.();
    if (!profile) return false;
    ensureState(profile);

    if (action === 'building-open') {
      const building = profile.buildings?.find(item => item.id === element.dataset.id);
      if (building?.type !== 'workshop' || building.status !== 'ready' || Number(building.level) < 1) return false;
      open(building.id, context);
      return true;
    }
    if (action === 'workshop-select') {
      selectedType = String(element.dataset.type || 'ladder');
      reopen();
      return true;
    }
    if (action === 'workshop-quantity-minus') {
      quantity = safeQuantity((Number(document.querySelector('#workshop-quantity')?.value) || quantity) - 1);
      const input = document.querySelector('#workshop-quantity');
      if (input) input.value = quantity;
      updateProductionPreview();
      return true;
    }
    if (action === 'workshop-quantity-plus') {
      quantity = safeQuantity((Number(document.querySelector('#workshop-quantity')?.value) || quantity) + 1);
      const input = document.querySelector('#workshop-quantity');
      if (input) input.value = quantity;
      updateProductionPreview();
      return true;
    }
    if (action === 'workshop-produce') {
      selectedType = String(element.dataset.type || selectedType);
      await produce(selectedType, context);
      return true;
    }
    if (action === 'workshop-cancel') {
      await cancel(element.dataset.id, context);
      return true;
    }
    return false;
  }

  document.addEventListener('input', event => {
    if (event.target?.id !== 'workshop-quantity') return;
    updateProductionPreview();
  });

  globalThis.ReinosWorkshopSystem = Object.freeze({
    VERSION,
    ensureState,
    open,
    process,
    handleAction
  });
})();
