/* ============================================================
   F2 UI — Navigation library
   Tabs · Breadcrumb · Pagination · DropdownMenu · CommandPalette · Stepper
   ============================================================ */
(function () {
  const { Icon } = window.F2;
  const { useDismiss } = window.SB;

  /* ====================== Tabs ====================== */
  function Tabs({ tabs = [], value, onChange, variant = 'line', style = {} }) {
    const items = tabs.map((t) => (typeof t === 'string' ? { value: t, label: t } : t));
    const idx = Math.max(0, items.findIndex((t) => t.value === value));
    function onKey(e) {
      if (e.key === 'ArrowRight' || e.key === 'ArrowLeft') {
        e.preventDefault();
        const next = e.key === 'ArrowRight' ? Math.min(idx + 1, items.length - 1) : Math.max(idx - 1, 0);
        onChange && onChange(items[next].value);
      }
    }
    if (variant === 'pill') {
      return (
        <div role="tablist" onKeyDown={onKey} style={{ display: 'inline-flex', gap: 3, padding: 4, background: 'var(--f2-surface-sunken)', border: '1px solid var(--f2-border)', borderRadius: 'var(--f2-radius-control)', ...style }}>
          {items.map((t) => {
            const on = t.value === value;
            return (
              <button key={t.value} role="tab" aria-selected={on} tabIndex={on ? 0 : -1} onClick={() => onChange && onChange(t.value)}
                style={{ display: 'inline-flex', alignItems: 'center', gap: 7, padding: '7px 14px', border: 'none', cursor: 'pointer', borderRadius: 7,
                  background: on ? 'var(--f2-surface-card)' : 'transparent', color: on ? 'var(--f2-text)' : 'var(--f2-text-muted)',
                  fontFamily: 'var(--f2-font-display)', fontWeight: 500, fontSize: 14, boxShadow: on ? 'inset 0 0 0 1px var(--f2-border)' : 'none',
                  transition: 'background var(--f2-dur-fast) var(--f2-ease), color var(--f2-dur-fast) var(--f2-ease)' }}>
                {t.icon && <Icon name={t.icon} size={15} />}{t.label}
              </button>
            );
          })}
        </div>
      );
    }
    return (
      <div role="tablist" onKeyDown={onKey} style={{ display: 'flex', gap: 4, borderBottom: '1px solid var(--f2-border)', ...style }}>
        {items.map((t) => {
          const on = t.value === value;
          return (
            <button key={t.value} role="tab" aria-selected={on} tabIndex={on ? 0 : -1} onClick={() => onChange && onChange(t.value)}
              style={{ display: 'inline-flex', alignItems: 'center', gap: 7, padding: '11px 14px', border: 'none', background: 'none', cursor: 'pointer',
                color: on ? 'var(--f2-text)' : 'var(--f2-text-muted)', fontFamily: 'var(--f2-font-display)', fontWeight: 500, fontSize: 14.5,
                borderBottom: `2px solid ${on ? 'var(--f2-accent)' : 'transparent'}`, marginBottom: -1, transition: 'color var(--f2-dur-fast) var(--f2-ease), border-color var(--f2-dur-fast) var(--f2-ease)' }}>
              {t.icon && <Icon name={t.icon} size={16} />}{t.label}
              {t.badge != null && <span style={{ fontFamily: 'var(--f2-font-mono)', fontSize: 11, color: 'var(--f2-text-faint)', background: 'var(--f2-surface-card)', borderRadius: 999, padding: '1px 7px', marginLeft: 2 }}>{t.badge}</span>}
            </button>
          );
        })}
      </div>
    );
  }

  /* ====================== Breadcrumb ====================== */
  function Breadcrumb({ items = [], style = {} }) {
    return (
      <nav aria-label="Breadcrumb" style={{ ...style }}>
        <ol style={{ display: 'flex', alignItems: 'center', gap: 8, margin: 0, padding: 0, listStyle: 'none', flexWrap: 'wrap' }}>
          {items.map((it, i) => {
            const last = i === items.length - 1;
            return (
              <li key={i} style={{ display: 'inline-flex', alignItems: 'center', gap: 8 }}>
                {last
                  ? <span aria-current="page" style={{ fontSize: 14, color: 'var(--f2-text)', fontWeight: 500 }}>{it.label}</span>
                  : <a href={it.href || '#'} onClick={(e) => { if (!it.href) e.preventDefault(); }} style={{ fontSize: 14, color: 'var(--f2-text-muted)', textDecoration: 'none', display: 'inline-flex', alignItems: 'center', gap: 6 }}>{it.icon && <Icon name={it.icon} size={14} />}{it.label}</a>}
                {!last && <Icon name="ChevronRight" size={14} color="var(--f2-text-faint)" />}
              </li>
            );
          })}
        </ol>
      </nav>
    );
  }

  /* ====================== Pagination ====================== */
  function pageList(page, count) {
    const out = []; const push = (x) => out.push(x);
    if (count <= 7) { for (let i = 1; i <= count; i++) push(i); return out; }
    push(1);
    const lo = Math.max(2, page - 1), hi = Math.min(count - 1, page + 1);
    if (lo > 2) push('…');
    for (let i = lo; i <= hi; i++) push(i);
    if (hi < count - 1) push('…');
    push(count);
    return out;
  }
  function Pagination({ page = 1, count = 1, onChange, style = {} }) {
    const go = (p) => { if (p >= 1 && p <= count && p !== page) onChange && onChange(p); };
    const btn = (active, disabled) => ({
      minWidth: 34, height: 34, padding: '0 8px', display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
      borderRadius: 'var(--f2-radius-control)', border: `1px solid ${active ? 'var(--f2-accent)' : 'var(--f2-border)'}`,
      background: active ? 'var(--f2-surface-accent)' : 'transparent', color: active ? 'var(--f2-accent-text)' : (disabled ? 'var(--f2-text-faint)' : 'var(--f2-text-secondary)'),
      fontFamily: 'var(--f2-font-mono)', fontSize: 13, cursor: disabled ? 'not-allowed' : 'pointer',
    });
    return (
      <nav aria-label="Pagination" style={{ display: 'inline-flex', alignItems: 'center', gap: 6, ...style }}>
        <button aria-label="Previous page" disabled={page <= 1} onClick={() => go(page - 1)} style={btn(false, page <= 1)}><Icon name="ChevronLeft" size={16} /></button>
        {pageList(page, count).map((p, i) => p === '…'
          ? <span key={`e${i}`} style={{ color: 'var(--f2-text-faint)', padding: '0 4px' }}>…</span>
          : <button key={p} aria-current={p === page ? 'page' : undefined} onClick={() => go(p)} style={btn(p === page)}>{p}</button>)}
        <button aria-label="Next page" disabled={page >= count} onClick={() => go(page + 1)} style={btn(false, page >= count)}><Icon name="ChevronRight" size={16} /></button>
      </nav>
    );
  }

  /* ====================== DropdownMenu ====================== */
  function DropdownMenu({ trigger, items = [], align = 'start', width = 220, style = {} }) {
    const [open, setOpen] = React.useState(false);
    const [active, setActive] = React.useState(-1);
    const ref = React.useRef(null);
    useDismiss(ref, () => setOpen(false), open);
    const real = items.map((it, i) => ({ it, i })).filter(({ it }) => !it.divider);
    function onKey(e) {
      if (!open && (e.key === 'ArrowDown' || e.key === 'Enter' || e.key === ' ')) { e.preventDefault(); setOpen(true); setActive(0); return; }
      if (!open) return;
      if (e.key === 'ArrowDown') { e.preventDefault(); setActive((a) => Math.min(a + 1, real.length - 1)); }
      else if (e.key === 'ArrowUp') { e.preventDefault(); setActive((a) => Math.max(a - 1, 0)); }
      else if (e.key === 'Enter') { e.preventDefault(); const r = real[active]; if (r && !r.it.disabled) { r.it.onClick && r.it.onClick(); setOpen(false); } }
    }
    return (
      <span ref={ref} style={{ position: 'relative', display: 'inline-flex', ...style }}>
        <span onClick={() => setOpen((o) => !o)} onKeyDown={onKey} tabIndex={-1}>{trigger}</span>
        {open && (
          <div role="menu" style={{ position: 'absolute', top: 'calc(100% + 6px)', [align === 'end' ? 'right' : 'left']: 0, zIndex: 90, width, padding: 5,
            background: 'var(--f2-surface-card)', border: '1px solid var(--f2-border-strong)', borderRadius: 'var(--f2-radius-control)', boxShadow: 'var(--f2-elevation-overlay)' }}>
            {items.map((it, i) => {
              if (it.divider) return <div key={`d${i}`} style={{ height: 1, background: 'var(--f2-border)', margin: '5px 0' }} />;
              const ri = real.findIndex((r) => r.i === i);
              const danger = it.danger;
              return (
                <button key={i} role="menuitem" disabled={it.disabled} onMouseEnter={() => setActive(ri)} onClick={() => { if (!it.disabled) { it.onClick && it.onClick(); setOpen(false); } }}
                  style={{ display: 'flex', alignItems: 'center', gap: 10, width: '100%', textAlign: 'left', padding: '8px 9px', border: 'none', borderRadius: 7, cursor: it.disabled ? 'not-allowed' : 'pointer',
                    background: ri === active ? (danger ? 'rgba(216,92,87,0.12)' : 'var(--f2-surface-raised)') : 'transparent',
                    color: it.disabled ? 'var(--f2-text-faint)' : (danger ? 'var(--f2-error)' : 'var(--f2-text-secondary)'), fontSize: 14, fontFamily: 'var(--f2-font-body)' }}>
                  {it.icon && <Icon name={it.icon} size={16} />}
                  <span style={{ flex: 1 }}>{it.label}</span>
                  {it.shortcut && <kbd style={{ fontFamily: 'var(--f2-font-mono)', fontSize: 11, color: 'var(--f2-text-faint)' }}>{it.shortcut}</kbd>}
                </button>
              );
            })}
          </div>
        )}
      </span>
    );
  }

  /* ====================== CommandPalette ====================== */
  function CommandPalette({ open, onClose, groups = [], placeholder = 'Type a command or search…', contained = false }) {
    const [q, setQ] = React.useState('');
    const [active, setActive] = React.useState(0);
    const inputRef = React.useRef(null);
    React.useEffect(() => { if (open) { setQ(''); setActive(0); setTimeout(() => inputRef.current && inputRef.current.focus(), 30); } }, [open]);
    React.useEffect(() => {
      if (!open) return undefined;
      const onKey = (e) => { if (e.key === 'Escape') onClose && onClose(); };
      document.addEventListener('keydown', onKey); return () => document.removeEventListener('keydown', onKey);
    }, [open, onClose]);
    if (!open) return null;
    const ql = q.trim().toLowerCase();
    const filteredGroups = groups.map((g) => ({ ...g, items: g.items.filter((it) => (it.label + ' ' + (it.hint || '')).toLowerCase().includes(ql)) })).filter((g) => g.items.length);
    const flat = []; filteredGroups.forEach((g) => g.items.forEach((it) => flat.push(it)));
    function onKey(e) {
      if (e.key === 'ArrowDown') { e.preventDefault(); setActive((a) => Math.min(a + 1, flat.length - 1)); }
      else if (e.key === 'ArrowUp') { e.preventDefault(); setActive((a) => Math.max(a - 1, 0)); }
      else if (e.key === 'Enter') { e.preventDefault(); const it = flat[active]; if (it) { it.onSelect && it.onSelect(); onClose && onClose(); } }
    }
    let runIdx = -1;
    return (
      <div style={{ position: contained ? 'absolute' : 'fixed', inset: 0, zIndex: 300, display: 'flex', alignItems: 'flex-start', justifyContent: 'center', paddingTop: contained ? 40 : '12vh' }}>
        <div onClick={onClose} style={{ position: 'absolute', inset: 0, background: 'rgba(11,13,17,0.6)' }} />
        <div role="dialog" aria-label="Command palette" style={{ position: 'relative', width: 540, maxWidth: '92%', maxHeight: contained ? 'calc(100% - 80px)' : '70vh', display: 'flex', flexDirection: 'column',
          background: 'var(--f2-surface-card)', border: '1px solid var(--f2-border-strong)', borderRadius: 'var(--f2-radius-lg)', boxShadow: 'var(--f2-elevation-overlay)', overflow: 'hidden' }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '14px 16px', borderBottom: '1px solid var(--f2-border)' }}>
            <Icon name="Search" size={17} color="var(--f2-text-muted)" />
            <input ref={inputRef} value={q} placeholder={placeholder} onChange={(e) => { setQ(e.target.value); setActive(0); }} onKeyDown={onKey}
              style={{ flex: 1, border: 'none', outline: 'none', background: 'transparent', color: 'var(--f2-text)', fontFamily: 'var(--f2-font-body)', fontSize: 16 }} />
            <kbd style={{ fontFamily: 'var(--f2-font-mono)', fontSize: 11, color: 'var(--f2-text-faint)', border: '1px solid var(--f2-border)', borderRadius: 5, padding: '2px 6px' }}>ESC</kbd>
          </div>
          <div style={{ overflowY: 'auto', padding: 8 }}>
            {flat.length === 0 && <div style={{ padding: '28px 12px', textAlign: 'center', color: 'var(--f2-text-faint)', fontSize: 14 }}>No results for "{q}"</div>}
            {filteredGroups.map((g) => (
              <div key={g.label} style={{ marginBottom: 6 }}>
                <div style={{ fontFamily: 'var(--f2-font-mono)', fontSize: 10, letterSpacing: '0.14em', textTransform: 'uppercase', color: 'var(--f2-text-faint)', padding: '8px 9px 4px' }}>{g.label}</div>
                {g.items.map((it) => {
                  runIdx++; const isActive = runIdx === active;
                  return (
                    <button key={it.label} onMouseEnter={() => setActive(flat.indexOf(it))} onClick={() => { it.onSelect && it.onSelect(); onClose && onClose(); }}
                      style={{ display: 'flex', alignItems: 'center', gap: 11, width: '100%', textAlign: 'left', padding: '9px 9px', border: 'none', borderRadius: 8, cursor: 'pointer',
                        background: isActive ? 'var(--f2-surface-raised)' : 'transparent', color: 'var(--f2-text-secondary)' }}>
                      {it.icon && <span style={{ color: isActive ? 'var(--f2-accent-text)' : 'var(--f2-text-muted)' }}><Icon name={it.icon} size={17} /></span>}
                      <span style={{ flex: 1, fontSize: 14.5, color: 'var(--f2-text)' }}>{it.label}</span>
                      {it.hint && <span style={{ fontFamily: 'var(--f2-font-mono)', fontSize: 11, color: 'var(--f2-text-faint)' }}>{it.hint}</span>}
                    </button>
                  );
                })}
              </div>
            ))}
          </div>
        </div>
      </div>
    );
  }

  /* ====================== Stepper ====================== */
  function Stepper({ steps = [], current = 0, orientation = 'horizontal', style = {} }) {
    const items = steps.map((s) => (typeof s === 'string' ? { label: s } : s));
    const vert = orientation === 'vertical';
    return (
      <ol style={{ display: 'flex', flexDirection: vert ? 'column' : 'row', gap: 0, margin: 0, padding: 0, listStyle: 'none', ...style }}>
        {items.map((s, i) => {
          const done = i < current, active = i === current;
          const color = done || active ? 'var(--f2-accent)' : 'var(--f2-border-strong)';
          return (
            <li key={i} style={{ display: 'flex', flexDirection: vert ? 'row' : 'column', alignItems: vert ? 'flex-start' : 'center', flex: vert ? 'none' : 1, gap: vert ? 12 : 0, position: 'relative' }}>
              <div style={{ display: 'flex', flexDirection: vert ? 'column' : 'row', alignItems: 'center', width: vert ? 'auto' : '100%', gap: vert ? 0 : 0 }}>
                {!vert && <div style={{ flex: 1, height: 2, background: i === 0 ? 'transparent' : (done || active ? 'var(--f2-accent)' : 'var(--f2-border)') }} />}
                <span aria-current={active ? 'step' : undefined} style={{ flex: '0 0 auto', width: 30, height: 30, borderRadius: '50%', display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
                  border: `2px solid ${color}`, background: done ? 'var(--f2-accent)' : 'var(--f2-surface)', color: done ? 'var(--f2-text-on-accent)' : (active ? 'var(--f2-accent-text)' : 'var(--f2-text-faint)'),
                  fontFamily: 'var(--f2-font-mono)', fontSize: 13, fontWeight: 600 }}>
                  {done ? <Icon name="Check" size={15} stroke={2.4} /> : i + 1}
                </span>
                {!vert && <div style={{ flex: 1, height: 2, background: i === items.length - 1 ? 'transparent' : (done ? 'var(--f2-accent)' : 'var(--f2-border)') }} />}
                {vert && i < items.length - 1 && <div style={{ width: 2, flex: 1, minHeight: 28, background: done ? 'var(--f2-accent)' : 'var(--f2-border)', marginTop: 2 }} />}
              </div>
              <div style={{ textAlign: vert ? 'left' : 'center', marginTop: vert ? 0 : 8, paddingBottom: vert ? 20 : 0 }}>
                <div style={{ fontSize: 14, fontWeight: 500, color: active || done ? 'var(--f2-text)' : 'var(--f2-text-muted)' }}>{s.label}</div>
                {s.description && <div style={{ fontSize: 12.5, color: 'var(--f2-text-faint)', marginTop: 2 }}>{s.description}</div>}
              </div>
            </li>
          );
        })}
      </ol>
    );
  }

  Object.assign(window.F2, { Tabs, Breadcrumb, Pagination, DropdownMenu, CommandPalette, Stepper });
})();
