// ─── Dashboard · Herramientas (Caja Chica/Notificaciones de margen/Ajustes
// de inventario) ────────────────────────────────────────────────────────
// 3 de las 12 secciones del Panel general (las 2 últimas no están en el
// sidebar — son los 2 íconos del header, campana y paquete). Extraídas de
// screens-dashboard.jsx (P10, split en screens/dashboard/). Expone a window:
// CajaChicaSection, AprobacionesSection, AjustesEntregaSection. Consume
// window.CAJA_CHICA/APROBACIONES/AJUSTES_ENTREGA (core/colecciones.js),
// useEntityStats (ui/entity-list.jsx), DashSection/DashTable/srvOr/MonoId/
// TextBold/TextMuted/NumBold (compartido.jsx), IdDateCell/KpiCard/TablePill
// (ui/primitives.jsx), APROB_TIPO_LABELS (dominio/pipeline.js),
// MicosMargenSemaforo (dominio/margen.js), formatMoney/formatMoneyShort
// (dominio/formato.js). Sin fixes de values/trends acá (las 3 secciones ya
// usaban solo datos reales) — se limpian delta/highlighted (props muertas de
// KpiCard) y la composición MonoId+TextMuted → IdDateCell en Caja Chica/
// Ajustes de Entrega (Aprobaciones no tiene columna id+fecha, ver su propia
// nota abajo).

// ─── Sección · CAJA CHICA ─────────────────────────
function CajaChicaSection({ onNav }) {
  const totalIngresos = CAJA_CHICA.filter((m) => m.tipo === 'INGRESO').reduce((s, m) => s + m.monto, 0);
  const totalEgresos  = CAJA_CHICA.filter((m) => m.tipo === 'EGRESO').reduce((s, m) => s + m.monto, 0);
  // A7 (BUGS-caza-01-07-2026.md #7): v_caja_chica_stats agrega en Postgres sobre el
  // universo real (count/sumIngresos/sumEgresos/saldo = mismo criterio orden-independiente
  // que el cálculo local: sum(ingresos)-sum(egresos)).
  // FIX P13 (ítem 13, Review P10 MEDIA-1): esto ANTES sumaba una base fija `50000 +` sin
  // respaldo real (el server da saldo=0 con los datos actuales — 0 movimientos de Caja
  // Chica — y el número mostrado mentía "$50.000 disponibles"). Doctrina de honestidad
  // (CLAUDE.md §10): todo número visible se deriva de los datos, nunca hardcodeado. Ahora
  // deriva 1:1 del mismo criterio que la lista real (screens/caja-chica/lista.jsx,
  // getCajaChicaWithSaldo — running balance de los movimientos, sin piso ficticio).
  const srvStats = window.useEntityStats ? window.useEntityStats('cajaChica') : null;
  const kIngresos = srvOr(srvStats, 'sumIngresos', totalIngresos);
  const kEgresos = srvOr(srvStats, 'sumEgresos', totalEgresos);
  const kSaldo = srvOr(srvStats, 'saldo', totalIngresos - totalEgresos);
  const kCount = srvOr(srvStats, 'count', CAJA_CHICA.length);

  return (
    <DashSection
      eyebrow="Herramientas · Caja Chica"
      title="Caja Chica"
      route="caja-chica"
      onNav={onNav}
      kpis={[
        { label: 'Saldo actual', value: formatMoneyShort(kSaldo), icon: IconWallet },
        { label: 'Ingresos',     value: formatMoneyShort(kIngresos), icon: IconArrowUpRight },
        { label: 'Egresos',      value: formatMoneyShort(kEgresos), icon: IconTrendingUp },
        { label: 'Movimientos',  value: String(kCount), icon: IconFileText },
      ]}
      animDelay={360}
    >
      <DashTable
        caption="Últimos 7 movimientos de caja"
        onRowClick={() => onNav('caja-chica')}
        rows={CAJA_CHICA}
        columns={[
          { key: 'id', label: 'ID · Fecha', width: '180px',
            render: (m) => <IdDateCell id={m.publicId} date={m.fecha} /> },
          { key: 'concepto', label: 'Concepto · Empresa', width: '1.6fr',
            render: (m) => (
              <div className="min-w-0">
                <TextBold>{m.concepto}</TextBold>
                {m.empresa
                  ? <TextMuted>{m.empresa}</TextMuted>
                  : <span style={{ color: 'color-mix(in oklab, var(--muted-foreground) 55%, transparent)', fontSize: 11.5, fontStyle: 'italic' }}>—</span>}
              </div>
            ) },
          { key: 'tipo', label: 'Tipo', width: '110px',
            render: (m) => m.tipo === 'INGRESO'
              ? <TablePill label="Ingreso" tone="pos" />
              : <TablePill label="Egreso" tone="neg" /> },
          { key: 'monto', label: 'Monto', width: '140px', align: 'right',
            render: (m) => m.tipo === 'INGRESO'
              ? <span className="text-[13px] font-extrabold tabular-nums" style={{ color: 'var(--success)' }}>+ {formatMoney(m.monto)}</span>
              : <span className="text-[13px] font-extrabold tabular-nums" style={{ color: 'var(--danger)' }}>− {formatMoney(m.monto)}</span> },
        ]}
      />
    </DashSection>
  );
}

// ─── Sección · APROBACIONES ───────────────────
function AprobacionesSection({ onNav }) {
  const costoTotal = APROBACIONES.reduce((s, a) => s + a.costo, 0);
  const gananciaTotal = APROBACIONES.reduce((s, a) => s + a.ganancia, 0);
  // A7 (BUGS-caza-01-07-2026.md #7): v_aprobaciones_stats agrega en Postgres sobre el
  // universo real (fallback si /stats falla o no llegó). "Expedientes" (distintos) no
  // está en la vista — sigue derivado en memoria.
  const srvStats = window.useEntityStats ? window.useEntityStats('aprobaciones') : null;
  const kTotal = srvOr(srvStats, 'total', APROBACIONES.length);
  const kCosto = srvOr(srvStats, 'sumCosto', costoTotal);
  const kGanancia = srvOr(srvStats, 'sumGanancia', gananciaTotal);

  return (
    <DashSection
      eyebrow="Herramientas · Notificaciones de margen"
      title="Notificaciones de margen"
      route="aprobaciones"
      onNav={onNav}
      kpis={[
        { label: 'Avisos de margen', value: String(kTotal), icon: IconCheckCircle },
        { label: 'Expedientes',    value: String(new Set(APROBACIONES.map(a => a.expedienteId)).size), icon: IconFileText },
        { label: 'Costo total',    value: formatMoneyShort(kCosto), icon: IconDollar },
        { label: 'Ganancia total', value: formatMoneyShort(kGanancia), icon: IconTrendingUp },
      ]}
      animDelay={660}
    >
      <DashTable
        caption="Últimos avisos de margen"
        onRowClick={() => onNav('aprobaciones')}
        rows={APROBACIONES}
        columns={[
          { key: 'tipo', label: 'Tipo', width: '130px',
            render: (a) => <TablePill label={APROB_TIPO_LABELS[a.tipo].label} tone={APROB_TIPO_LABELS[a.tipo].tone} /> },
          {
            // Sin IdDateCell acá (a propósito): esta columna es documento +
            // expediente + solicitante, NO id+fecha — forma distinta a las
            // demás secciones, no es la misma duplicación a colapsar.
            key: 'documento', label: 'Documento · Expediente', width: '1.5fr',
            render: (a) => (
              <div className="min-w-0">
                <MonoId>{a.documento}</MonoId>
                <TextMuted>
                  <span className="font-mono font-bold">{a.expedienteId}</span> · {a.solicitante}
                </TextMuted>
              </div>
            ) },
          { key: 'costo', label: 'Costo', width: '130px', align: 'right',
            render: (a) => <NumBold>{formatMoney(a.costo)}</NumBold> },
          { key: 'ganancia', label: 'Ganancia', width: '150px', align: 'right',
            // Mismo criterio que AprobacionesScreen (screens/aprobaciones/lista.jsx):
            // margen del PEOR producto flageado vs MICOS_UMBRAL_GANANCIA, no el
            // agregado vs 25/30% — BUGS-caza-01-07-2026.md #17/M10 (MicosMargenSemaforo,
            // dominio/margen.js). NOTA (fuera de alcance de P10, ya documentada): `costo`
            // es copia idéntica de `unitario` en el 100% de los presupuestos migrados
            // (sin costo real cargado) — el % que se ve acá es un cálculo REAL sobre un
            // dato de origen no representativo, no un valor inventado por el front; el
            // fix de honestidad de esa columna vive en v_expediente_financiero (P5/D4),
            // no se replicó acá porque no fue nombrado en el dispatch de este paquete.
            render: (a) => {
              const sem = window.MicosMargenSemaforo(a);
              return (
                <div className="flex flex-col items-end gap-0.5">
                  <NumBold>{formatMoney(a.ganancia)}</NumBold>
                  <span className="text-[11px] font-bold tabular-nums" style={{ color: sem.color }}>{sem.pct.toFixed(0)}%</span>
                </div>
              );
            } },
        ]}
      />
    </DashSection>
  );
}

// ─── Sección · AJUSTES DE ENTREGA ──────────────
function AjustesEntregaSection({ onNav }) {
  const total = AJUSTES_ENTREGA.length;
  const itemsConDiff = AJUSTES_ENTREGA.reduce((s, a) => s + a.items.filter(i => i.facturado !== i.entregado).length, 0);
  const stockPos = AJUSTES_ENTREGA.reduce((s, a) => s + (a.diffStock > 0 ? a.diffStock : 0), 0);
  const stockNeg = AJUSTES_ENTREGA.reduce((s, a) => s + (a.diffStock < 0 ? a.diffStock : 0), 0);
  const stockNeto = stockPos + stockNeg;
  // A7 (BUGS-caza-01-07-2026.md #7): v_ajustes_entrega_stats agrega en Postgres sobre el
  // universo real. De paso corrige el label: "pendientes" en la vista SÍ filtra
  // aprobado<>true (el cálculo local de acá contaba TODOS los ajustes, no solo los
  // pendientes). "Ítems con diferencia" no está en la vista — sigue en memoria.
  const srvStats = window.useEntityStats ? window.useEntityStats('ajustesEntrega') : null;
  const kPendientes = srvOr(srvStats, 'pendientes', total);
  const kStockNeg = srvOr(srvStats, 'sumDiffNeg', stockNeg);
  const kStockPos = srvOr(srvStats, 'sumDiffPos', stockPos);
  const kStockNeto = kStockPos + kStockNeg;

  return (
    <DashSection
      eyebrow="Herramientas · Ajustes de inventario"
      title="Ajustes de Inventario"
      route="ajustes-inventario"
      onNav={onNav}
      kpis={[
        { label: 'Ajustes pendientes', value: String(kPendientes), icon: IconCheckCircle },
        { label: 'Ítems con diferencia', value: String(itemsConDiff), icon: IconPackage },
        { label: 'Restan stock', value: `${kStockNeg} u.`, icon: IconTrendingUp },
        { label: 'Impacto neto', value: `${kStockNeto > 0 ? '+' : ''}${kStockNeto} u.`, icon: IconArrowUpRight },
      ]}
      animDelay={720}
    >
      <DashTable
        caption="Últimos 7 ajustes de entrega"
        onRowClick={() => onNav('ajustes-inventario')}
        rows={AJUSTES_ENTREGA}
        emptyLabel="Sin ajustes pendientes"
        emptyHint="Cuando un remito difiera de lo entregado en quirófano va a aparecer acá."
        columns={[
          { key: 'remito', label: 'Remito', width: '180px',
            render: (a) => <IdDateCell id={a.remitoId} date={a.creado} /> },
          { key: 'expediente', label: 'Expediente · Solicitante', width: '1.5fr',
            render: (a) => (
              <div className="min-w-0">
                <p className="text-[12.5px] font-bold truncate" style={{ color: 'var(--foreground)' }}>
                  <span className="font-mono" style={{ color: 'var(--accent)' }}>{a.expedienteId}</span>
                </p>
                <TextMuted>{a.solicitante} · {a.items.filter(i => i.facturado !== i.entregado).length} con diferencia</TextMuted>
              </div>
            ) },
          { key: 'items', label: 'Ítems', width: '90px', align: 'right',
            render: (a) => <NumBold>{a.items.length}</NumBold> },
          { key: 'impacto', label: 'Impacto stock', width: '140px', align: 'right',
            render: (a) => (
              <span className="text-[14px] font-extrabold tabular-nums"
                style={{ color: a.diffStock < 0 ? 'var(--danger)' : a.diffStock > 0 ? 'var(--success)' : 'var(--foreground)' }}>
                {a.diffStock > 0 ? '+' : ''}{a.diffStock} u.
              </span>
            ) },
        ]}
      />
    </DashSection>
  );
}

Object.assign(window, { CajaChicaSection, AprobacionesSection, AjustesEntregaSection });
