// ─── Documento del expediente: Remito ────────────────────────────────────
// RemitoScreen: tercer documento del pipeline (ORDEN_COMPRA → REMITO), hereda
// ítems de la OC (o del presupuesto si no hay OC) y dispara el ajuste de
// entrega (M11) que bloquea la impresión hasta que se apruebe en Ajustes de
// inventario. Extraída de screens-docs.jsx en P7. Expone a window:
// RemitoScreen. Consume window.resolveDocExp (screens/docs/compartido.jsx),
// DocumentShell/DocCard/PartyBlock/Totals/MedicalContextCard/
// buildEmisorFields/buildClienteFields (ui/doc-kit-shell.jsx), DocMetaStrip
// (ui/doc-kit-meta.jsx), ItemsTable (ui/doc-kit-items.jsx), useDocEdit/
// buildDocActions (ui/doc-kit-edit.jsx), emptyRemito/saveDocOnExp (dominio/
// expediente-docs.js), window.MicosStore/AJUSTES_ENTREGA (core/store.js/
// colecciones.js), window.MicosDocRemito/openPrintDoc, window.PartySelectorModal
// (ui/party-selector.jsx)/ENTIDADES (core/colecciones.js) — DECISIÓN 4 (06/07/2026):
// lápiz "Cambiar cliente", antes no-op, ver estado `clientePicker` más abajo.
//
// P7 (duplicación #3 del mapa): el bloque final Observaciones+CAI/Vto CAI/
// Aclaración, reimplementado a mano (textarea/párrafo casi idéntico al de
// ObservacionesCard + 3 campos propios que esa card no soporta), se extrae a
// `ObservacionesRemitoCard` — sub-componente PROPIO de esta pantalla (no
// infra cross-file: solo Remito necesita CAI) que reproduce el mismo patrón
// visual de "Notas" en vez de tenerlo inline en el render.
//
// MUERTO encontrado al partir el archivo (no estaba en el censo del mapa):
// REMITO_ESTADOS/REMITO_ESTADO_LABELS (enum DRAFT/PENDIENTE_RECEPCION/
// CONFIRMADO/ANULADO) sin un solo consumidor en todo el repo — el `estado`
// que emptyRemito() prellena nunca se muestra en ningún lado. Se borra.
//
// EXCEPCIÓN AL TECHO DE ~250 LÍNEAS (regla nueva de la compuerta, P7 §3) — SOBRE el techo
// duro de 400 (número real en ESTRUCTURA.md §(g), DECISIÓN 4 06/07/2026 lo empujó un poco
// más): dos temas relacionados y ya nombrados (RemitoScreen + su ObservacionesRemitoCard),
// sin corte más chico posible sin fragmentar en un archivo de una sola función sin otro
// consumidor. Debe re-splitearse en un paquete de limpieza dedicado (fuera de alcance
// puntual de cualquier decisión chica que solo agregue un campo/lápiz) — candidato natural:
// sacar ObservacionesRemitoCard a su propio archivo.
//
// FIX P13 (A0, hallazgo ALTO de la consolidación — misma familia que
// presupuesto.jsx): el PartyBlock "Cliente" leía `exp.particular.nombre`/
// `.apellido` sin guarda (una de las 5 copias del baseline, `77b36f5`) —
// blindado igual que las demás; ver presupuesto.jsx para el detalle completo
// de la causa de fondo (id-race de Expedientes, arreglado en core/app.jsx +
// screens/expedientes/alta.jsx).

// ─── Observaciones + datos propios del remito (Aclaración / CAI / Vto CAI) ──
// Mismo patrón de "Notas" (label + textarea en edición / párrafo en lectura)
// que ObservacionesCard (ui/doc-kit-shell.jsx), con los 3 campos que solo
// tiene el Remito debajo — por eso no es la misma ObservacionesCard.
function ObservacionesRemitoCard({
  editing,
  observaciones, onObservacionesChange,
  cai, onCaiChange,
  caiFechaVenc, onCaiFechaVencChange,
  aclaracion, onAclaracionChange,
}) {
  return (
    <DocCard editing={editing}>
      <p className="text-[11px] font-bold uppercase tracking-[0.2em] mb-5" style={{ color: 'var(--accent)' }}>
        Observaciones
      </p>
      <div className="space-y-2">
        <p className="text-[10.5px] font-bold uppercase tracking-[0.14em]" style={{ color: 'var(--muted-foreground)' }}>
          Notas
        </p>
        {editing ? (
          <textarea
            value={observaciones}
            onChange={(e) => onObservacionesChange(e.target.value)}
            rows={3}
            placeholder="Notas, condiciones particulares o instrucciones…"
            className="edit-textarea text-[14px] font-bold leading-snug"
          />
        ) : (
          <p className="text-[14px] font-bold leading-snug whitespace-pre-line" style={{ color: 'var(--foreground)' }}>
            {observaciones || '—'}
          </p>
        )}
      </div>
      <div className="grid grid-cols-1 sm:grid-cols-3 gap-x-8 gap-y-6 mt-6 pt-5" style={{ borderTop: '1px solid color-mix(in oklab, var(--border) 45%, transparent)' }}>
        <div className="space-y-2">
          <p className="text-[10.5px] font-bold uppercase tracking-[0.14em]" style={{ color: 'var(--muted-foreground)' }}>
            CAI
          </p>
          {editing ? (
            <input
              value={cai}
              onChange={(e) => onCaiChange(e.target.value)}
              placeholder="CAI"
              className="edit-input w-full font-mono text-[14px] font-bold tabular-nums"
              style={{ color: 'var(--foreground)' }}
            />
          ) : (
            <p className="font-mono text-[15px] font-extrabold tabular-nums tracking-tight" style={{ color: 'var(--foreground)' }}>
              {cai || '—'}
            </p>
          )}
        </div>
        <div className="space-y-2">
          <p className="text-[10.5px] font-bold uppercase tracking-[0.14em]" style={{ color: 'var(--muted-foreground)' }}>
            Vto. CAI
          </p>
          {editing ? (
            <input
              type="date"
              value={caiFechaVenc}
              onChange={(e) => onCaiFechaVencChange(e.target.value)}
              className="edit-input w-full font-mono text-[14px] font-bold tabular-nums"
              style={{ color: 'var(--foreground)' }}
            />
          ) : (
            <p className="font-mono text-[15px] font-extrabold tabular-nums tracking-tight" style={{ color: 'var(--foreground)' }}>
              {caiFechaVenc ? formatDate(caiFechaVenc) : '—'}
            </p>
          )}
        </div>
        <div className="space-y-2">
          <p className="text-[10.5px] font-bold uppercase tracking-[0.14em]" style={{ color: 'var(--muted-foreground)' }}>
            Aclaración
          </p>
          {editing ? (
            <input
              value={aclaracion}
              onChange={(e) => onAclaracionChange(e.target.value)}
              placeholder="Aclaración del remito"
              className="edit-input w-full text-[14px] font-bold"
              style={{ color: 'var(--foreground)' }}
            />
          ) : (
            <p className="text-[14px] font-bold leading-snug" style={{ color: 'var(--foreground)' }}>
              {aclaracion || '—'}
            </p>
          )}
        </div>
      </div>
    </DocCard>
  );
}

// `startEditing` (opcional): lo inyecta DocSubrouteGate (screens/docs/compartido.jsx)
// en un F5/deep-link directo a esta sub-ruta, para abrir el remito REAL ya en edición
// (datos reales, no un alta en blanco). En navegación normal llega false y no cambia
// nada (startEditing sigue siendo isCreate).
function RemitoScreen({ expediente, onBack, startEditing = false }) {
  const exp = resolveDocExp(expediente);
  const co = COMPANY_CONFIG;
  const isCreate = !exp.remito;
  const original = React.useMemo(() => exp.remito || emptyRemito(exp), [exp.remito]);
  const [toast, setToast] = React.useState(null);
  // DECISIÓN 4 (06/07/2026): lápiz "Cambiar cliente" — antes no-op (`onClick={() => {}}`).
  const [clientePicker, setClientePicker] = React.useState(false);
  // M11 — al montar refrescamos ajustes de entrega para que el bloqueo de impresión sea real.
  const [, bumpAjustes] = React.useReducer((x) => x + 1, 0);
  React.useEffect(() => {
    if (window.MicosStore && window.MicosStore.refresh) {
      window.MicosStore.refresh('ajustesEntrega').then(() => bumpAjustes()).catch(() => {});
    }
  }, []);

  const { editing, draft, setDraft, enterEdit, discardEdit, saveEdit, patch } = useDocEdit(() => {
    // Enriquece itemsFactura con datos de itemsReal (match por sku) para mostrar unit/bonif/IVA/ganancia igual que "Detalle real entregado".
    // FIX (hallazgo ALTA #1, auditoría 05/07/2026): "Ítems facturados" ahora persiste de
    // verdad como filas de remito_item (facturado=true, remitos/route.ts) — un ítem YA
    // guardado trae su propio sku/unitario/total reales (no `codigo`, que es el shape viejo
    // sin persistir de emptyRemito() al CREAR un remito nuevo, dominio/expediente-docs.js,
    // fuera de alcance de este cambio). bonifPct/ivaPct/costo siguen sin ser columnas (ni acá
    // ni en itemsReal) — se derivan del ítem real emparejado por sku, mismo criterio de
    // siempre.
    const realBySku = Object.fromEntries((original.itemsReal || []).map((r) => [r.sku, r]));
    const enrichedFactura = original.itemsFactura.map((it) => {
      const sku = it.sku || it.codigo;
      const r = realBySku[sku] || {};
      const cantidad = Number(it.cantidad) || 0;
      const unitario = it.unitario != null ? Number(it.unitario) : (Number(r.unitario) || 0);
      const bonifPct = it.bonifPct != null ? Number(it.bonifPct) : (Number(r.bonifPct) || 0);
      const ivaPct = it.ivaPct ?? r.ivaPct ?? 21;
      const costo = it.costo ?? r.costo;
      const lote = it.lote || r.lote;
      const total = it.total != null ? Number(it.total) : cantidad * unitario * (1 - bonifPct / 100);
      return { sku, descripcion: it.descripcion, cantidad, unitario, bonifPct, ivaPct, costo, lote, total };
    });
    return {
      // FIX (review-lote.md, hallazgo MEDIO P17a): "Emisión" bindeaba a `fechaEmision`, clave
      // que remitos NO tiene como columna (la real es `fecha_creacion`, la misma que ordena la
      // lista desde P15) — el desbloqueo de P17a la dejó editable pero el PATCH la descartaba
      // por whitelist, así que el cambio se perdía en silencio. `fechaCreacion` SÍ es columna
      // real (REMITO_COLUMNS en src/app/api/remitos/route.ts) y persiste de punta a punta.
      fechaCreacion: original.fechaCreacion,
      fechaValidez: original.fechaValidez || exp.presupuesto?.fechaValidez || '',
      // FIX (hallazgo ALTA #7, auditoría 05/07/2026): antes SIEMPRE arrancaban del vendedor/
      // condición de venta LINKEADOS al expediente (nunca del propio remito) — el valor
      // guardado en el documento se perdía visualmente en cada re-entrada aunque la DB lo
      // tuviera. `original.*` (persistido) gana; el vínculo del expediente queda como
      // default solo para un remito nuevo/sin ese campo cargado todavía. `formaPago` (no
      // `condicionVenta`, que es el nombre local histórico) mapea mecánicamente a la
      // columna real `forma_pago` sin necesitar alias en el backend.
      vendedor: original.vendedor || exp.vendedor?.name || '',
      vendedorAux: original.vendedorAux || exp.vendedorAux?.name || '',
      formaPago: original.formaPago || exp.entidad?.condicionVenta || 'Cuenta corriente — 30 días',
      // FIX (hallazgo "Moneda", AUDITORIA-ui-decorativa-05-07-2026.md): arrancaba SIEMPRE
      // hardcodeado a 'Pesos argentinos' en vez de partir de lo persistido (original.moneda),
      // igual que orden-compra.jsx ya hacía.
      moneda: original.moneda || 'Pesos argentinos',
      aclaracion: original.aclaracion || '',
      cai: original.cai || '',
      caiFechaVenc: original.caiFechaVenc || '',
      observaciones: original.observaciones || '',
      // DECISIÓN 4: override opcional del cliente de este documento (`remitos.entidad_id`).
      entidadId: original.entidadId || null,
      itemsFactura: enrichedFactura,
      itemsReal: original.itemsReal.map((it) => ({ ...it })),
    };
  }, {
    startEditing: isCreate || startEditing,
    onCancel: () => { if (isCreate) onBack(); },
    onSave: (d) => {
      const docObj = {
        ...original,
        fechaCreacion: d.fechaCreacion,
        fechaValidez: d.fechaValidez,
        // FIX (hallazgo ALTA #7): antes docObj NI SIQUIERA copiaba estos 3 campos del draft
        // — doble muerte (no viajaban Y la whitelist tampoco los tenía). Ahora viajan con los
        // nombres que REMITO_COLUMNS espera (vendedor/vendedorAux mecánicos; formaPago mapea
        // a la columna real `forma_pago`).
        vendedor: d.vendedor || '',
        vendedorAux: d.vendedorAux || '',
        formaPago: d.formaPago || '',
        // FIX (hallazgo "Moneda"): docObj no copiaba `d.moneda` — el select se editaba en
        // pantalla pero el valor elegido nunca viajaba al backend.
        moneda: d.moneda || '',
        aclaracion: d.aclaracion || '',
        cai: d.cai || '',
        caiFechaVenc: d.caiFechaVenc || '',
        observaciones: d.observaciones || '',
        importeLetras: d.importeLetras || '',
        // DECISIÓN 4: mismo criterio que orden-compra.jsx — el spread de `...original`
        // (arriba) solo trae el valor VIEJO; el elegido con el lápiz viaja acá.
        entidadId: d.entidadId || null,
        // FIX (hallazgo ALTA #1): antes se mandaba un shape recortado a {codigo,descripcion,
        // cantidad} (perdía unitario/total) Y el backend ni siquiera los leía. Ahora se manda
        // el ítem completo (mismo criterio que itemsReal) — remitos/route.ts lo persiste como
        // fila de remito_item con facturado=true.
        itemsFactura: (d.itemsFactura || []).map((it) => ({ ...it })),
        itemsReal: (d.itemsReal || []).map((it) => ({ ...it })),
      };
      saveDocOnExp(exp, 'remito', docObj);
      // M11 — al CREAR un remito, el backend genera su ajuste de entrega (POST /api/remitos →
      // ajustes_entrega, pendiente de aprobación; hasta que se apruebe no se puede imprimir).
      // Reintentos escalonados porque el ajuste se crea DENTRO del POST (async, varias
      // queries) y un solo refresh fijo podía correr antes de que existiera (review M11 #3).
      if (isCreate && window.MicosStore && window.MicosStore.refresh) {
        let intentos = 0;
        const buscarAjuste = () => {
          intentos++;
          window.MicosStore.refresh('ajustesEntrega').then(() => {
            bumpAjustes();
            const hay = (window.AJUSTES_ENTREGA || []).some((a) =>
              (a.remitoUuid && a.remitoUuid === original.id) ||
              (a.remitoId && a.remitoId === `REM-${docObj.numero}`));
            if (!hay && intentos < 4) setTimeout(buscarAjuste, 800 * intentos);
          }).catch(() => { if (intentos < 4) setTimeout(buscarAjuste, 800 * intentos); });
        };
        setTimeout(buscarAjuste, 700);
      }
      setToast(`Remito ${docObj.numero} ${isCreate ? 'creado' : 'guardado'}`);
      setTimeout(() => setToast(null), 3600);
    },
  });

  const rem = editing && draft ? draft : original;
  // DECISIÓN 4: cliente = override de ESTE remito (rem.entidadId) o el del expediente (de
  // siempre) — resolveClienteDocumento (compartido.jsx) compartida con presupuesto/OC.
  const cliente = resolveClienteDocumento(exp, rem.entidadId);

  const patchFacturaItem = (idx, field, value) => setDraft((d) => {
    const itemsFactura = d.itemsFactura.map((it, i) => {
      if (i !== idx) return it;
      const next = { ...it, [field]: value };
      const c = Number(next.cantidad) || 0, u = Number(next.unitario) || 0, b = Number(next.bonifPct) || 0;
      next.total = c * u * (1 - b / 100);
      return next;
    });
    return { ...d, itemsFactura };
  });
  const addFacturaItem = () => setDraft((d) => ({ ...d, itemsFactura: [...d.itemsFactura, window.MicosItemsMath.blank()] }));
  const removeFacturaItem = (idx) => setDraft((d) => ({ ...d, itemsFactura: d.itemsFactura.filter((_, i) => i !== idx) }));

  const patchRealItem = (idx, field, value) => setDraft((d) => {
    const itemsReal = d.itemsReal.map((it, i) => {
      if (i !== idx) return it;
      const next = { ...it, [field]: value };
      const c = Number(next.cantidad) || 0, u = Number(next.unitario) || 0, b = Number(next.bonifPct) || 0;
      next.total = c * u * (1 - b / 100);
      return next;
    });
    return { ...d, itemsReal };
  });
  const addRealItem = () => setDraft((d) => ({ ...d, itemsReal: [...d.itemsReal, window.MicosItemsMath.blank()] }));
  const removeRealItem = (idx) => setDraft((d) => ({ ...d, itemsReal: d.itemsReal.filter((_, i) => i !== idx) }));

  // Totals reales (modelo único)
  const finReal = window.MicosItemsMath.summary(rem.itemsReal);
  const netoGravado = finReal.totalBase;
  const bonifTotal = finReal.bonifTotal;
  const ivaLines = finReal.ivaLines;
  const totalReal = finReal.total;

  // Totals facturados (mismo cálculo, sobre itemsFactura enriquecidos)
  const finFac = window.MicosItemsMath.summary(rem.itemsFactura);
  const facIvaLines = finFac.ivaLines;
  const totalFactura = finFac.total;

  const onPrint = () => {
    const fresh = resolveDocExp(expediente);
    const doc = fresh.remito || original;
    const data = window.MicosDocRemito.fromExpediente(fresh, co, {
      ...doc,
      items: (rem.itemsReal || []).map((it) => ({ cantidad: it.cantidad, codigo: it.sku || it.codigo, descripcion: it.descripcion })),
    });
    window.openPrintDoc(data, {
      mod: window.MicosDocRemito,
      // FIX (F7, cierre E2E): antes `doc.numero` crudo (bloque numérico sin prefijo) —
      // dropeaba el `L-`/`REM-` en el título del visor. `doc.publicId` es el id real (con o
      // sin `L-`); mismo criterio que Presupuesto (onPrint, fix P15) y que el bigId 20 líneas
      // abajo. Fallback al placeholder `REM-${numero}` solo para un alta sin fila real todavía.
      title: `Remito ${doc.publicId || `REM-${doc.numero}`}`.trim(),
      subtitle: `${fresh.publicId}${fresh.entidad?.razonSocial ? ' · ' + fresh.entidad.razonSocial : ''}`,
    });
  };
  // El remito va a Ajustes de inventario: no se imprime hasta aprobarse (match por uuid o public_id, con fallback al REM-numero viejo).
  const remitoAjuste = (window.AJUSTES_ENTREGA || []).find((a) =>
    (a.remitoUuid && original.id && a.remitoUuid === original.id) ||
    (a.remitoId && (a.remitoId === original.publicId || a.remitoId === `REM-${original.numero}`)));
  const remitoPrintBlocked = !!(remitoAjuste && remitoAjuste.aprobado === false);
  // Puente ERP→CRM (carril B-erp): "Enviar por mail" con este remito adjunto.
  // `doc` = publicId real (REM-…/L-REM-…, = código del remito en el CRM).
  const onEmail = window.buildDocEmailAction && window.buildDocEmailAction({
    tipo: 'Remito',
    docId: original.publicId || `REM-${original.numero}`,
    expPublicId: exp.publicId,
    fields: cliente.fields,
  });
  const actions = buildDocActions({ editing, enterEdit, discardEdit, saveEdit, onPrint, onEmail,
    printBlocked: remitoPrintBlocked,
    printBlockedTitle: 'No se puede imprimir hasta aprobar el ajuste en Ajustes de inventario' });

  return (
    <DocumentShell
      onBack={onBack}
      eyebrow="Remito"
      // Pill = estado PERSISTIDO real (remitos.estado: PENDIENTE/EN_TRANSITO/ENTREGADO/CONFIRMADO/
      // ANULADO), no un rótulo fijo. Fallback a 'Confirmado' solo si todavía no tiene estado.
      statusLabel={editing ? 'Editando' : (((window.REM_DOC_ESTADOS || {})[original.estado] || {}).label || original.estado || 'Confirmado')}
      statusPill="pill-remito"
      // FIX (P15, H2): publicId real (antes `REM-${numero}` dropeaba el `L-` legacy); fallback = placeholder de alta.
      bigId={original.publicId || `REM-${original.numero}`}
      expedienteId={exp.publicId}
      fechaEmision={rem.fechaCreacion}
      editing={editing}
      isCreate={isCreate}
      toast={toast}
      actions={actions}
    >
      <MedicalContextCard exp={exp} />

      <DocMetaStrip editing={editing} items={[
        { label: 'Número', value: original.publicId || `REM-${original.numero}`, mono: true, accent: true }, // idem bigId (H2)
        // P17a (desbloqueo general, recorrido §1): antes bloqueada tras emitir
        // (`locked: editing && !isCreate`) — no es numeración/fiscal/calculada,
        // así que se desbloquea como el resto de las fechas del documento.
        // FIX (review-lote.md, hallazgo MEDIO P17a): bindeada a `fechaCreacion` (columna real
        // `fecha_creacion`, ver comentario en useDocEdit arriba) — antes mapeaba a
        // `fechaEmision`, que no persistía.
        { label: 'Emisión', value: editing ? draft.fechaCreacion : formatDate(original.fechaCreacion), mono: true, editable: editing, inputType: 'date', onChange: (v) => patch('fechaCreacion', v) },
        { label: 'Validez hasta', value: editing ? draft.fechaValidez : formatDate(rem.fechaValidez), mono: true, editable: editing, inputType: 'date', onChange: (v) => patch('fechaValidez', v) },
        { label: 'Expediente', value: exp.publicId, mono: true, accent: true },
        // FIX (hallazgo ALTA #7): en modo lectura mostraban SIEMPRE el vendedor/condición de
        // venta del expediente, ignorando lo persistido en el propio remito (`original.*`) —
        // aunque el PATCH ya hubiera guardado el valor, la pantalla nunca lo mostraba de
        // vuelta. `original.*` (lo guardado en este documento) gana; el dato del expediente
        // queda como fallback para un remito que todavía no tiene ese campo cargado.
        { label: 'Vendedor', value: editing ? draft.vendedor : (original.vendedor || exp.vendedor?.name || 'Sin vendedor'), editable: editing, onChange: (v) => patch('vendedor', v) },
        { label: 'Vendedor auxiliar', value: editing ? draft.vendedorAux : (original.vendedorAux || exp.vendedorAux?.name || '—'), editable: editing, onChange: (v) => patch('vendedorAux', v) },
        { label: 'Forma de pago', value: editing ? draft.formaPago : (original.formaPago || exp.entidad?.condicionVenta || 'Cuenta corriente — 30 días'), editable: editing, onChange: (v) => patch('formaPago', v) },
        // FIX (hallazgo "Moneda"): modo lectura mostraba SIEMPRE 'Pesos argentinos' fijo,
        // ignorando lo persistido — mismo criterio que Vendedor/Forma de pago arriba.
        { label: 'Moneda', value: editing ? draft.moneda : (original.moneda || 'Pesos argentinos'), editable: editing, inputType: 'select', options: ['Pesos argentinos', 'Dólares (USD)', 'Euros (EUR)'], onChange: (v) => patch('moneda', v) },
      ]} />

      <DocCard>
        <div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
          <PartyBlock
            eyebrow="Emisor"
            name={co.nombre}
            sub={co.situacionIva}
            fields={buildEmisorFields(co)}
          />
          <PartyBlock
            eyebrow="Cliente"
            name={cliente.nombre}
            sub={cliente.sub}
            fields={cliente.fields}
            onEdit={editing ? () => setClientePicker(true) : undefined}
            editLabel="Cambiar cliente"
          />
        </div>
      </DocCard>

      {editing && clientePicker && window.PartySelectorModal && (
        <window.PartySelectorModal
          type="entidad"
          open={true}
          onClose={() => setClientePicker(false)}
          onPick={(obj) => {
            if (obj && obj.id) patch('entidadId', obj.id);
            setClientePicker(false);
          }}
        />
      )}

      {/* Items Factura — heredados del Presupuesto / OC, editables en modo edición */}
      <DocCard editing={editing}>
        <div className="flex items-center justify-between mb-5">
          <p className="text-[11px] font-bold uppercase tracking-[0.2em]" style={{ color: 'var(--accent)' }}>
            Ítems facturados
          </p>
          <p className="text-[11.5px] font-bold uppercase tracking-[0.1em]" style={{ color: 'var(--muted-foreground)' }}>
            {rem.itemsFactura.length} ítems
          </p>
        </div>
        <ItemsTable
          items={rem.itemsFactura}
          showGanancia
          showBonif
          showIva
          editing={editing}
          onItemChange={patchFacturaItem}
          onItemRemove={removeFacturaItem}
          onAdd={addFacturaItem}
        />
        <Totals
          subtotal={finFac.totalBase}
          bonificaciones={finFac.bonifTotal}
          ivaLines={facIvaLines}
          total={totalFactura}
        />
      </DocCard>

      {/* Items Real (con costos) */}
      <DocCard editing={editing}>
        <div className="flex items-center justify-between mb-5">
          <p className="text-[11px] font-bold uppercase tracking-[0.2em]" style={{ color: 'var(--accent)' }}>
            Detalle real entregado
          </p>
          <p className="text-[11.5px] font-bold uppercase tracking-[0.1em]" style={{ color: 'var(--muted-foreground)' }}>
            {rem.itemsReal.length} ítems
          </p>
        </div>
        <ItemsTable
          items={rem.itemsReal}
          showGanancia
          showBonif
          showIva
          editing={editing}
          onItemChange={patchRealItem}
          onItemRemove={removeRealItem}
          onAdd={addRealItem}
        />
        <Totals
          subtotal={netoGravado}
          bonificaciones={bonifTotal}
          ivaLines={ivaLines}
          total={totalReal}
        />
      </DocCard>

      {/* Observaciones + datos del remito (Aclaración / CAI / Vto CAI) */}
      <ObservacionesRemitoCard
        editing={editing}
        observaciones={editing ? draft.observaciones : original.observaciones}
        onObservacionesChange={(v) => patch('observaciones', v)}
        cai={editing ? draft.cai : original.cai}
        onCaiChange={(v) => patch('cai', v)}
        caiFechaVenc={editing ? draft.caiFechaVenc : original.caiFechaVenc}
        onCaiFechaVencChange={(v) => patch('caiFechaVenc', v)}
        aclaracion={editing ? draft.aclaracion : original.aclaracion}
        onAclaracionChange={(v) => patch('aclaracion', v)}
      />
    </DocumentShell>
  );
}

Object.assign(window, { RemitoScreen });
