// ─── Aprobaciones · Ajustes de Entrega (paquete del header) ───────────────
// AjustesEntregaCard: tabla expandible de diferencias facturado/entregado por
// remito, con aprobar/cancelar/editar-entregado — el ÚNICO módulo del cajón
// viejo con escritura server-side bien resuelta de punta a punta (whitelist
// AJUSTE_COLUMNS, campos de auditoría sellados server-side, sin fabricación de
// datos). Extraído tal cual de screens-others.jsx (P9, split del cajón de 5
// módulos) — cero cambio de comportamiento. Expone a window: AjustesEntregaCard.
// Consume applyInventarioFromAjuste (inventario-impacto.js), KpiCard (ui/
// primitives.jsx), formatMoney (dominio/formato.js), MicosCurrentUser (dominio/
// sesion.js), MicosStore (core/store.js).
function AjustesEntregaCard({ onOpen }) {
  const [expandedId, setExpandedId] = React.useState(AJUSTES_ENTREGA[0]?.id || null);
  const [search, setSearch] = React.useState('');
  const [chipValue, setChipValue] = React.useState(null);
  const [, _force] = React.useReducer((x) => x + 1, 0);

  // M11 — al montar refrescamos los ajustes desde el backend: los que se generan al crear un
  // remito (POST /api/remitos) no están en el snapshot del hydrate inicial.
  React.useEffect(() => {
    if (window.MicosStore && window.MicosStore.refresh) {
      window.MicosStore.refresh('ajustesEntrega').then(() => _force()).catch(() => {});
    }
  }, []);

  // Aprobar = habilita la impresión del remito + impacta el stock. Cancelar = quita el
  // ajuste (levanta la retención: el remito queda imprimible sin aprobación).
  const aprobar = (aj) => {
    if (window.MicosStore) {
      const u = (window.MicosCurrentUser && window.MicosCurrentUser()) || null;
      const quienNombre = (u && (u.nombre ? `${u.nombre} ${u.apellido || ''}`.trim() : u.name)) || 'Equipo Micos';
      // Solo mandamos `aprobado`: el server sella aprobado_por (auth.uid()), aprobado_at e
      // inventario_aplicado — no confiamos en el cliente para los campos de auditoría (el PATCH
      // los rechaza; anti audit-field spoofing, security review #2).
      window.MicosStore.update('ajustesEntrega', aj.id, { aprobado: true });
      aj.aprobadoPor = quienNombre; // display inmediato (el refresh trae el nombre resuelto del backend)
      // Aprobar impacta el stock con la diferencia facturado − entregado (idempotente).
      try { applyInventarioFromAjuste(aj); } catch (_) {}
      // Traer el shape resuelto del backend (aprobadoPor=nombre, inventarioAplicado, etc.).
      if (window.MicosStore.refresh) {
        setTimeout(() => { window.MicosStore.refresh('ajustesEntrega').then(() => _force()).catch(() => {}); }, 700);
      }
    }
    _force();
  };
  const cancelar = (aj) => { if (window.MicosStore) window.MicosStore.remove('ajustesEntrega', aj.id); _force(); };

  // Editar lo REALMENTE entregado por ítem (solo ajustes pendientes). Actualiza el display al
  // instante (mutación local) y, al salir del campo, persiste: el PATCH reemplaza los items y
  // recalcula diff_stock (Σ facturado − entregado) — esa diferencia es la que se descuenta al
  // aprobar. Sin esto, entregado===facturado siempre y el descuento sería 0.
  const setEntregado = (aj, idx, val) => {
    const n = Math.max(0, Number(val) || 0);
    aj.items = aj.items.map((it, i) => (i === idx ? { ...it, entregado: n } : it));
    // Recalcular el neto local (Σ facturado − entregado) para que las KPIs/diff de la card
    // reflejen el cambio al instante; el backend lo recalcula igual como fuente de verdad.
    aj.diffStock = aj.items.reduce((s, it) => s + ((Number(it.facturado) || 0) - (Number(it.entregado) || 0)), 0);
    _force();
  };
  const persistItems = (aj) => {
    if (window.MicosStore) window.MicosStore.update('ajustesEntrega', aj.id, { items: aj.items });
  };

  const totalAjustes = AJUSTES_ENTREGA.length;
  const pendientes = AJUSTES_ENTREGA.filter((a) => a.aprobado !== true).length;
  const itemsConDiffTotal = 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;

  const chipOptions = [
    { label: 'Resta stock',     value: 'NEG',  count: AJUSTES_ENTREGA.filter(a => a.diffStock < 0).length },
    { label: 'Suma stock',      value: 'POS',  count: AJUSTES_ENTREGA.filter(a => a.diffStock > 0).length },
    { label: 'Sin diferencia',  value: 'ZERO', count: AJUSTES_ENTREGA.filter(a => a.diffStock === 0).length },
  ].filter(o => o.count > 0);

  const filtered = AJUSTES_ENTREGA.filter((a) => {
    if (chipValue === 'NEG'  && !(a.diffStock < 0)) return false;
    if (chipValue === 'POS'  && !(a.diffStock > 0)) return false;
    if (chipValue === 'ZERO' && !(a.diffStock === 0)) return false;
    if (!search.trim()) return true;
    const q = search.trim().toLowerCase();
    // Guardas contra null: serializeAjuste puede devolver remitoId/solicitante null cuando el
    // embed no resuelve (remito soft-eliminado, o usuario sin permiso 'expedientes' para leer
    // el remito embebido). Sin la guarda, .toLowerCase() sobre null rompía TODA la pantalla al
    // tipear en el buscador (review M11 #2).
    return (a.remitoId || '').toLowerCase().includes(q)
      || (a.expedienteId || '').toLowerCase().includes(q)
      || (a.solicitante || '').toLowerCase().includes(q);
  });

  const gridCols = '180px 1fr 130px 180px 150px';
  // Tabla expandida: ID · Producto (con lote) · Facturado · Entregado (editable si pendiente)
  const itemCols = '150px 1fr 110px 130px';
  // Fallback de lote por SKU para datos persistidos sin el campo (demo)
  const LOTE_FALLBACK = {
    'JNJ-PLAC-014': 'L-24112', 'SMN-TRN-007': 'L-24108', 'STR-CMNT-002': 'L-24091',
    'MED-CTHR-021': 'L-24077', 'BRA-SUTR-009': 'L-24063', 'SYN-PIN-031': 'L-24055',
  };

  return (
    <div className="space-y-5 pt-4">
      {/* Header de la sección — espejo del header de EntityListScreen */}
      <div className="flex flex-wrap items-end justify-between gap-4 animate-fade-in-up" style={{ animationDelay: '260ms' }}>
        <div className="space-y-3 min-w-0">
          <p className="text-[11px] font-bold uppercase tracking-[0.18em]" style={{ color: 'var(--accent)' }}>
            Herramientas · Ajustes de inventario
          </p>
          <h2 className="text-[clamp(28px,4.2vw,40px)] leading-[1.05] font-extrabold tracking-[-0.02em]" style={{ color: 'var(--foreground)' }}>
            Ajustes de Inventario
          </h2>
          <p className="text-[13.5px] font-medium max-w-2xl" style={{ color: 'var(--muted-foreground)' }}>
            Lo facturado en el remito puede no coincidir con lo entregado en quirófano. Aprobá los ajustes para impactar el stock y habilitar la impresión del remito.
          </p>
        </div>
        <div className="flex items-center gap-2.5 flex-shrink-0">
          {/* FIX hallazgo auditoría 05/07/2026 (botón sin onClick, misma cara que uno
              clickeable): no existe todavía una vista de historial de ajustes — en vez de
              dejar la promesa sin cablear, queda deshabilitado honesto (mismo patrón "gris
              plano, sin feedback" de los disabled legítimos ya documentados, CLAUDE.md §2). */}
          <button type="button" className="btn btn-outline" disabled title="Historial de ajustes — todavía no disponible">
            <IconClock size={15} />
            <span className="hidden sm:inline">Ver historial</span>
          </button>
        </div>
      </div>

      {/* KPIs */}
      <div className="grid grid-cols-2 lg:grid-cols-4 gap-3 sm:gap-4 stagger">
        <KpiCard
          label="Ajustes pendientes"
          value={String(pendientes)}
          delta={`${itemsConDiffTotal} items con diferencia`}
          deltaTone="neutral"
          icon={IconCheckCircle}
        />
        <KpiCard
          label="Sumas al stock"
          value={`+${stockPos} unidades`}
          delta="Sobrantes en quirófano"
          deltaTone="pos"
          icon={IconArrowUpRight}
        />
        <KpiCard
          label="Restas al stock"
          value={`${stockNeg} unidades`}
          delta="Faltantes a reponer"
          deltaTone="neg"
          icon={IconPackage}
        />
        <KpiCard
          label="Impacto neto"
          value={`${stockNeto > 0 ? '+' : ''}${stockNeto} unidades`}
          delta="Sobre el stock disponible"
          deltaTone={stockNeto < 0 ? 'neg' : stockNeto > 0 ? 'pos' : 'neutral'}
          icon={IconTrendingUp}
        />
      </div>

      {/* Filter chips */}
      {chipOptions.length > 0 && (
        <div className="flex items-center gap-2 overflow-x-auto pb-1 scrollbar-none animate-fade-in-up" style={{ animationDelay: '300ms' }}>
          <button
            onClick={() => setChipValue(null)}
            className="chip"
            style={chipValue == null
              ? { background: 'var(--accent)', color: 'var(--accent-foreground)', boxShadow: '0 6px 18px -8px rgba(15,187,182,0.55)' }
              : { background: 'color-mix(in oklab, var(--muted-foreground) 8%, transparent)', color: 'var(--muted-foreground)' }
            }
          >
            Todos
            <span className="opacity-70 tabular-nums">{AJUSTES_ENTREGA.length}</span>
          </button>
          {chipOptions.map((opt) => {
            const active = chipValue === opt.value;
            return (
              <button
                key={opt.value}
                onClick={() => setChipValue(active ? null : opt.value)}
                className="chip"
                style={active
                  ? { background: 'var(--accent)', color: 'var(--accent-foreground)', boxShadow: '0 6px 18px -8px rgba(15,187,182,0.55)' }
                  : { background: 'color-mix(in oklab, var(--muted-foreground) 8%, transparent)', color: 'var(--muted-foreground)' }
                }
              >
                {opt.label}
                <span className="opacity-70 tabular-nums">{opt.count}</span>
              </button>
            );
          })}
        </div>
      )}

      {/* Card con la lista de ajustes — mismo shell que el table card */}
      <div className="glow-track animate-fade-in-up rounded-2xl" style={{
        animationDelay: '320ms',
        background: 'var(--card)',
        border: '1px solid color-mix(in oklab, var(--border) 55%, transparent)',
        boxShadow: 'var(--shadow-card)',
        overflow: 'hidden',
      }}>
        {/* Search row */}
        <div className="flex items-center justify-between gap-4 px-5 py-4"
          style={{ borderBottom: '1px solid color-mix(in oklab, var(--border) 55%, transparent)' }}>
          <div className="relative flex-1 max-w-2xl">
            <IconSearch size={15} className="absolute left-3.5 top-1/2 -translate-y-1/2" style={{ color: 'var(--muted-foreground)' }} />
            <input
              value={search}
              onChange={(e) => setSearch(e.target.value)}
              placeholder="Buscar por remito, expediente o solicitante…"
              className="w-full h-10 pl-10 pr-3 text-[13px] font-medium rounded-lg outline-none transition-colors"
              style={{
                background: 'color-mix(in oklab, var(--surface) 50%, transparent)',
                border: '1px solid color-mix(in oklab, var(--border) 45%, transparent)',
                color: 'var(--foreground)',
              }}
            />
          </div>
          <span className="text-[12px] font-semibold tabular-nums whitespace-nowrap" style={{ color: 'var(--muted-foreground)' }}>
            {filtered.length} resultados
          </span>
        </div>

        {/* Table head */}
        <div className="grid gap-4 px-6 py-3.5 text-[10.5px] font-bold uppercase tracking-[0.08em]"
          style={{
            gridTemplateColumns: gridCols,
            color: 'var(--muted-foreground)',
            borderBottom: '1px solid color-mix(in oklab, var(--border) 60%, transparent)',
          }}>
          <span>Remito</span>
          <span>Expediente · Ítems</span>
          <span>Solicitante</span>
          <span className="text-right">Impacto stock</span>
          <span className="text-right">Acciones</span>
        </div>

        {filtered.map((aj, idx) => {
          const expanded = expandedId === aj.id;
          const itemsConDiff = aj.items.filter(i => i.facturado !== i.entregado).length;
          const isLast = idx === filtered.length - 1;
          return (
            <div
              key={aj.id}
              style={{ borderBottom: !isLast ? '1px solid color-mix(in oklab, var(--border) 45%, transparent)' : 'none' }}
            >
              {/* Fila resumen — clickeable para expandir */}
              <div
                role="button"
                tabIndex={0}
                onClick={() => setExpandedId(expanded ? null : aj.id)}
                onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); setExpandedId(expanded ? null : aj.id); } }}
                className="w-full grid items-center gap-4 px-6 py-4 text-left cursor-pointer exp-row"
                style={{ gridTemplateColumns: gridCols }}
              >
                <div className="min-w-0">
                  <p className="font-mono text-[12.5px] font-bold tracking-wide uppercase" style={{ color: 'var(--accent)' }}>{aj.remitoId}</p>
                  <p className="text-[11.5px] mt-1 tabular-nums" style={{ color: 'var(--muted-foreground)' }}>{aj.creado.slice(0,10)}</p>
                </div>
                <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)' }}>{aj.expedienteId}</span>
                  </p>
                  <p className="text-[11.5px] mt-0.5 truncate" style={{ color: 'var(--muted-foreground)' }}>
                    {itemsConDiff} {itemsConDiff === 1 ? 'item' : 'items'} con diferencia · {aj.items.length} total
                  </p>
                </div>
                <span className="text-[12.5px] font-semibold" style={{ color: 'var(--foreground)' }}>{aj.solicitante}</span>
                <div className="text-right">
                  <p className="text-[15px] font-extrabold tabular-nums"
                    style={{ color: aj.diffStock < 0 ? 'var(--danger)' : aj.diffStock > 0 ? 'var(--success)' : 'var(--foreground)' }}>
                    {aj.diffStock > 0 ? '+' : ''}{aj.diffStock} unidades
                  </p>
                </div>
                <div className="flex items-center justify-end gap-2">
                  {aj.aprobado === true ? (
                    <span className="inline-flex items-center gap-1.5 rounded-md px-2.5 h-7 text-[11px] font-bold uppercase tracking-[0.04em]"
                      style={{ background: 'color-mix(in oklab, var(--success) 16%, transparent)', color: 'var(--success)' }}
                      title={aj.aprobadoPor ? `Aprobado por ${aj.aprobadoPor}` : 'Aprobado'}>
                      <IconCheck size={13} />Aprobado
                    </span>
                  ) : (
                    <>
                      <button
                        type="button"
                        onClick={(e) => { e.stopPropagation(); cancelar(aj); }}
                        className="inline-flex items-center justify-center rounded-md transition-colors cursor-pointer"
                        style={{ width: 32, height: 32, color: 'var(--danger)', background: 'rgba(220, 38, 38, 0.10)', border: 'none' }}
                        onMouseEnter={(e) => e.currentTarget.style.background = 'rgba(220, 38, 38, 0.22)'}
                        onMouseLeave={(e) => e.currentTarget.style.background = 'rgba(220, 38, 38, 0.10)'}
                        title="Cancelar ajuste"
                      >
                        <IconX size={15} />
                      </button>
                      <button
                        type="button"
                        onClick={(e) => { e.stopPropagation(); aprobar(aj); }}
                        className="inline-flex items-center justify-center rounded-md transition-colors cursor-pointer"
                        style={{ width: 32, height: 32, color: 'var(--accent-foreground)', background: 'var(--accent)', border: 'none' }}
                        title="Aprobar ajuste (habilita imprimir el remito)"
                      >
                        <IconCheck size={15} />
                      </button>
                    </>
                  )}
                  <IconChevronDown
                    size={16}
                    style={{
                      color: 'var(--muted-foreground)',
                      transform: expanded ? 'rotate(180deg)' : 'rotate(0deg)',
                      transition: 'transform .18s ease',
                    }}
                  />
                </div>
              </div>

              {/* Detalle expandido: tabla facturado vs entregado */}
              <div
                aria-hidden={!expanded}
                style={{
                  display: 'grid',
                  gridTemplateRows: expanded ? '1fr' : '0fr',
                  transition: 'grid-template-rows .28s ease',
                }}>
                <div style={{ overflow: 'hidden' }}>
                  <div
                    style={{
                      background: 'color-mix(in oklab, var(--muted-foreground) 4%, transparent)',
                      borderTop: '1px solid color-mix(in oklab, var(--border) 40%, transparent)',
                      opacity: expanded ? 1 : 0,
                      transition: 'opacity .22s ease',
                    }}>
                  {/* Cabecera de la mini-tabla */}
                  <div className="grid items-center gap-4 px-6 py-2.5 text-[10.5px] font-bold uppercase tracking-[0.1em]"
                    style={{
                      gridTemplateColumns: itemCols,
                      color: 'var(--muted-foreground)',
                      borderBottom: '1px solid color-mix(in oklab, var(--border) 35%, transparent)',
                    }}>
                    <span>ID</span>
                    <span>Producto</span>
                    <span className="text-right">Facturado</span>
                    <span className="text-right">Entregado</span>
                  </div>
                  {/* Filas */}
                  {aj.items.map((it, i) => {
                    const lote = it.lote || LOTE_FALLBACK[it.sku] || '—';
                    return (
                      <div
                        key={i}
                        className="grid items-center gap-4 px-6 py-2.5"
                        style={{
                          gridTemplateColumns: itemCols,
                          borderBottom: i < aj.items.length - 1 ? '1px solid color-mix(in oklab, var(--border) 25%, transparent)' : 'none',
                        }}
                      >
                        <span className="font-mono text-[11.5px] font-bold tracking-wide uppercase" style={{ color: 'var(--accent)' }}>{it.sku}</span>
                        <div className="min-w-0">
                          <p className="text-[12.5px] font-medium truncate" style={{ color: 'var(--foreground)' }}>{it.desc}</p>
                          <p className="font-mono text-[11px] font-semibold tracking-wide uppercase mt-0.5 truncate" style={{ color: 'var(--muted-foreground)' }}>Lote {lote}</p>
                        </div>
                        <span className="text-right text-[13px] font-bold tabular-nums self-center" style={{ color: 'var(--foreground)' }}>
                          {it.facturado} <span className="text-[11px] font-medium" style={{ color: 'var(--muted-foreground)' }}>u.</span>
                        </span>
                        {aj.aprobado ? (
                          // Aprobado: solo lectura; en accent si difiere de lo facturado (hubo ajuste).
                          <span className="text-right text-[13px] font-bold tabular-nums self-center"
                            style={{ color: it.facturado !== it.entregado ? 'var(--accent)' : 'var(--foreground)' }}>
                            {it.entregado} <span className="text-[11px] font-medium" style={{ color: 'var(--muted-foreground)' }}>u.</span>
                          </span>
                        ) : (
                          // Pendiente: editable. Uncontrolled (defaultValue) para no perder foco al tipear;
                          // al salir del campo actualiza el display (KPIs/diff) y persiste (PATCH → recalcula diff_stock).
                          <input
                            type="number" min="0"
                            className="input text-right tabular-nums self-center"
                            style={{ height: '30px', padding: '0 8px', fontSize: '13px', fontWeight: 700 }}
                            defaultValue={it.entregado}
                            key={`ent-${aj.id}-${i}`}
                            onBlur={(e) => { setEntregado(aj, i, e.target.value); persistItems(aj); }}
                            title="Unidades realmente entregadas — la diferencia con lo facturado ajusta el stock al aprobar"
                          />
                        )}
                      </div>
                    );
                  })}
                  </div>
                </div>
              </div>
            </div>
          );
        })}
      </div>
    </div>
  );
}

Object.assign(window, { AjustesEntregaCard });
