// ─── Dashboard · Finanzas (Cobros/Pagos) ─────────────────────────────────
// FinanzasLadoSection: UN componente parametrizado por `lado` ('cobros' |
// 'pagos') que reemplaza a CobrosSection + PagosSection (screens-
// dashboard.jsx original) — eran prácticamente el mismo componente con
// cobro↔pago y entidad↔proveedor intercambiados (mismas 4 KPIs, misma forma
// de columnas). Extraído en su propio archivo (P10, split de
// screens-dashboard.jsx) — el más "denso" de las 12 secciones tras
// colapsarlas de a 2, separado de operaciones.jsx para no acercarse al techo
// de líneas.
//
// FIX (mapa-comprension.md §inv-dash, duplicación #3, mitad B — "CobrosSection
// y PagosSection son casi el mismo componente"): mismo criterio que ya se
// aplicó a screens/finanzas/lista.jsx/LogisticaScreen con la prop `tabs` de
// EntityListScreen — acá el "lado" lo fija el CALLER (panel.jsx invoca
// `<FinanzasLadoSection lado="cobros" />` y `<FinanzasLadoSection
// lado="pagos" />`), no un tab interno (el dashboard muestra las DOS
// secciones, una debajo de la otra, como el original).
//
// FIX (mapa-comprension.md §inv-dash, bug severidad alta — "trend inventado"):
// mueren `delta`/`highlighted`/`trend` — ver header de operaciones.jsx para
// el razonamiento completo (mismo fix, mismas 2 secciones son las más
// flagrantes: "Pagado" tenía `trend:[9,10,11,12,12,13,14]` sin relación
// alguna con ningún dato real, ni el último punto).
//
// Expone a window: FinanzasLadoSection. Consume window.COBROS/PAGOS (core/
// colecciones.js), useEntityStats (ui/entity-list.jsx), DashSection/
// DashTable/srvOr/MonoId/TextBold/NumBold (compartido.jsx), IdDateCell/
// KpiCard/TablePill (ui/primitives.jsx), COBRO_ESTADOS/PAGO_ESTADOS (dominio/
// pipeline.js), formatMoney/formatMoneyShort (dominio/formato.js).

// Config por lado: qué colección/estados/columnas/íconos difieren entre
// Cobros y Pagos. La forma estructural (4 KPIs + tabla top-7) es idéntica.
const FINANZAS_LADO_CFG = {
  cobros: {
    eyebrow: 'Operaciones · Finanzas', title: 'Cobros', route: 'finanzas', animDelay: 180,
    rows: () => COBROS, estados: () => COBRO_ESTADOS, estadoOk: 'COBRADO',
    statKey: 'cobros',
    kpiTotalLabel: 'Total cobros', kpiOkLabel: 'Cobrados', kpiPendLabel: 'Por cobrar', kpiMontoOkLabel: 'Cobrado',
    iconTotal: IconDollar, iconOk: IconCheckCircle, iconPend: IconWallet, iconMontoOk: IconTrendingUp,
    caption: 'Últimos 7 cobros',
    partyLabel: 'Entidad', partyField: 'entidad',
    thirdCol: { key: 'expediente', label: 'Expediente', width: '180px', render: (r) => <MonoId>{r.expedienteId}</MonoId> },
    dateField: 'fecha',
  },
  pagos: {
    eyebrow: 'Operaciones · Finanzas', title: 'Pagos', route: 'finanzas', animDelay: 240,
    rows: () => PAGOS, estados: () => PAGO_ESTADOS, estadoOk: 'PAGADO',
    statKey: 'pagos',
    kpiTotalLabel: 'Total pagos', kpiOkLabel: 'Pagados', kpiPendLabel: 'Por pagar', kpiMontoOkLabel: 'Pagado',
    iconTotal: IconShoppingCart, iconOk: IconCheck, iconPend: IconClock, iconMontoOk: IconTrendingUp,
    caption: 'Últimos 7 pagos',
    partyLabel: 'Proveedor', partyField: 'proveedor',
    thirdCol: {
      key: 'compra', label: 'Compra', width: '180px',
      render: (r) => r.compraNumero
        ? <MonoId>{r.compraNumero}</MonoId>
        : <span style={{ color: 'color-mix(in oklab, var(--muted-foreground) 50%, transparent)', fontStyle: 'italic', fontSize: 12 }}>—</span>,
    },
    dateField: 'fecha',
  },
};

function FinanzasLadoSection({ lado, onNav }) {
  const cfg = FINANZAS_LADO_CFG[lado];
  const rows = cfg.rows();
  const estados = cfg.estados();
  const total = rows.reduce((s, r) => s + r.total, 0);
  const ok = rows.filter(r => r.estado === cfg.estadoOk);
  const pend = rows.filter(r => r.estado !== cfg.estadoOk);
  const totalOk = ok.reduce((s, r) => s + r.total, 0);
  const totalPend = pend.reduce((s, r) => s + r.total, 0);
  // A7 (BUGS-caza-01-07-2026.md #7): v_cobros_stats/v_pagos_stats agregan en Postgres
  // sobre el universo real (total/monto/conteo por estado); fallback si /stats falla o
  // no llegó. Los montos POR ESTADO (Cobrado $/Por cobrar $, Pagado $/Por pagar $) no
  // están en la vista (solo conteo por estado) — quedan client-side sobre lo
  // hidratado, mismo criterio ya documentado para Finanzas P3.
  const srvStats = window.useEntityStats ? window.useEntityStats(cfg.statKey) : null;
  const byEstadoSrv = srvOr(srvStats, 'byEstado', null);
  const kTotalCount = srvOr(srvStats, 'total', rows.length);
  const kTotalMonto = srvOr(srvStats, 'sumTotal', total);
  const kOkCount = byEstadoSrv ? (byEstadoSrv[cfg.estadoOk] || 0) : ok.length;
  const kPendCount = srvStats ? Math.max(0, kTotalCount - kOkCount) : pend.length;

  return (
    <DashSection
      eyebrow={cfg.eyebrow}
      title={cfg.title}
      route={cfg.route}
      onNav={onNav}
      kpis={[
        { label: cfg.kpiTotalLabel,  value: String(kTotalCount), icon: cfg.iconTotal },
        { label: cfg.kpiOkLabel,     value: String(kOkCount),    icon: cfg.iconOk },
        { label: cfg.kpiPendLabel,   value: String(kPendCount),  icon: cfg.iconPend },
        { label: cfg.kpiMontoOkLabel, value: formatMoneyShort(totalOk), icon: cfg.iconMontoOk },
      ]}
      animDelay={cfg.animDelay}
    >
      <DashTable
        caption={cfg.caption}
        onRowClick={() => onNav('finanzas')}
        rows={rows}
        columns={[
          { key: 'id', label: 'ID · Fecha', width: '180px',
            render: (r) => <IdDateCell id={r.publicId} date={r[cfg.dateField]} /> },
          { key: 'party', label: cfg.partyLabel, width: '1.4fr',
            render: (r) => <TextBold>{r[cfg.partyField]}</TextBold> },
          cfg.thirdCol,
          { key: 'total', label: 'Total', width: '150px', align: 'right',
            render: (r) => <NumBold>{formatMoney(r.total)}</NumBold> },
          { key: 'estado', label: 'Estado', width: '120px', align: 'right',
            render: (r) => { const e = estados[r.estado] || { label: r.estado || '—', tone: 'neutral' }; return <TablePill label={e.label} tone={e.tone} />; } },
        ]}
      />
    </DashSection>
  );
}

Object.assign(window, { FinanzasLadoSection });
