/* ============================================================
   AIGENT DESIGN SYSTEM — shared React components
   Depends on icons.jsx (loaded first) + aigent.css.
   All components exposed on window for cross-file use.
   ============================================================ */

const { useState, useRef, useEffect } = React;
const { EyeIcon, Caret, AlertIcon, CheckIcon } = window;

/* ---------- App shell ---------- */
function AppHeader({ children }) {
  return (
    <header className="app-header">
      <div className="wordmark"><b>ai</b><span>gent</span></div>
      {children}
    </header>
  );
}

function AppFooter({ year = 2025, links = [{ label: "Forgot username?" }, { label: "Need help?" }] }) {
  return (
    <footer className="app-footer">
      <span>© Aigent, {year}</span>
      {links.map((l, i) => (
        <React.Fragment key={i}>
          <span className="dot"></span>
          <a href={l.href || "#"} onClick={(e) => !l.href && e.preventDefault()}>{l.label}</a>
        </React.Fragment>
      ))}
    </footer>
  );
}

/* ---------- Button ---------- */
function Button({ variant = "primary", size, block, loading, className, children, ...rest }) {
  const cls = ["btn", "btn-" + variant];
  if (size === "lg") cls.push("btn-lg");
  if (block) cls.push("btn-block");
  if (className) cls.push(className);
  return (
    <button className={cls.join(" ")} disabled={loading || rest.disabled} {...rest}>
      {loading && <span className={"spinner" + (variant === "primary" || variant === "danger" ? "" : " spinner-brand")} />}
      {children}
    </button>
  );
}

/* ---------- Field wrapper ---------- */
function Field({ label, htmlFor, error, helper, children }) {
  return (
    <div className={"field" + (error ? " invalid" : "")}>
      {label && <label className="field-label" htmlFor={htmlFor}>{label}</label>}
      {children}
      {error
        ? <div className="error-msg"><AlertIcon />{error}</div>
        : helper ? <div className="helper-msg">{helper}</div> : null}
    </div>
  );
}

/* ---------- Text field ---------- */
function TextField({ id, label, error, helper, inputRef, trailing, ...input }) {
  return (
    <Field label={label} htmlFor={id} error={error} helper={helper}>
      <div className={"control" + (trailing ? " has-trailing" : "")}>
        <input id={id} ref={inputRef} className="input" aria-invalid={!!error} {...input} />
        {trailing}
      </div>
    </Field>
  );
}

/* ---------- Password field ---------- */
function PasswordField({ id, label, error, helper, inputRef, ...input }) {
  const [show, setShow] = useState(false);
  return (
    <Field label={label} htmlFor={id} error={error} helper={helper}>
      <div className="control has-trailing">
        <input id={id} ref={inputRef} className="input" type={show ? "text" : "password"}
               aria-invalid={!!error} {...input} />
        <button type="button" className="trailing-btn" aria-pressed={show}
                aria-label={show ? "Hide password" : "Show password"}
                onClick={() => setShow((s) => !s)}>
          <EyeIcon off={show} />
        </button>
      </div>
    </Field>
  );
}

/* ---------- Checkbox ---------- */
function Checkbox({ checked, onChange, children }) {
  return (
    <label className="checkbox">
      <input type="checkbox" checked={checked} onChange={(e) => onChange(e.target.checked)} />
      <span className="box"><CheckIcon size={14} /></span>
      {children}
    </label>
  );
}

/* ---------- Searchable Select (combobox) ---------- */
function Select({ value, onChange, options, placeholder = "Search or select…", error, onOpen }) {
  const [open, setOpen] = useState(false);
  const [query, setQuery] = useState("");
  const [active, setActive] = useState(0);
  const wrapRef = useRef(null);
  const inputRef = useRef(null);

  const selected = options.find((o) => o.id === value);
  const display = open ? query : (selected ? selected.name : "");
  const filtered = options.filter((o) => o.name.toLowerCase().includes(query.trim().toLowerCase()));

  useEffect(() => {
    const onDoc = (e) => { if (wrapRef.current && !wrapRef.current.contains(e.target)) setOpen(false); };
    document.addEventListener("mousedown", onDoc);
    return () => document.removeEventListener("mousedown", onDoc);
  }, []);

  const openMenu = () => {
    setOpen(true); setQuery(""); setActive(0);
    onOpen && onOpen();
    requestAnimationFrame(() => inputRef.current && inputRef.current.focus());
  };
  const pick = (o) => { onChange(o.id); setOpen(false); setQuery(""); };

  const onKey = (e) => {
    if (!open && (e.key === "ArrowDown" || e.key === "Enter")) { e.preventDefault(); openMenu(); return; }
    if (!open) return;
    if (e.key === "ArrowDown") { e.preventDefault(); setActive((a) => Math.min(a + 1, filtered.length - 1)); }
    else if (e.key === "ArrowUp") { e.preventDefault(); setActive((a) => Math.max(a - 1, 0)); }
    else if (e.key === "Enter") { e.preventDefault(); if (filtered[active]) pick(filtered[active]); }
    else if (e.key === "Escape") setOpen(false);
  };

  return (
    <div className={"control has-trailing" + (open ? " open" : "")} ref={wrapRef}>
      <input ref={inputRef} className="input" type="text" role="combobox" aria-expanded={open}
             autoComplete="off" placeholder={placeholder} value={display} aria-invalid={!!error}
             onChange={(e) => { setQuery(e.target.value); setActive(0); if (!open) setOpen(true); }}
             onFocus={() => { if (!open) openMenu(); }}
             onClick={() => { if (!open) openMenu(); }}
             onKeyDown={onKey} />
      <button type="button" className="trailing-btn" tabIndex="-1" aria-label="Toggle list"
              onMouseDown={(e) => { e.preventDefault(); open ? setOpen(false) : openMenu(); }}>
        <Caret up={open} />
      </button>
      {open && (
        <div className="menu" role="listbox">
          {filtered.length === 0 && <div className="menu-empty">No matches for “{query.trim()}”</div>}
          {filtered.map((o, i) => (
            <div key={o.id} role="option" aria-selected={o.id === value}
                 className={"menu-item" + (i === active ? " active" : "")}
                 onMouseEnter={() => setActive(i)}
                 onMouseDown={(e) => { e.preventDefault(); pick(o); }}>
              <span>{o.name}{o.sub && <><br /><span className="sub">{o.sub}</span></>}</span>
              {o.id === value && <span className="check"><CheckIcon /></span>}
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

/* ---------- Badge ---------- */
function Badge({ tone = "neutral", children }) {
  return <span className={"badge badge-" + tone}>{children}</span>;
}

function Tooltip({ text, align, children }) {
  return (
    <span className={"tip" + (align ? " " + align : "")}>
      <span className="tip-trigger" tabIndex={0}>{children}</span>
      <span className="tip-bub" role="tooltip">{text}</span>
    </span>
  );
}

Object.assign(window, { AppHeader, AppFooter, Button, Field, TextField, PasswordField, Checkbox, Select, Badge, Tooltip });
