// ─── Directorio — componentes compartidos (dir-kit) ──────
// Layout compartido por las 4 fichas de detalle del Directorio (Entidad/
// Médico/Particular/Proveedor): DirCard (tarjeta con eyebrow), DirFieldGrid
// (grilla label/value), DirHeader (back+título+status+avatar+acciones),
// DirRegistros (tarjetas clickeables de KPIs relacionados), DirChip,
// DirNotas, DirContactoRow, y el helper dirCalcAge. git mv tal cual desde
// public/erp/screens-directorio-shared.jsx (P4, el mapa lo da limpio — sin
// código muerto). Expone a window: dirCalcAge, DirCard, DirFieldGrid,
// DirHeader, DirRegistros, DirChip, DirNotas, DirContactoRow, dirExportRegistro,
// DirToast. Consume window.DocCard (ui/doc-kit-shell.jsx), window.TablePill/
// window.MicosExport (print/export-xlsx.js), Icon* (ui/icons.jsx).
//
// FIX F3/directorio (AUDITORIA-ui-decorativa-05-07-2026.md): DirNotas pasa a
// disabled-honesto (sin ruta de escritura real) y suma `dirExportRegistro`/
// `DirToast`, el enganche real del botón "Exportar" de las 4 fichas de detalle
// (ver comentario junto a cada función más abajo).
//
// DECISIÓN 1 (ARBITRAJES.md ítem 1, 06/07/2026 — CRUD real de los sub-recursos del
// directorio): `DirContactoRow` pierde la columna "Área" (nunca fue una columna real de
// `entidad_contacto` — el fix de raíz saca el campo decorativo en vez de mostrarlo siempre
// vacío, CLAUDE.md decisión estructural #3) y suma el prop opcional `actions` (par
// lápiz+tacho del renglón). El motor de alta/edición de los sub-recursos
// (`DirSubResourceModal`/`DirRowActions`) se partió a `ui/dir-subresource-modal.jsx` — tema
// aparte (CRUD modal) del layout de fichas de este archivo, este archivo ya rondaba el techo
// (AGENTS.md: "un archivo = un tema", partir por tema al superar el techo).

const { useState: _useStateDir } = React;

// ─── Helper: edad desde ISO ─────────────────────────
function dirCalcAge(birthIso) {
  if (!birthIso) return null;
  const birth = new Date(birthIso);
  const today = new Date();
  let age = today.getFullYear() - birth.getFullYear();
  const m = today.getMonth() - birth.getMonth();
  if (m < 0 || (m === 0 && today.getDate() < birth.getDate())) age--;
  return age;
}

// ─── Sectioned card with eyebrow + optional action ──
function DirCard({ eyebrow, action, children }) {
  return (
    <DocCard className="p-7 sm:p-8">
      <div className="flex items-center justify-between mb-6 gap-4 flex-wrap">
        <p className="text-[11px] font-bold uppercase tracking-[0.2em]" style={{ color: 'var(--accent)' }}>
          {eyebrow}
        </p>
        {action}
      </div>
      {children}
    </DocCard>
  );
}

// ─── Field grid (label/value) ───────────────────────
function DirFieldGrid({ fields, cols = 4 }) {
  const colsCls = cols === 3
    ? 'grid grid-cols-2 sm:grid-cols-3 gap-x-8 gap-y-6'
    : 'grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 gap-x-8 gap-y-6';
  return (
    <div className={colsCls}>
      {fields.map((f, i) => (
        <div key={i} className="space-y-2 min-w-0">
          <p className="text-[10.5px] font-bold uppercase tracking-[0.14em]" style={{ color: 'var(--muted-foreground)' }}>
            {f.label}
          </p>
          {f.pill ? (
            <TablePill label={f.value} tone={f.pillTone || 'neutral'} />
          ) : (
            <p className={`text-[15.5px] font-extrabold leading-snug${f.mono ? ' font-mono tabular-nums' : ''}`}
              style={{
                color: f.accent ? 'var(--accent)' :
                       f.muted ? 'color-mix(in oklab, var(--muted-foreground) 70%, transparent)' : 'var(--foreground)',
                wordBreak: 'break-word',
              }}>
              {f.value || '—'}
            </p>
          )}
        </div>
      ))}
    </div>
  );
}

// ─── Detail header (back + title + status + actions) ─
// Matches reference pattern (Expedientes): back link as its own row above,
// then eyebrow + status pill row, big title, subtitle. Supports an avatar
// rendered next to the title block.
function DirHeader({ backLabel, onBack, eyebrow, title, subtitle, statusLabel, statusTone, avatar, actions }) {
  return (
    <React.Fragment>
      <button onClick={onBack}
        className="back-link 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)' }}
        onMouseEnter={e => e.currentTarget.style.color = 'var(--accent)'}
        onMouseLeave={e => e.currentTarget.style.color = 'var(--muted-foreground)'}>
        <IconArrowLeft size={13} />
        {backLabel}
      </button>
      <div className="flex flex-wrap items-start justify-between gap-4 animate-fade-in-up" style={{ animationDelay: '40ms' }}>
        <div className="flex items-start gap-5 min-w-0">
          {avatar}
          <div className="space-y-3 min-w-0">
            <div className="flex items-center gap-3 flex-wrap">
              {eyebrow && (
                <span className="text-[11px] font-bold uppercase tracking-[0.18em]" style={{ color: 'var(--accent)' }}>
                  {eyebrow}
                </span>
              )}
              {statusLabel && <TablePill label={statusLabel} tone={statusTone} />}
            </div>
            <h1 className="text-[clamp(28px,4.2vw,40px)] leading-[1.05] font-extrabold tracking-[-0.02em]"
              style={{ color: 'var(--foreground)' }}>{title}</h1>
            {subtitle && (
              <p className="text-[13.5px] font-medium" style={{ color: 'var(--muted-foreground)' }}>{subtitle}</p>
            )}
          </div>
        </div>
        {actions && (
          <div className="flex items-center gap-2 flex-shrink-0 flex-wrap">{actions}</div>
        )}
      </div>
    </React.Fragment>
  );
}

// ─── Registros asociados (clickable cards grid) ─────
function DirRegistros({ items }) {
  return (
    <div className={`grid grid-cols-2 ${items.length === 1 ? 'lg:grid-cols-1 max-w-md' : items.length === 2 ? 'lg:grid-cols-2' : 'lg:grid-cols-4'} gap-3`}>
      {items.map((it, i) => (
        <button key={i} onClick={it.onClick}
          className="text-left rounded-2xl p-5 transition-all duration-200"
          style={{
            background: 'var(--card)',
            border: '1px solid color-mix(in oklab, var(--border) 55%, transparent)',
            boxShadow: 'var(--shadow-card)',
          }}
          onMouseEnter={e => {
            e.currentTarget.style.transform = 'translateY(-2px)';
            e.currentTarget.style.boxShadow = 'var(--shadow-card-hover), var(--shadow-accent-soft)';
            e.currentTarget.style.borderColor = 'color-mix(in oklab, var(--accent) 40%, var(--border))';
          }}
          onMouseLeave={e => {
            e.currentTarget.style.transform = '';
            e.currentTarget.style.boxShadow = 'var(--shadow-card)';
            e.currentTarget.style.borderColor = 'color-mix(in oklab, var(--border) 55%, transparent)';
          }}>
          <div className="flex items-center justify-between mb-3">
            <div className="flex h-9 w-9 items-center justify-center rounded-lg"
              style={{ background: 'color-mix(in oklab, var(--accent) 12%, transparent)', color: 'var(--accent)' }}>
              {it.icon}
            </div>
            <IconArrowUpRight size={14} style={{ color: 'var(--muted-foreground)' }} />
          </div>
          <p className="text-[10.5px] font-bold uppercase tracking-[0.14em]" style={{ color: 'var(--muted-foreground)' }}>
            {it.label}
          </p>
          <div className="flex items-baseline gap-2 mt-1.5">
            <p className="text-[24px] font-extrabold tabular-nums leading-none" style={{ color: 'var(--foreground)' }}>
              {it.value}
            </p>
            {it.sublabel && (
              <p className="text-[11px] font-bold" style={{ color: 'var(--muted-foreground)' }}>{it.sublabel}</p>
            )}
          </div>
        </button>
      ))}
    </div>
  );
}

// ─── Chip button (clickable) ─────────────────────────
function DirChip({ label, sub, onClick, tone = 'neutral' }) {
  const TONES = {
    neutral: { bg: 'color-mix(in oklab, var(--muted-foreground) 8%, transparent)',  fg: 'var(--foreground)',         border: 'color-mix(in oklab, var(--border) 70%, transparent)' },
    accent:  { bg: 'color-mix(in oklab, var(--accent) 10%, transparent)',           fg: 'var(--accent)',             border: 'color-mix(in oklab, var(--accent) 30%, transparent)' },
    muted:   { bg: 'transparent',                                                   fg: 'var(--muted-foreground)',  border: 'color-mix(in oklab, var(--border) 55%, transparent)' },
  };
  const t = TONES[tone] || TONES.neutral;
  return (
    <button onClick={onClick}
      className="inline-flex items-center gap-2 px-3.5 py-2 rounded-full text-[12.5px] font-bold transition-all duration-200"
      style={{ background: t.bg, color: t.fg, border: `1px solid ${t.border}`, cursor: onClick ? 'pointer' : 'default' }}
      onMouseEnter={e => { if (onClick) { e.currentTarget.style.transform = 'translateY(-1px)'; e.currentTarget.style.boxShadow = '0 4px 12px -4px rgba(0,0,0,0.10)'; } }}
      onMouseLeave={e => { if (onClick) { e.currentTarget.style.transform = ''; e.currentTarget.style.boxShadow = 'none'; } }}>
      {label}
      {sub && <span className="opacity-60 text-[11px] font-medium">· {sub}</span>}
    </button>
  );
}

// ─── Notas card ──────────────────────────────────────
// DISABLED HONESTO (AUDITORIA-ui-decorativa-05-07-2026.md, MEDIA "Editar notas (las 3
// fichas)" + "lápiz Editar-notas de proveedor"; mismo doctrina que el botón de abajo,
// precedente P24 Lotes, extendido por el writer `directorio` de F3 con delegación de
// ARBITRAJES.md ítem 1): la columna `notas` solo existe en `medicos` (ninguna config de
// RECORD_FORMS la declara como campo editable) y NO existe en entidades/particulares —
// no hay ningún camino de escritura real para esta ficha, compartida por las 4 pantallas
// del Directorio. `disabled` dispara `.btn:disabled`/estilo gris plano (CLAUDE.md §2/§3);
// el `title` explica el porqué en vez de fingir que el lápiz hace algo al clickear.
function DirNotas({ notas }) {
  return (
    <DirCard eyebrow="Notas internas"
      action={
        <button disabled title="Editar notas — todavía no implementado (sin columna en entidades/particulares, sin campo de edición en medicos)" className="party-edit-btn">
          <IconPencil size={13} />
        </button>
      }>
      {notas
        ? <p className="text-[13.5px] leading-relaxed" style={{ color: 'var(--foreground)' }}>{notas}</p>
        : <p className="text-[13px] italic" style={{ color: 'var(--muted-foreground)' }}>Sin notas registradas.</p>
      }
    </DirCard>
  );
}

// ─── Export de un registro de detalle (Exportar del header de las 4 fichas) ───────────
// FIX AUDITORIA-ui-decorativa-05-07-2026.md MEDIA "Exportar de detalle (entidad/médico/
// particular)" + "Exportar de detalle de proveedor": el botón crudo de DirHeader.actions
// no tenía NINGÚN enganche (el `isExportAction` de ui/entity-list.jsx solo cablea el
// `secondaryAction` de la LISTA, nunca el botón del detalle — ver evidencia del hallazgo).
// Reusa `window.MicosExport.exportTable` (el MISMO helper plano que ya usa ExportModal,
// print/export-xlsx.js) para exportar el registro individual con los campos YA resueltos
// que cada detalle muestra (los mismos arrays {label,value} de sus DirFieldGrid) — sin
// tocar ui/entity-list.jsx (no es de este grupo) ni duplicar la generación de Excel/CSV.
function dirExportRegistro(filename, camposGrupos) {
  const campos = [].concat(...camposGrupos);
  const headers = campos.map((f) => f.label);
  const row = campos.map((f) => (f.value == null ? '' : f.value));
  let res = { format: 'xlsx' };
  if (window.MicosExport) res = window.MicosExport.exportTable(filename, headers, [row]) || res;
  return res;
}

// Toast mínimo (mismo look que el `listToast` de ui/entity-list.jsx) para confirmar el
// export de detalle — CLAUDE.md §7 (feedback visual siempre que se confirme una acción).
function DirToast({ message }) {
  if (!message) return null;
  return (
    <div className="fixed bottom-6 right-6 z-50 flex items-center gap-3 rounded-xl px-4 py-3 animate-fade-in-up"
      style={{ background: 'var(--card)', border: '1px solid color-mix(in oklab, var(--accent) 45%, transparent)', boxShadow: '0 18px 50px -14px rgba(8, 20, 24, 0.5)', maxWidth: 'min(92vw, 380px)' }}>
      <span className="inline-flex items-center justify-center rounded-lg flex-shrink-0"
        style={{ width: 30, height: 30, background: 'color-mix(in oklab, var(--accent) 16%, transparent)', color: 'var(--accent)' }}>
        <IconCheck size={16} />
      </span>
      <p className="text-[12.5px] font-bold truncate" style={{ color: 'var(--foreground)' }}>{message}</p>
    </div>
  );
}

// ─── Contactos list row ──────────────────────────────
// FIX DECISIÓN 1 (06/07/2026): la columna "Área" se saca — `entidad_contacto` (docker
// exec psql \d, 06/07/2026: id/entidad_id/nombre/rol/telefono/email/created_at/deleted_at)
// nunca tuvo esa columna, quedaba siempre vacía (mismo criterio que la KPI "Convenios" de
// la lista de Entidades, CLAUDE.md decisión estructural #3). `c.rol` (antes `c.cargo`,
// nombre decorativo sin columna real) pasa a mostrarse bajo el nombre, como antes.
// `actions` (opcional): DirRowActions del renglón — sin él, el row queda solo-lectura
// (compat con cualquier consumidor viejo que no pase acciones).
function DirContactoRow({ c, isLast, actions }) {
  return (
    <div className="grid items-center gap-4 px-4 py-3.5"
      style={{ gridTemplateColumns: actions ? '1.6fr 1.4fr 1fr auto' : '1.6fr 1.4fr 1fr', borderBottom: !isLast ? '1px solid color-mix(in oklab, var(--border) 40%, transparent)' : 'none' }}>
      <div className="min-w-0">
        <p className="text-[13px] font-bold truncate" style={{ color: 'var(--foreground)' }}>{c.nombre}</p>
        <p className="text-[11.5px] mt-0.5 truncate" style={{ color: 'var(--muted-foreground)' }}>{c.rol || '—'}</p>
      </div>
      <div className="min-w-0">
        <p className="text-[12px] font-mono tabular-nums truncate" style={{ color: 'var(--muted-foreground)' }}>{c.telefono || '—'}</p>
      </div>
      <div className="min-w-0">
        <p className="text-[12px] truncate" style={{ color: 'var(--muted-foreground)' }}>{c.email || '—'}</p>
      </div>
      {actions && <div className="flex-shrink-0">{actions}</div>}
    </div>
  );
}

Object.assign(window, {
  dirCalcAge, DirCard, DirFieldGrid, DirHeader, DirRegistros, DirChip, DirNotas, DirContactoRow,
  dirExportRegistro, DirToast,
});
