'use strict';

(function () {
  const FOLDER_ORDER = ['attack', 'espionage', 'kingdom'];
  const REPORTS_PER_PAGE = 7;
  const FOLDERS = Object.freeze({
    all: {
      id: 'all',
      icon: '🗂️',
      title: 'Todos',
      subtitle: 'Resumo das pastas'
    },
    attack: {
      id: 'attack',
      icon: '⚔️',
      title: 'Ataques',
      subtitle: 'Batalhas, defesas e regressos'
    },
    espionage: {
      id: 'espionage',
      icon: '🕵️',
      title: 'Espionagem',
      subtitle: 'Espionagens a barões e jogadores'
    },
    kingdom: {
      id: 'kingdom',
      icon: '🏰',
      title: 'Reino',
      subtitle: 'Construção, produção e avisos'
    }
  });

  let activeFolder = 'all';
  const activePageByFolder = { attack: 1, espionage: 1, kingdom: 1 };

  function includesAny(text, words) {
    const normalized = String(text || '').toLowerCase();
    return words.some(word => normalized.includes(word));
  }

  function classify(report) {
    const reportType = String(report?.reportType || '');
    const title = String(report?.title || '');
    const result = String(report?.result || '');

    if (reportType === 'espionage' || reportType === 'player-spy' || result === 'spy' || includesAny(title, ['espionagem'])) {
      return 'espionage';
    }

    if (
      reportType === 'battle' ||
      reportType === 'battle-defense' ||
      report?.battleData ||
      report?.defenseBattleData ||
      includesAny(title, ['batalha', 'ataque', 'defesa', 'castelo saqueado', 'exército regressou'])
    ) {
      return 'attack';
    }

    return 'kingdom';
  }

  function safeDate(report) {
    const date = new Date(Number(report?.at) || report?.at || Date.now());
    if (Number.isNaN(date.getTime())) return '';
    return date.toLocaleString('pt-PT');
  }

  function fallbackResult(report) {
    if (report?.result === 'win') return 'Vitória';
    if (report?.result === 'loss') return 'Derrota';
    if (report?.result === 'spy') return 'Espionagem';
    return 'Informação';
  }

  function fallbackClass(report) {
    if (report?.result === 'win') return 'report-win';
    if (report?.result === 'loss') return 'report-loss';
    if (report?.result === 'spy') return 'report-spy';
    return '';
  }

  function clampPage(page, totalPages) {
    const value = Number.parseInt(page, 10);
    if (!Number.isFinite(value)) return 1;
    return Math.min(Math.max(value, 1), Math.max(totalPages, 1));
  }

  function currentPage(folderId, totalReports) {
    const totalPages = Math.max(1, Math.ceil(totalReports / REPORTS_PER_PAGE));
    activePageByFolder[folderId] = clampPage(activePageByFolder[folderId], totalPages);
    return activePageByFolder[folderId];
  }

  function renderDetails(report, context, presentation) {
    if (presentation?.detailsHtml) return presentation.detailsHtml;
    const escapeHtml = context.escapeHtml || (value => String(value ?? ''));
    if (context.resourceIcons?.richText) return context.resourceIcons.richText(report?.text || '', escapeHtml);
    return escapeHtml(report?.text || '');
  }

  function renderRows(reports, context) {
    const escapeHtml = context.escapeHtml || (value => String(value ?? ''));
    if (!reports.length) return '<tr><td colspan="4" class="report-folder-empty-row">Sem relatórios nesta pasta.</td></tr>';

    return reports.map(report => {
      const presentation = context.reportPresentation?.(report) || null;
      const resultLabel = presentation?.label || fallbackResult(report);
      const resultClass = presentation?.className || fallbackClass(report);
      return `<tr>
        <td>${safeDate(report)}</td>
        <td>${escapeHtml(report?.title || 'Relatório')}</td>
        <td class="${resultClass}">${escapeHtml(resultLabel)}</td>
        <td><div class="report-folder-details-cell">${renderDetails(report, context, presentation)}</div></td>
      </tr>`;
    }).join('');
  }

  function renderPagination(folderId, totalReports, context) {
    const totalPages = Math.max(1, Math.ceil(totalReports / REPORTS_PER_PAGE));
    if (totalPages <= 1) {
      return `<div class="report-pagination single"><span>Página 1 de 1</span></div>`;
    }

    const escapeHtml = context.escapeHtml || (value => String(value ?? ''));
    const page = currentPage(folderId, totalReports);
    const pageButtons = Array.from({ length: totalPages }, (_, index) => {
      const number = index + 1;
      return `<button type="button" class="report-page-btn ${number === page ? 'active' : ''}" data-action="report-page-go" data-folder="${escapeHtml(folderId)}" data-page="${number}" ${number === page ? 'disabled' : ''}>${number}</button>`;
    }).join('');

    return `<div class="report-pagination">
      <button type="button" class="report-page-step" data-action="report-page-go" data-folder="${escapeHtml(folderId)}" data-page="${page - 1}" ${page <= 1 ? 'disabled' : ''}>‹ Anterior</button>
      <div class="report-page-numbers" aria-label="Páginas dos relatórios">${pageButtons}</div>
      <span>Página ${page} de ${totalPages}</span>
      <button type="button" class="report-page-step" data-action="report-page-go" data-folder="${escapeHtml(folderId)}" data-page="${page + 1}" ${page >= totalPages ? 'disabled' : ''}>Seguinte ›</button>
    </div>`;
  }

  function renderTable(folderId, reports, context) {
    const folder = FOLDERS[folderId] || FOLDERS.kingdom;
    const count = reports.length;
    const page = currentPage(folder.id, count);
    const start = (page - 1) * REPORTS_PER_PAGE;
    const pageReports = reports.slice(start, start + REPORTS_PER_PAGE);
    const first = count ? start + 1 : 0;
    const last = count ? Math.min(start + REPORTS_PER_PAGE, count) : 0;

    return `<section class="report-folder-section" data-report-section="${folder.id}">
      <div class="report-folder-section-head">
        <div>
          <h3>${folder.icon} ${folder.title}</h3>
          <small>${count === 1 ? '1 relatório' : `${context.format?.(count) || count} relatórios`} ${count ? `• a mostrar ${first}-${last}` : ''}</small>
        </div>
      </div>
      <div class="report-folder-table-wrap">
        <table class="table report-folder-table">
          <thead><tr><th>Data</th><th>Assunto</th><th>Resultado</th><th>Detalhes</th></tr></thead>
          <tbody>${renderRows(pageReports, context)}</tbody>
        </table>
      </div>
      ${renderPagination(folder.id, count, context)}
    </section>`;
  }

  function renderFolderCard(folderId, count, context) {
    const folder = FOLDERS[folderId];
    const active = activeFolder === folderId;
    return `<button type="button" class="report-folder-card ${active ? 'active' : ''}" data-action="report-folder-select" data-folder="${folder.id}">
      <span class="report-folder-icon">${folder.icon}</span>
      <span class="report-folder-main">
        <b>${folder.title}</b>
        <small>${folder.subtitle}</small>
      </span>
      <strong>${context.format?.(count) || count}</strong>
    </button>`;
  }

  function renderFolderSummary(grouped, context) {
    return `<section class="report-folder-summary">
      <div class="report-folder-summary-head">
        <h3>Escolhe uma pasta de relatórios</h3>
        <small>Assim os relatórios não ficam misturados e não é preciso fazer scroll para ver listas grandes.</small>
      </div>
      <div class="report-folder-summary-grid">
        ${FOLDER_ORDER.map(folderId => {
          const folder = FOLDERS[folderId];
          const count = grouped[folderId].length;
          const pages = Math.max(1, Math.ceil(count / REPORTS_PER_PAGE));
          return `<button type="button" class="report-folder-summary-card" data-action="report-folder-select" data-folder="${folder.id}">
            <span>${folder.icon}</span>
            <b>${folder.title}</b>
            <small>${count === 1 ? '1 relatório' : `${context.format?.(count) || count} relatórios`} • ${pages === 1 ? '1 página' : `${pages} páginas`}</small>
          </button>`;
        }).join('')}
      </div>
    </section>`;
  }

  function render(context) {
    const profile = context.getProfile?.() || {};
    const reports = [...(Array.isArray(profile.reports) ? profile.reports : [])].reverse();
    const grouped = { attack: [], espionage: [], kingdom: [] };
    reports.forEach(report => grouped[classify(report)].push(report));

    const total = reports.length;
    const folderCards = ['all', ...FOLDER_ORDER].map(folderId => {
      const count = folderId === 'all' ? total : grouped[folderId].length;
      return renderFolderCard(folderId, count, context);
    }).join('');

    const header = context.viewHeader?.(
      'Relatórios',
      'Caixa organizada por pastas e páginas para separar espionagens, ataques e acontecimentos do reino.'
    ) || '';

    const activeIsValid = activeFolder === 'all' || FOLDER_ORDER.includes(activeFolder);
    if (!activeIsValid) activeFolder = 'all';

    const body = activeFolder === 'all'
      ? renderFolderSummary(grouped, context)
      : renderTable(activeFolder, grouped[activeFolder], context);

    return `<div class="view reports-view">
      ${header}
      <div class="report-folder-grid">${folderCards}</div>
      ${total ? body : '<div class="report-folder-empty">Ainda não existem relatórios.</div>'}
    </div>`;
  }

  async function handleAction(action, element, context) {
    if (action === 'report-folder-select') {
      const folder = String(element?.dataset?.folder || 'all');
      activeFolder = FOLDERS[folder] ? folder : 'all';
      if (activeFolder !== 'all') activePageByFolder[activeFolder] = 1;
      context.renderActiveView?.();
      return true;
    }

    if (action === 'report-page-go') {
      const folder = String(element?.dataset?.folder || activeFolder);
      if (!FOLDER_ORDER.includes(folder)) return false;
      activeFolder = folder;
      activePageByFolder[folder] = Math.max(1, Number.parseInt(element?.dataset?.page || '1', 10) || 1);
      context.renderActiveView?.();
      return true;
    }

    return false;
  }

  globalThis.ReinosReportFolders = Object.freeze({
    render,
    handleAction,
    classify
  });
})();
