// ─── Buscador global del navbar (P21) ────────────────────────────────────
// GlobalSearch: reemplaza el botón decorativo que tenía el Header (ui/shell.jsx)
// — sin estado, sin onClick, solo un ícono + texto fijo "Buscar expedientes,
// pacientes…" (ver diagnóstico completo en paquetes/p21-reporte.md). Ahora es
// un input real: tipear dispara `window.MicosGlobalSearch(query)` (dominio/
// busqueda.js, lógica pura sobre las colecciones hidratadas) y arma un
// desplegable de resultados agrupados por tipo; click navega con el router
// real vía `onOpen(result.nav)` (implementado en core/app.jsx,
// `navigateSearchResult` — el único lugar que interpreta el campo `nav`).
//
// Combobox compartido (arbitraje, ver "Notas de merge" en el reporte): NO se
// reusa `InventoryCombobox` (ui/doc-kit-items.jsx, P17b lo está mejorando en
// paralelo) tal cual — está acoplado a `window.INVENTARIO` y a
// `onPick(producto)`, no sirve para resultados multi-colección agrupados. Lo
// que SÍ se reusa, sin tocarlo, es el patrón visual del popover compartido:
// las clases `.inv-pop`/`.inv-pop__head`/`.inv-pop__row` de assets/styles.css
// (portal fixed, header en mayúsculas, fila con hover) — mismo look & feel
// que el selector de ítems del punto 4 del recorrido. El ancho doble y el
// wrap del título los implementa ESTE archivo directo (no dependen del merge
// de P17b: ese cambio vive adentro de InventoryCombobox como JS inline, no
// como regla CSS reusable — ver nota de merge para el detalle).
//
// Atajo ⌘K/Ctrl+K enfoca el input (la promesa que ya tenía el título del botón
// viejo, "Buscar (⌘K)", nunca estaba conectada a nada).
// Expone a window: GlobalSearch. Consume MicosGlobalSearch (dominio/busqueda.js),
// IconSearch/IconX (ui/icons.jsx). Se usa desde Header (ui/shell.jsx).

function GlobalSearch({ onOpen }) {
  const [query, setQuery] = React.useState('');
  const [open, setOpen] = React.useState(false);
  const [mobileOpen, setMobileOpen] = React.useState(false);
  const [rect, setRect] = React.useState(null);
  const wrapRef = React.useRef(null);
  const inputRef = React.useRef(null); // input MÓVIL (md:hidden)
  const desktopInputRef = React.useRef(null); // input DESKTOP (hidden md:flex)

  const groups = React.useMemo(() => (window.MicosGlobalSearch ? window.MicosGlobalSearch(query) : []), [query]);
  const totalResults = groups.reduce((n, g) => n + g.items.length, 0);

  const place = () => { if (wrapRef.current) setRect(wrapRef.current.getBoundingClientRect()); };

  React.useEffect(() => {
    if (!open) return;
    place();
    const onScroll = (e) => {
      if (e.target && e.target.closest && e.target.closest('.inv-pop')) return;
      place();
    };
    const onResize = () => place();
    const onDoc = (e) => {
      const inPop = e.target.closest && e.target.closest('.inv-pop');
      if (wrapRef.current && !wrapRef.current.contains(e.target) && !inPop) setOpen(false);
    };
    window.addEventListener('scroll', onScroll, true);
    window.addEventListener('resize', onResize);
    document.addEventListener('mousedown', onDoc);
    return () => {
      window.removeEventListener('scroll', onScroll, true);
      window.removeEventListener('resize', onResize);
      document.removeEventListener('mousedown', onDoc);
    };
  }, [open]);

  // ⌘K / Ctrl+K enfoca el buscador desde cualquier pantalla; Escape lo cierra.
  //
  // FIX (hallazgo auditoría 05/07/2026, "⌘K del buscador global roto en DESKTOP"): antes
  // esto SIEMPRE hacía `setMobileOpen(true)` + enfocaba `inputRef` (el input MÓVIL, oculto
  // por CSS `md:hidden` en desktop) — en una pantalla ≥768px (breakpoint `md` de Tailwind)
  // el atajo no hacía nada visible: el input real que el usuario ve (`desktopInputRef`,
  // `hidden md:flex`) nunca recibía foco. `matchMedia` decide cuál de los dos inputs es el
  // visible en ESTE momento (ambos existen siempre en el DOM, la visibilidad es puro CSS) y
  // solo abre/enfoca ese.
  React.useEffect(() => {
    const onKey = (e) => {
      if ((e.metaKey || e.ctrlKey) && (e.key === 'k' || e.key === 'K')) {
        e.preventDefault();
        const esDesktop = window.matchMedia && window.matchMedia('(min-width: 768px)').matches;
        if (esDesktop) {
          setOpen(true);
          setTimeout(() => desktopInputRef.current && desktopInputRef.current.focus(), 0);
        } else {
          setMobileOpen(true);
          setTimeout(() => inputRef.current && inputRef.current.focus(), 0);
        }
      } else if (e.key === 'Escape') {
        setOpen(false);
      }
    };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, []);

  const pick = (result) => {
    onOpen && onOpen(result.nav);
    setOpen(false);
    setQuery('');
    setMobileOpen(false);
  };

  const pop = (open && rect) ? ReactDOM.createPortal(
    <div className="inv-pop" style={{ top: rect.bottom + 6, left: rect.left, width: Math.max(rect.width, 460), maxHeight: 420 }}>
      {query.trim().length < 2 ? (
        <p className="inv-pop__head" style={{ padding: '10px 12px' }}>Escribí al menos 2 caracteres…</p>
      ) : totalResults === 0 ? (
        <p className="inv-pop__head" style={{ padding: '10px 12px' }}>Sin resultados para «{query}»</p>
      ) : groups.map((g) => {
        const GIcon = window[g.icon] || null;
        return (
          <div key={g.tipo}>
            <p className="inv-pop__head">{g.tipo}</p>
            {g.items.map((r) => (
              <button
                key={`${g.tipo}-${r.id}`}
                type="button"
                className="inv-pop__row"
                style={{ gridTemplateColumns: '30px minmax(0,1fr) auto' }}
                onMouseDown={(e) => { e.preventDefault(); pick(r); }}>
                <span className="inline-flex items-center justify-center rounded-lg flex-shrink-0"
                  style={{ width: 26, height: 26, background: 'color-mix(in oklab, var(--accent) 14%, transparent)', color: 'var(--accent)' }}>
                  {GIcon ? <GIcon size={13} /> : null}
                </span>
                <span className="min-w-0">
                  <span className="block text-[13px] font-bold" style={{ color: 'var(--foreground)', whiteSpace: 'normal', wordBreak: 'break-word' }}>{r.titulo}</span>
                  <span className="block text-[11.5px]" style={{ color: 'var(--muted-foreground)', whiteSpace: 'normal', wordBreak: 'break-word' }}>{r.subtitulo}</span>
                </span>
                <IconChevronRight size={14} style={{ color: 'var(--muted-foreground)' }} />
              </button>
            ))}
          </div>
        );
      })}
    </div>, document.body) : null;

  return (
    <div ref={wrapRef} style={{ position: 'relative' }}>
      {/* Desktop: input real (antes era un <button> decorativo sin handler) */}
      <div
        className="hidden md:flex items-center gap-2.5 h-9 pl-3 pr-2 rounded-xl transition-all"
        style={{ background: 'var(--card)', border: '1px solid var(--border)', width: 'clamp(180px, 22vw, 280px)' }}
        onMouseEnter={(e) => { e.currentTarget.style.borderColor = 'color-mix(in oklab, var(--accent) 35%, var(--border))'; }}
        onMouseLeave={(e) => { e.currentTarget.style.borderColor = 'var(--border)'; }}>
        <IconSearch size={14} style={{ color: 'var(--muted-foreground)', flexShrink: 0 }} />
        <input
          ref={desktopInputRef}
          value={query}
          onChange={(e) => { setQuery(e.target.value); setOpen(true); }}
          onFocus={() => setOpen(true)}
          placeholder="Buscar expedientes, facturas, médicos…"
          title="Buscar (⌘K)"
          className="text-[12.5px] font-medium flex-1 min-w-0 bg-transparent outline-none"
          style={{ color: 'var(--foreground)' }}
        />
      </div>

      {/* Mobile: ícono que expande el mismo input+dropdown (antes era otro botón decorativo) */}
      <button
        className="btn btn-icon md:hidden"
        style={{ background: 'var(--card)', color: 'var(--muted-foreground)', border: '1px solid var(--border)' }}
        title="Buscar"
        onClick={() => { setMobileOpen((v) => !v); setTimeout(() => inputRef.current && inputRef.current.focus(), 0); }}>
        <IconSearch size={16} />
      </button>
      {mobileOpen && (
        <div className="md:hidden flex items-center gap-2 h-9 px-3 rounded-xl absolute right-0 top-0"
          style={{ background: 'var(--card)', border: '1px solid var(--border)', width: '70vw', zIndex: 20 }}>
          <IconSearch size={14} style={{ color: 'var(--muted-foreground)', flexShrink: 0 }} />
          <input
            ref={inputRef}
            value={query}
            onChange={(e) => { setQuery(e.target.value); setOpen(true); }}
            onFocus={() => setOpen(true)}
            placeholder="Buscar…"
            className="text-[12.5px] font-medium flex-1 min-w-0 bg-transparent outline-none"
            style={{ color: 'var(--foreground)' }}
          />
          <button type="button" onClick={() => { setMobileOpen(false); setOpen(false); setQuery(''); }} style={{ color: 'var(--muted-foreground)' }}>
            <IconX size={14} />
          </button>
        </div>
      )}
      {pop}
    </div>
  );
}

Object.assign(window, { GlobalSearch });
