// ─── Documentos del expediente: glue compartido ──────────────────────────
// Lo común y chico entre las 7 pantallas de documento del expediente
// (presupuesto/orden-compra/remito/factura/recibo/doc-medica/doc-extra, todas en
// screens/docs/ desde P7): resolveDocExp (resuelve el expediente real que cada
// pantalla necesita para renderizar) y DocSubrouteGate (la compuerta de carga
// del detalle antes de montar la pantalla — ver su header) y resolveClienteDocumento
// (DECISIÓN 4, 06/07/2026 — resuelve el PartyBlock "Cliente/Comprador" con el override de
// entidad del lápiz, ver su propio comentario). El resto de lo que antes vivía en
// screens-docs.jsx como "librería compartida" ya se había extraído: el motor de documento
// editable a ui/doc-kit-*.jsx (P4) y el hub de persistencia/dominio a dominio/
// expediente-docs.js (P5). Expone a window: resolveDocExp, resolveClienteDocumento,
// DocSubrouteGate, DocLoadingState. Consume window.MicosResolveExpedienteDocs/
// MicosMergeDetalleRico (dominio/expediente-docs.js), buildClienteFields (ui/doc-kit-
// shell.jsx), ENTIDADES (core/colecciones.js), IconArrowLeft (ui/icons.jsx).

// Resuelve el expediente para renderizar: hidrata los documentos desde las
// colecciones por referencia/FK (MicosResolveExpedienteDocs). P6: murió el
// dual-path EXPEDIENTE_DETAIL/"Sofía" — mismo camino para TODO expediente.
function resolveDocExp(expediente) {
  const base = expediente || {};
  return window.MicosResolveExpedienteDocs ? window.MicosResolveExpedienteDocs(base) : base;
}

// DECISIÓN 4 (paquete de decisiones, 06/07/2026) — lápiz "Cambiar cliente/comprador": resuelve
// el bloque PartyBlock del cliente de UN documento del pipeline — el override elegido con el
// lápiz (`entidadIdOverride`, persistido en la columna `entidad_id` propia del documento:
// presupuestos/ordenes_compra/remitos) si existe, si no el particular/entidad del EXPEDIENTE
// (comportamiento de siempre, sin cambios). Compartida por presupuesto.jsx/orden-compra.jsx/
// remito.jsx (los 3 con este lápiz) para no triplicar la misma resolución — factura/recibo
// standalone tienen su PROPIO mecanismo (cliente embebido en el documento, sin FK al
// directorio; ver screens/finanzas/factura.jsx) y no la usan. `buildClienteFields` (ui/doc-
// kit-shell.jsx) ya sabe resolver por `entidadId` contra el directorio — se le pasa un
// objeto liviano con solo esa key en vez de duplicar esa lógica acá.
function resolveClienteDocumento(exp, entidadIdOverride) {
  const entidad = entidadIdOverride ? (window.ENTIDADES || []).find((e) => e.id === entidadIdOverride) : null;
  if (entidad) {
    return {
      nombre: entidad.razonSocial,
      sub: entidad.condicionIva || 'Responsable Inscripto',
      fields: window.buildClienteFields({ entidadId: entidadIdOverride }),
    };
  }
  return {
    nombre: exp.entidad?.razonSocial || (exp.particular?.nombre ? `${exp.particular.nombre} ${exp.particular.apellido || ''}`.trim() : '—'),
    sub: exp.entidad?.condicionIva || 'Consumidor Final',
    fields: window.buildClienteFields(exp),
  };
}

// ─── Compuerta de carga del sub-documento (fix bug transversal F5-subruta) ──
// Al recargar (F5) parado en una sub-ruta de documento del expediente, la app
// arranca SIN el detalle rico: los documentos (presupuesto/OC/remito/factura/
// recibo/archivos) se mergean a las colecciones globales SOLO cuando alguien
// pide /api/expedientes/detail — y ese fetch vivía únicamente en
// ExpedienteDetailScreen (screens/expedientes/detalle.jsx), que en un F5 directo
// a la sub-ruta NUNCA se monta. Sin ese merge, MicosResolveExpedienteDocs no
// encuentra el documento real (más aún si cae fuera de la ventana BIG_LIMIT=500
// de la hidratación) → la pantalla arranca en modo ALTA con defaults (public_id
// nuevo, moneda default): useDocEdit fija startEditing=isCreate en el PRIMER
// montaje y ya no se corrige aunque después lleguen los datos. Resultado: un
// usuario que refresca ve un documento NUEVO en blanco en vez del suyo.
//
// DocSubrouteGate resuelve la raíz: pide el detalle (mismo fetch-and-merge que
// ExpedienteDetailScreen) ANTES de montar la pantalla, y mientras tanto muestra
// un estado de carga honesto. Recién con los documentos ya mergeados monta la
// pantalla — así useDocEdit decide isCreate sobre datos reales. El expediente ya
// llega resuelto por el router (core/router.jsx reconstruye selectedExpediente
// desde el publicId de la URL de la sub-ruta). `window.__micosDetalleCargado`
// (Set por carga de página) evita re-pedir el detalle y el parpadeo de carga en
// la navegación normal (detalle → documento): ExpedienteDetailScreen marca ahí
// el expediente al mergear su detalle, así la compuerta lo ve listo y monta
// directo, sin fetch ni loading.
const _GATE_UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;

function DocLoadingState({ onBack, backLabel = 'Volver al expediente' }) {
  return (
    <div className="space-y-7 pt-2">
      <button onClick={onBack}
        className="flex items-center gap-2 text-[11px] font-bold uppercase tracking-[0.12em] cursor-pointer transition-colors animate-fade-in-up"
        style={{ color: 'var(--muted-foreground)' }}>
        <IconArrowLeft size={13} />
        {backLabel}
      </button>
      <div className="rounded-2xl bg-card p-12 flex flex-col items-center justify-center gap-4 animate-fade-in-up"
        style={{ border: '1px solid color-mix(in oklab, var(--border) 55%, transparent)', boxShadow: 'var(--shadow-card)' }}>
        <span className="ai-spin" style={{ color: 'var(--accent)', display: 'inline-flex' }}>
          <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
            <line x1="12" y1="2" x2="12" y2="6" /><line x1="12" y1="18" x2="12" y2="22" /><line x1="4.9" y1="4.9" x2="7.8" y2="7.8" /><line x1="16.2" y1="16.2" x2="19.1" y2="19.1" /><line x1="2" y1="12" x2="6" y2="12" /><line x1="18" y1="12" x2="22" y2="12" /><line x1="4.9" y1="19.1" x2="7.8" y2="16.2" /><line x1="16.2" y1="7.8" x2="19.1" y2="4.9" />
          </svg>
        </span>
        <p className="text-[13.5px] font-bold" style={{ color: 'var(--muted-foreground)' }}>
          Cargando el documento…
        </p>
      </div>
    </div>
  );
}

function DocSubrouteGate({ expediente, onBack, children }) {
  const expId = expediente && expediente.id;
  const isRealId = !!expId && _GATE_UUID_RE.test(String(expId));
  const cargados = window.__micosDetalleCargado || (window.__micosDetalleCargado = new Set());
  // deepLink: se llegó por F5/deep-link DIRECTO a la sub-ruta (el detalle no estaba
  // cargado al montar). Ahí el documento abre en EDICIÓN con los datos reales ya
  // mergeados — así el valor guardado queda visible en los controles del form (el
  // <select> Moneda, las fechas, etc.) en vez de un alta en blanco, y es lo que hace
  // verificable la persistencia post-F5. En navegación normal (detalle → documento)
  // el detalle YA está cargado (ExpedienteDetailScreen lo marcó) → deepLink false →
  // abre en modo lectura, como siempre. Se congela al montar (ref): el fetch del
  // efecto marca `cargados` después, pero deepLink debe reflejar el estado inicial.
  const deepLinkRef = React.useRef(null);
  if (deepLinkRef.current === null) deepLinkRef.current = isRealId && !cargados.has(expId);
  const deepLink = deepLinkRef.current;
  // Listo desde el montaje si no hay id real que cargar (fallback sin expediente)
  // o si el detalle de este expediente YA se mergeó en esta carga de página.
  const [ready, setReady] = React.useState(!isRealId || cargados.has(expId));
  React.useEffect(() => {
    if (!isRealId || cargados.has(expId)) { setReady(true); return undefined; }
    let cancelled = false;
    setReady(false);
    fetch('/api/expedientes/detail?id=' + encodeURIComponent(expId), { credentials: 'same-origin' })
      .then((r) => (r.ok ? r.json() : Promise.reject(r.status)))
      .then((rich) => { if (!cancelled && rich && rich.id && window.MicosMergeDetalleRico) window.MicosMergeDetalleRico(rich); })
      .catch((err) => console.warn('[DocSubrouteGate] detalle rico', expId, err))
      .finally(() => { if (cancelled) return; cargados.add(expId); setReady(true); });
    return () => { cancelled = true; };
  }, [expId, isRealId]);
  if (!ready) return <DocLoadingState onBack={onBack} />;
  // Inyecta `startEditing` (solo lo consumen las pantallas de documento del pipeline
  // vía useDocEdit; las que no lo leen —doc médica/extra— lo ignoran sin efecto).
  return React.cloneElement(children, { startEditing: deepLink });
}

Object.assign(window, { resolveDocExp, resolveClienteDocumento, DocSubrouteGate, DocLoadingState });
