import { auth } from '../services/auth.js';
import { InvoiceModal } from '../components/InvoiceModal.js';
import { apiGet } from '../services/apiClient.js';
import { icons } from '../services/icons.js';
import {
  Chart,
  BarController,
  BarElement,
  CategoryScale,
  LinearScale,
  Tooltip,
  Legend
} from 'chart.js';

Chart.register(BarController, BarElement, CategoryScale, LinearScale, Tooltip, Legend);

function getGreeting() {
  const hour = new Date().getHours();
  if (hour < 12) return 'Buenos días';
  if (hour < 20) return 'Buenas tardes';
  return 'Buenas noches';
}

async function fetchAllInvoices() {
  const data = await apiGet('/api/Invoices?limit=500&page=1');
  return Array.isArray(data) ? data : data.data || data.invoices || [];
}

async function fetchAllSupplierInvoices() {
  const data = await apiGet('/api/SupplierInvoices?limit=500&page=1');
  return Array.isArray(data) ? data : data.data || data.invoices || [];
}

function calcKPIs(invoices) {
  const total = invoices.length;
  const totalBilled = invoices.reduce((sum, inv) => sum + (inv.total || 0), 0);
  const paid = invoices.filter(inv => inv.status === 'paid').length;
  const unpaid = invoices.filter(inv => inv.status === 'unpaid').length;
  const draft = invoices.filter(inv => inv.status === 'draft').length;
  const paidRate = total > 0 ? ((paid / total) * 100).toFixed(1) : '0.0';
  const pendingAmount = invoices.reduce((s, inv) => s + (inv.remainToPay || 0), 0);
  return { total, totalBilled, paid, unpaid, draft, paidRate, pendingAmount };
}

function calcQuarterlyBoth(ventas, compras) {
  const year = new Date().getFullYear();
  const qv = [0, 0, 0, 0];
  const qc = [0, 0, 0, 0];

  const addTo = (arr, invoices) => {
    invoices.forEach(inv => {
      if (!inv.date || !inv.total) return;
      const d = new Date(inv.date);
      if (d.getFullYear() !== year) return;
      const m = d.getMonth();
      const idx = m <= 2 ? 0 : m <= 5 ? 1 : m <= 8 ? 2 : 3;
      arr[idx] += inv.total;
    });
  };

  addTo(qv, ventas);
  addTo(qc, compras);
  return { ventas: qv, compras: qc };
}

function formatCurrency(amount) {
  return new Intl.NumberFormat('es-ES', {
    style: 'currency', currency: 'EUR', maximumFractionDigits: 0
  }).format(amount || 0);
}

function formatDate(dateStr) {
  if (!dateStr) return '—';
  return new Date(dateStr).toLocaleDateString('es-ES', {
    day: '2-digit', month: '2-digit', year: 'numeric'
  });
}

function getStatusBadge(status) {
  const map = {
    draft: { label: 'Borrador', cls: 'badge-draft' },
    unpaid: { label: 'Pte. Pago', cls: 'badge-unpaid' },
    paid: { label: 'Pagada', cls: 'badge-paid' },
  };
  const s = map[status] || { label: status || '—', cls: 'badge-draft' };
  return `<span class="badge ${s.cls}">${s.label}</span>`;
}

function statusDotClass(status) {
  const map = {
    paid: 'status-paid',
    unpaid: 'status-unpaid',
    draft: 'status-draft',
  };
  return map[status] || 'status-draft';
}

function escapeHtml(str) {
  if (str == null) return '';
  const div = document.createElement('div');
  div.textContent = String(str);
  return div.innerHTML;
}

function buildQuarterlySummary(invoices) {
  const quarters = {};
  invoices.forEach(inv => {
    if (!inv.date) return;
    const d = new Date(inv.date);
    const year = d.getFullYear();
    const q = Math.floor(d.getMonth() / 3) + 1;
    const key = `${year}-Q${q}`;
    if (!quarters[key]) quarters[key] = { year, q, ht: 0, tax: 0, total: 0, paid: 0, pending: 0, count: 0 };
    const ttc = parseFloat(inv.total) || 0;
    quarters[key].ht      += parseFloat(inv.totalHt)  || 0;
    quarters[key].tax     += parseFloat(inv.totalTax) || 0;
    quarters[key].total   += ttc;
    if (inv.status === 'paid') quarters[key].paid    += ttc;
    else if (inv.status === 'unpaid') quarters[key].pending += ttc;
    quarters[key].count   += 1;
  });
  return Object.values(quarters).sort((a, b) =>
    b.year !== a.year ? b.year - a.year : b.q - a.q
  );
}

function renderQuarterlyTable(wrap, invoices) {
  const rows = buildQuarterlySummary(invoices);
  if (rows.length === 0) { wrap.innerHTML = '<p class="db-table-loading">Sin datos</p>'; return; }

  const fmt = n => new Intl.NumberFormat('es-ES', { style: 'currency', currency: 'EUR', maximumFractionDigits: 0 }).format(n);
  const qLabel = q => [`1er`, `2º`, `3er`, `4º`][q - 1] + ` trimestre`;

  const byYear = {};
  rows.forEach(r => { if (!byYear[r.year]) byYear[r.year] = []; byYear[r.year].push(r); });

  let html = '';
  Object.keys(byYear).sort((a, b) => b - a).forEach(year => {
    const yr = byYear[year];
    const tot = yr.reduce((a, r) => ({
      ht: a.ht + r.ht, tax: a.tax + r.tax, total: a.total + r.total,
      paid: a.paid + r.paid, pending: a.pending + r.pending, count: a.count + r.count
    }), { ht: 0, tax: 0, total: 0, paid: 0, pending: 0, count: 0 });

    html += `
      <div class="quarterly-year-block">
        <div class="quarterly-year-header">
          <span class="quarterly-year-label">${year}</span>
          <span class="quarterly-year-total">${fmt(tot.total)} · ${tot.count} facturas</span>
        </div>
        <table class="quarterly-table">
          <thead><tr>
            <th>Trimestre</th><th>Facturas</th><th>Base imponible</th>
            <th>IVA</th><th>Total emitido</th><th>Cobrado</th><th>Pte. cobro</th>
          </tr></thead>
          <tbody>
            ${yr.map(r => `<tr>
                <td class="quarterly-q-label">T${r.q} · <span>${qLabel(r.q)}</span></td>
                <td class="quarterly-count">${r.count}</td>
                <td class="quarterly-num">${fmt(r.ht)}</td>
                <td class="quarterly-num quarterly-tax">${fmt(r.tax)}</td>
                <td class="quarterly-num ${r.total > 0 ? 'quarterly-paid' : r.total < 0 ? 'quarterly-pending' : ''}">${fmt(r.total)}</td>
                <td class="quarterly-num ${r.paid > 0 ? 'quarterly-paid' : r.paid < 0 ? 'quarterly-pending' : 'quarterly-zero'}"${r.paid < 0 ? ' title="Incluye facturas rectificativas (abonos)"' : ''}>${fmt(r.paid)}</td>
                <td class="quarterly-num ${r.pending > 0.01 ? 'quarterly-pending' : 'quarterly-zero'}">${fmt(r.pending)}</td>
              </tr>`).join('')}
          </tbody>
          <tfoot>
            <tr class="quarterly-footer-row">
              <td>Total ${year}</td><td>${tot.count}</td>
              <td>${fmt(tot.ht)}</td><td>${fmt(tot.tax)}</td>
              <td class="${tot.total > 0 ? 'quarterly-paid' : tot.total < 0 ? 'quarterly-pending' : ''}">${fmt(tot.total)}</td>
              <td class="${tot.paid > 0 ? 'quarterly-paid' : tot.paid < 0 ? 'quarterly-pending' : 'quarterly-zero'}"${tot.paid < 0 ? ' title="Incluye facturas rectificativas (abonos)"' : ''}>${fmt(tot.paid)}</td>
              <td class="${tot.pending > 0.01 ? 'quarterly-pending' : 'quarterly-zero'}">${fmt(tot.pending)}</td>
            </tr>
          </tfoot>
        </table>
      </div>`;
  });
  wrap.innerHTML = html;
}

function openInvoiceModal(invoiceId) {
  const modal = InvoiceModal(invoiceId, null, () => { });
  document.body.appendChild(modal);
}

export function renderDashboard() {
  const user = auth.getUser();
  const userName = user?.identifier || user?.email || user?.username || 'Usuario';
  const year = new Date().getFullYear();

  const container = document.createElement('div');
  container.className = 'dashboard';

  container.innerHTML = /*html*/`
    <div class="db-header">
      <div>
        <h1 class="db-greeting">${getGreeting()}, ${escapeHtml(userName)}</h1>
        <p class="db-subtitle">Resumen de facturación · ${year}</p>
      </div>
      <button id="logout-button" class="logout-button">
        ${icons.logout}
        <span>Cerrar sesión</span>
      </button>
    </div>

    <div class="db-kpi-row">
      <div class="db-kpi-card">
        <div class="db-kpi-top">
          <span class="db-kpi-label">Facturas emitidas</span>
          <div class="db-kpi-icon db-kpi-icon--blue">${icons.fileText}</div>
        </div>
        <div class="db-kpi-value" id="kpi-total"><span class="db-kpi-skeleton"></span></div>
        <div class="db-kpi-sub" id="kpi-total-sub"><span class="db-kpi-skeleton db-kpi-skeleton-sm"></span></div>
      </div>

      <div class="db-kpi-card">
        <div class="db-kpi-top">
          <span class="db-kpi-label">Total ventas</span>
          <div class="db-kpi-icon db-kpi-icon--green">${icons.dollarSign}</div>
        </div>
        <div class="db-kpi-value" id="kpi-ventas"><span class="db-kpi-skeleton"></span></div>
        <div class="db-kpi-sub" id="kpi-ventas-sub"><span class="db-kpi-skeleton db-kpi-skeleton-sm"></span></div>
      </div>

      <div class="db-kpi-card">
        <div class="db-kpi-top">
          <span class="db-kpi-label">Total compras</span>
          <div class="db-kpi-icon db-kpi-icon--red">${icons.dollarSign}</div>
        </div>
        <div class="db-kpi-value" id="kpi-compras"><span class="db-kpi-skeleton"></span></div>
        <div class="db-kpi-sub" id="kpi-compras-sub"><span class="db-kpi-skeleton db-kpi-skeleton-sm"></span></div>
      </div>

      <div class="db-kpi-card">
        <div class="db-kpi-top">
          <span class="db-kpi-label">Balance neto</span>
          <div class="db-kpi-icon db-kpi-icon--emerald">${icons.checkCircle}</div>
        </div>
        <div class="db-kpi-value" id="kpi-balance"><span class="db-kpi-skeleton"></span></div>
        <div class="db-kpi-sub" id="kpi-balance-sub"><span class="db-kpi-skeleton db-kpi-skeleton-sm"></span></div>
      </div>

      <div class="db-kpi-card">
        <div class="db-kpi-top">
          <span class="db-kpi-label">Tasa de cobro</span>
          <div class="db-kpi-icon db-kpi-icon--purple">${icons.checkCircle}</div>
        </div>
        <div class="db-kpi-value" id="kpi-rate"><span class="db-kpi-skeleton"></span></div>
        <div class="db-kpi-sub" id="kpi-rate-sub"><span class="db-kpi-skeleton db-kpi-skeleton-sm"></span></div>
      </div>

      <div class="db-kpi-card">
        <div class="db-kpi-top">
          <span class="db-kpi-label">Pendiente de cobro</span>
          <div class="db-kpi-icon db-kpi-icon--amber">${icons.clock}</div>
        </div>
        <div class="db-kpi-value" id="kpi-pending"><span class="db-kpi-skeleton"></span></div>
        <div class="db-kpi-sub" id="kpi-pending-sub"><span class="db-kpi-skeleton db-kpi-skeleton-sm"></span></div>
      </div>
    </div>

    <div class="db-mid-row">
      <div class="db-chart-card">
        <div class="db-card-header">
          <span class="db-card-title">Balance trimestral</span>
          <span class="db-card-year">${year}</span>
        </div>
        <div class="db-chart-body">
          <canvas id="db-quarterly-chart"></canvas>
        </div>
      </div>

      <div class="db-recent-card">
        <div class="db-card-header">
          <span class="db-card-title">Últimos movimientos</span>
          <a href="#invoices" class="db-see-all">Ver todas</a>
        </div>
        <div class="db-recent-list" id="db-recent-list">
          ${[...Array(6)].map(() => `
            <div class="db-recent-item db-recent-skeleton">
              <div class="db-skel-icon"></div>
              <div class="db-skel-lines"><span></span><span></span></div>
              <div class="db-skel-right"><span></span><span></span></div>
            </div>`).join('')}
        </div>
      </div>
    </div>

    <div class="db-table-card">
      <div class="db-card-header">
        <span class="db-card-title">Facturación trimestral</span>
      </div>
      <div class="db-table-wrap" id="db-quarterly-table-wrap">
        <p class="db-table-loading">Cargando...</p>
      </div>
    </div>

    <div class="db-table-card">
      <div class="db-card-header">
        <span class="db-card-title">Últimas facturas emitidas</span>
        <a href="#invoices" class="db-see-all">Ver todas</a>
      </div>
      <div class="db-table-wrap">
        <table class="db-monitoring-table">
          <thead>
            <tr>
              <th>Número</th>
              <th>Cliente</th>
              <th>Estado</th>
              <th>Fecha</th>
              <th>Vencimiento</th>
              <th class="db-th-right">Total</th>
            </tr>
          </thead>
          <tbody id="db-table-body">
            <tr><td colspan="6" class="db-table-loading">Cargando...</td></tr>
          </tbody>
        </table>
      </div>
    </div>
  `;

  container.querySelector('#logout-button').addEventListener('click', () => {
    auth.logout();
    window.location.hash = '#login';
  });

  (async () => {
    let invoices = [];
    let supplierInvoices = [];

    try {
      [invoices, supplierInvoices] = await Promise.all([
        fetchAllInvoices(),
        fetchAllSupplierInvoices(),
      ]);
    } catch (err) {
      console.error('Dashboard: error al cargar facturas', err);
      ['#db-recent-list', '#db-table-body'].forEach(sel => {
        container.querySelector(sel).innerHTML = '<p class="db-error">Error al cargar datos.</p>';
      });
      return;
    }

    const { total, totalBilled, paid, unpaid, draft, paidRate, pendingAmount } = calcKPIs(invoices);
    const totalCompras = supplierInvoices.reduce((s, inv) => s + (inv.total || 0), 0);
    const balance = totalBilled - totalCompras;

    container.querySelector('#kpi-total').textContent = total.toLocaleString('es-ES');
    container.querySelector('#kpi-total-sub').innerHTML =
      `<span class="db-sub-green">${paid} pagadas</span>&nbsp;&middot;&nbsp;` +
      `<span class="db-sub-amber">${unpaid} pendientes</span>&nbsp;&middot;&nbsp;` +
      `<span class="db-sub-muted">${draft} borrador</span>`;

    container.querySelector('#kpi-ventas').textContent = formatCurrency(totalBilled);
    container.querySelector('#kpi-ventas-sub').textContent = `Acumulado ${year}`;

    container.querySelector('#kpi-compras').textContent = formatCurrency(totalCompras);
    container.querySelector('#kpi-compras-sub').textContent = `${supplierInvoices.length} facturas de proveedor`;

    container.querySelector('#kpi-balance').textContent = formatCurrency(balance);
    container.querySelector('#kpi-balance-sub').innerHTML =
      balance >= 0
        ? `<span class="db-sub-green">Resultado positivo</span>`
        : `<span class="db-sub-red">Resultado negativo</span>`;

    container.querySelector('#kpi-rate').textContent = `${paidRate}%`;
    container.querySelector('#kpi-rate-sub').textContent = `${paid} de ${total} cobradas`;

    container.querySelector('#kpi-pending').textContent = formatCurrency(pendingAmount);
    container.querySelector('#kpi-pending-sub').innerHTML =
      pendingAmount > 0
        ? `<span class="db-sub-red">${unpaid} factura${unpaid !== 1 ? 's' : ''} sin cobrar</span>`
        : '<span class="db-sub-green">Sin importes pendientes</span>';

    const canvas = container.querySelector('#db-quarterly-chart');
    const { ventas: qv, compras: qc } = calcQuarterlyBoth(invoices, supplierInvoices);

    const isDark = document.documentElement.getAttribute('data-theme') === 'dark';
    const chartGridColor = isDark ? 'rgba(148, 163, 184, 0.08)' : '#f3f4f6';
    const chartTickColor = isDark ? '#94a3b8' : '#9ca3af';

    new Chart(canvas, {
      type: 'bar',
      data: {
        labels: ['Q1  Ene–Mar', 'Q2  Abr–Jun', 'Q3  Jul–Sep', 'Q4  Oct–Dic'],
        datasets: [
          {
            label: 'Ventas',
            data: qv,
            backgroundColor: 'rgba(37, 99, 235, 0.85)',
            hoverBackgroundColor: 'rgba(29, 78, 216, 1)',
            borderRadius: 4,
            borderSkipped: false,
            barPercentage: 0.7,
            categoryPercentage: 0.8,
          },
          {
            label: 'Compras',
            data: qc,
            backgroundColor: 'rgba(220, 38, 38, 0.75)',
            hoverBackgroundColor: 'rgba(185, 28, 28, 1)',
            borderRadius: 4,
            borderSkipped: false,
            barPercentage: 0.7,
            categoryPercentage: 0.8,
          }
        ]
      },
      options: {
        responsive: true,
        maintainAspectRatio: false,
        plugins: {
          legend: {
            display: true,
            position: 'top',
            labels: {
              color: chartTickColor,
              font: { size: 12, family: 'Inter, system-ui, sans-serif' },
              boxWidth: 12,
              padding: 16,
            }
          },
          tooltip: {
            callbacks: { label: ctx => ` ${ctx.dataset.label}: ${formatCurrency(ctx.parsed.y)}` },
            backgroundColor: isDark ? '#1e293b' : '#111827',
            titleColor: '#f9fafb',
            bodyColor: isDark ? '#cbd5e1' : '#d1d5db',
            padding: 10,
            cornerRadius: 6,
            displayColors: true,
          }
        },
        scales: {
          x: {
            grid: { display: false },
            border: { display: false },
            ticks: {
              color: chartTickColor,
              font: { size: 12, family: 'Inter, system-ui, sans-serif' }
            }
          },
          y: {
            grid: { color: chartGridColor },
            border: { display: false },
            ticks: {
              color: chartTickColor,
              font: { size: 11, family: 'Inter, system-ui, sans-serif' },
              callback: v => v >= 1000 ? `${(v / 1000).toFixed(0)}k €` : `${v} €`,
              maxTicksLimit: 5,
            }
          }
        },
        animation: { duration: 600, easing: 'easeOutQuart' }
      }
    });

    // Combined recent list: ventas + compras, last 8 by date
    const activityDate = inv => new Date(inv.dateModification || inv.dateCreation || inv.date || 0);

    const ventasTagged = invoices.map(inv => ({ ...inv, _type: 'venta', _party: inv.clientName }));
    const comprasTagged = supplierInvoices.map(inv => ({
      ...inv,
      _type: 'compra',
      _party: inv.supplierName,
      number: inv.number || inv.supplierRef,
    }));

    const recent = [...ventasTagged, ...comprasTagged]
      .sort((a, b) => activityDate(b) - activityDate(a))
      .slice(0, 10);

    const recentList = container.querySelector('#db-recent-list');
    if (recent.length === 0) {
      recentList.innerHTML = `<div class="db-no-data">No hay facturas recientes.</div>`;
    } else {
      recentList.innerHTML = recent.map(inv => {
        const isVenta = inv._type === 'venta';
        const typeBadge = isVenta
          ? `<span class="db-type-badge db-type-venta" title="Venta">V</span>`
          : `<span class="db-type-badge db-type-compra" title="Compra">C</span>`;
        return `
          <div class="db-recent-item${isVenta ? '' : ' db-recent-compra'}" data-id="${inv.id}" data-type="${inv._type}" role="button" tabindex="0">
            <div class="db-recent-dot ${statusDotClass(inv.status)}">
              ${icons.fileText}
            </div>
            <div class="db-recent-info">
              <span class="db-recent-num">${typeBadge} ${escapeHtml(inv.number || `#${inv.id}`)}</span>
              <span class="db-recent-client">${escapeHtml(inv._party || '—')}</span>
            </div>
            <div class="db-recent-right">
              <span class="db-recent-amount${(inv.total || 0) < 0 || inv.status === 'unpaid' ? ' db-recent-amount--pending' : inv.status === 'paid' ? ' db-recent-amount--paid' : ''}">${formatCurrency(inv.total)}</span>
              <span class="db-recent-date">${formatDate(inv.dateModification || inv.dateCreation || inv.date)}</span>
            </div>
            <div class="db-recent-arrow">
              ${icons.chevron}
            </div>
          </div>
        `;
      }).join('');

      recentList.querySelectorAll('.db-recent-item[data-id]').forEach(el => {
        const id = parseInt(el.dataset.id);
        const type = el.dataset.type;
        el.addEventListener('click', () => {
          if (type === 'venta') openInvoiceModal(id);
          else { window.__openSupplierInvoice = id; window.location.hash = '#facturas-proveedores'; }
        });
        el.addEventListener('keydown', e => {
          if (e.key === 'Enter' || e.key === ' ') {
            if (type === 'venta') openInvoiceModal(id);
            else { window.__openSupplierInvoice = id; window.location.hash = '#facturas-proveedores'; }
          }
        });
      });
    }

    renderQuarterlyTable(container.querySelector('#db-quarterly-table-wrap'), invoices);

    const tableRows = [...invoices]
      .sort((a, b) => new Date(b.date) - new Date(a.date))
      .slice(0, 25);

    const tbody = container.querySelector('#db-table-body');
    if (tableRows.length === 0) {
      tbody.innerHTML = '<tr><td colspan="6" class="db-table-loading">No hay facturas</td></tr>';
    } else {
      const today = new Date(); today.setHours(0, 0, 0, 0);
      const in7 = new Date(today); in7.setDate(in7.getDate() + 7);

      tbody.innerHTML = tableRows.map(inv => {
        const expDate = inv.expireDate ? new Date(inv.expireDate) : null;
        const needsPayment = inv.status !== 'paid';
        let dateClass = '';
        if (expDate && needsPayment) {
          if (expDate < today) dateClass = 'db-date--overdue';
          else if (expDate <= in7) dateClass = 'db-date--soon';
        }

        return `
        <tr class="db-table-row db-row--${inv.status || 'draft'}" data-id="${inv.id}" role="button" tabindex="0">
          <td class="db-cell-num db-num--${inv.status || 'draft'}">${escapeHtml(inv.number || `#${inv.id}`)}</td>
          <td class="db-cell-client">${escapeHtml(inv.clientName || '—')}</td>
          <td>${getStatusBadge(inv.status)}</td>
          <td>${formatDate(inv.date)}</td>
          <td class="${dateClass}">${formatDate(inv.expireDate)}</td>
          <td class="db-cell-right db-cell-num ${inv.status === 'unpaid' || (inv.total || 0) < 0 ? 'db-total--neg' : inv.status === 'paid' ? 'db-total--pos' : ''}">${formatCurrency(inv.total)}</td>
        </tr>`;
      }).join('');

      tbody.querySelectorAll('.db-table-row[data-id]').forEach(row => {
        const id = parseInt(row.dataset.id);
        row.addEventListener('click', () => openInvoiceModal(id));
        row.addEventListener('keydown', e => { if (e.key === 'Enter' || e.key === ' ') openInvoiceModal(id); });
      });
    }
  })();

  return container;
}
