/* eagle-ui.jsx — theme context + shared Eagle Eye primitives.
   useE() returns the active theme tokens; everything reads color via it so
   light/dark toggles re-theme instantly. Telemetry rows resolve a color KEY
   (ev.ck) against the theme. */

const EagleThemeCtx = React.createContext(null);
function useE() { return React.useContext(EagleThemeCtx) || window.EAGLE_THEMES.dark; }

/* ---- severity chip ------------------------------------------ */
function SevChip({ sev, size = "sm" }) {
  const E = useE();
  const map = { CRITICAL: E.crit, HIGH: E.high, MEDIUM: E.med, LOW: E.low };
  const c = map[sev] || E.muted;
  const pad = size === "lg" ? "px-2 py-0.5 text-[11px]" : "px-1.5 py-0.5 text-[10px]";
  return (
    <span className={"inline-flex items-center gap-1 rounded font-bold uppercase tracking-wider " + pad}
      style={{ color: c, background: c + "1f", fontFamily: E.mono }}>
      <span className="inline-block h-1.5 w-1.5 rounded-full" style={{ background: c }} /> {sev}
    </span>
  );
}

/* ---- markdown + entity highlighter -------------------------- */
const _SEV = { CRITICAL: "crit", HIGH: "high", MEDIUM: "med", LOW: "low" };
const _HILITE = /(\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b|\bworkstation-\d+\b|\blaptop-\d+\b|\bsrv-[a-z0-9-]+\b|\bvpn-gw-\d+\b|\bsvc[-_][a-z0-9]+\b|\b\d{2,5}\/(?:TCP|UDP)\b|[a-z0-9._%+-]+@company\.com|\b(?:CRITICAL|HIGH|MEDIUM|LOW)\b)/g;

function hiliteText(str, key, E) {
  return str.split(_HILITE).map((p, i) => {
    if (!p) return null;
    if (i % 2 === 1) {
      if (_SEV[p]) return <span key={key + i} style={{ color: E[_SEV[p]], fontWeight: 700 }}>{p}</span>;
      return <span key={key + i} className="rounded px-1" style={{ fontFamily: E.mono, fontSize: "0.92em", color: E.app, background: E.app + "1a" }}>{p}</span>;
    }
    return <React.Fragment key={key + i}>{p}</React.Fragment>;
  });
}
function inlineNodes(text, key, E) {
  const out = []; const re = /(`[^`]+`|\*\*[^*]+\*\*|\*[^*]+\*)/g;
  let last = 0, m, idx = 0;
  while ((m = re.exec(text)) !== null) {
    if (m.index > last) out.push(...[].concat(hiliteText(text.slice(last, m.index), key + "p" + idx++, E)));
    const tok = m[0];
    if (tok.startsWith("`")) out.push(<code key={key + "c" + idx++} className="rounded px-1.5 py-0.5" style={{ fontFamily: E.mono, fontSize: "0.86em", color: E.text, background: E.fill }}>{tok.slice(1, -1)}</code>);
    else if (tok.startsWith("**")) out.push(<strong key={key + "b" + idx++} style={{ color: E.text, fontWeight: 700 }}>{hiliteText(tok.slice(2, -2), key + "bb" + idx, E)}</strong>);
    else out.push(<em key={key + "i" + idx++} style={{ color: E.text }}>{tok.slice(1, -1)}</em>);
    last = re.lastIndex;
  }
  if (last < text.length) out.push(...[].concat(hiliteText(text.slice(last), key + "pf", E)));
  return out;
}
function EInline({ text }) { const E = useE(); return <>{inlineNodes(text || "", "i", E)}</>; }

function Markdown({ text }) {
  const E = useE();
  const lines = (text || "").split("\n"); const blocks = []; let list = null;
  const flush = () => {
    if (list) {
      const Tag = list.ordered ? "ol" : "ul";
      blocks.push(<Tag key={"l" + blocks.length} className={(list.ordered ? "list-decimal" : "list-disc") + " my-2 space-y-1.5 pl-5"}>{list.items.map((it, i) => <li key={i} className="leading-relaxed" style={{ color: E.text }}>{inlineNodes(it, "li" + blocks.length + "-" + i, E)}</li>)}</Tag>);
      list = null;
    }
  };
  lines.forEach((raw, i) => {
    const line = raw.replace(/\s+$/, ""); if (!line.trim()) { flush(); return; }
    let m;
    if ((m = line.match(/^###?\s+(.*)/))) { flush(); blocks.push(<div key={"h" + i} className="mb-1 mt-3 text-[15px] font-bold first:mt-0" style={{ color: E.text }}>{inlineNodes(m[1], "h" + i, E)}</div>); return; }
    if ((m = line.match(/^\s*[-*]\s+(.*)/))) { if (!list || list.ordered) { flush(); list = { ordered: false, items: [] }; } list.items.push(m[1]); return; }
    if ((m = line.match(/^\s*\d+\.\s+(.*)/))) { if (!list || !list.ordered) { flush(); list = { ordered: true, items: [] }; } list.items.push(m[1]); return; }
    flush(); blocks.push(<p key={"p" + i} className="my-1.5 leading-relaxed" style={{ color: E.text }}>{inlineNodes(line, "p" + i, E)}</p>);
  });
  flush();
  return <div className="text-[14px]">{blocks}</div>;
}

/* ---- copy button -------------------------------------------- */
function CopyBtn({ getText, label = "Copy" }) {
  const E = useE();
  const [done, setDone] = React.useState(false);
  return (
    <button onClick={() => { try { navigator.clipboard.writeText(getText()); } catch (e) {} setDone(true); setTimeout(() => setDone(false), 1400); }}
      className="inline-flex items-center gap-1.5 rounded-md px-2 py-1 text-[11px] font-medium transition-colors"
      style={{ color: done ? E.success : E.muted, background: E.fill, border: `1px solid ${E.border}` }}>
      <window.Icon name={done ? "Check" : "Copy"} size={12} /> {done ? "Copied" : label}
    </button>
  );
}

/* ---- theme toggle ------------------------------------------- */
function EagleThemeToggle({ mode, onToggle }) {
  const E = useE();
  const light = mode === "light";
  return (
    <button onClick={onToggle} aria-label={light ? "Switch to dark" : "Switch to light"}
      className="inline-flex h-9 items-center gap-2 rounded-lg px-2.5 text-[12px] font-semibold transition-colors hover:opacity-80"
      style={{ color: E.text2, background: E.elevated, border: `1px solid ${E.border}` }}>
      <window.Icon name={light ? "Moon" : "Sun"} size={15} style={{ color: E.gateway }} />
      <span className="hidden sm:inline">{light ? "Dark" : "Light"}</span>
    </button>
  );
}

/* ---- meters + demo nav -------------------------------------- */
function MeterChip({ icon, label, value, ck }) {
  const E = useE();
  return (
    <div className="flex items-center gap-2 rounded-lg px-2.5 py-1.5" style={{ background: E.elevated, border: `1px solid ${E.border}` }}>
      <window.Icon name={icon} size={13} style={{ color: ck ? E[ck] : E.muted }} />
      <div className="leading-none">
        <div className="text-[9px] uppercase tracking-[0.14em]" style={{ color: E.muted }}>{label}</div>
        <div className="mt-0.5 text-[12.5px] font-semibold tabular-nums" style={{ fontFamily: E.mono, color: E.text }}>{value}</div>
      </div>
    </div>
  );
}

/* ---- persistent Eagle Eye screen tabs ----------------------- */
// Real anchors with hash hrefs → native middle/Cmd-click "open in new tab".
// A guarded onClick keeps left-clicks as smooth in-app navigation.
function ScreenTabs({ current, onGo }) {
  const E = useE();
  const tabs = [["soc", "Dashboard", "LayoutDashboard"], ["model", "Model", "Box"], ["app", "Application", "Boxes"], ["agent", "Agent", "Workflow"], ["compare", "Compare", "Columns3"]];
  return (
    <div className="lr-scroll flex items-center gap-0.5 overflow-x-auto rounded-lg p-0.5" style={{ background: E.elevated, border: `1px solid ${E.border}` }}>
      {tabs.map(([k, label, icon]) => { const on = current === k; const c = k === "model" ? E.model : k === "app" ? E.app : k === "agent" ? E.agent : E.gateway; return (
        <a key={k} href={"#/eagle/" + k}
          onClick={(e) => { if (e.metaKey || e.ctrlKey || e.shiftKey || e.button !== 0) return; e.preventDefault(); onGo(k); }}
          className="inline-flex h-7 shrink-0 items-center gap-1.5 whitespace-nowrap rounded-md px-2.5 text-[12px] font-semibold transition-colors" style={{ background: on ? c + "22" : "transparent", color: on ? c : E.muted }}>
          <window.Icon name={icon} size={13} /><span className="hidden lg:inline">{label}</span>
        </a>
      ); })}
    </div>
  );
}

function EagleNav({ layer, meters, running, onBack, center, mode, onToggleTheme, current, onGo }) {
  const E = useE(); const lc = E[layer.key];
  return (
    <header className="flex flex-wrap items-center justify-between gap-3 border-b px-6 py-2.5 lg:px-8" style={{ background: E.headerBg, borderColor: E.border, backdropFilter: "blur(12px)" }}>
      <div className="flex items-center gap-3">
        {onGo && <ScreenTabs current={current} onGo={onGo} />}
        <span className="inline-flex shrink-0 items-center gap-2 whitespace-nowrap rounded-lg px-2.5 py-1.5 text-[11px] font-bold uppercase tracking-[0.12em]" style={{ color: lc, background: lc + "1a", border: `1px solid ${lc}40`, fontFamily: E.mono }}>
          <window.Icon name={layer.icon} size={14} /> {layer.label}
        </span>
        {center}
      </div>
      <div className="flex flex-wrap items-center gap-2">
        <MeterChip icon="Hash" label="Tokens" value={meters.tokens} ck="cost" />
        <MeterChip icon="DollarSign" label="Cost" value={meters.cost} ck="cost" />
        <MeterChip icon="Gauge" label="Latency" value={meters.latency} ck={running ? "agent" : null} />
        {current && <window.OpenInNewTab href={"#/eagle/" + current} size={15} className="h-9 w-9" title="Open this screen in new tab" style={{ color: E.text2, background: E.elevated, border: `1px solid ${E.border}` }} />}
        {onToggleTheme && <EagleThemeToggle mode={mode} onToggle={onToggleTheme} />}
      </div>
    </header>
  );
}

/* ---- run bar (selected-alert summary + run control) --------- */
function RunBar({ layer, alert, running, started, onRun, onReset, onPickAlert, runLabel = "Analyse Alert" }) {
  const E = useE(); const lc = E[layer.key]; const [raw, setRaw] = React.useState(false);
  return (
    <div className="rounded-xl" style={{ background: E.surface, border: `1px solid ${E.border}` }}>
      <div className="flex flex-wrap items-center gap-3 px-3.5 py-3">
        <SevChip sev={alert.sev} size="lg" />
        <div className="min-w-0 flex-1">
          <div className="flex items-center gap-2 text-[13px] font-bold" style={{ color: E.text }}>{alert.title}
            <span className="truncate text-[11px] font-normal tabular-nums" style={{ color: E.muted, fontFamily: E.mono }}>#{alert.code}</span>
          </div>
          <div className="truncate text-[11px]" style={{ fontFamily: E.mono, color: E.muted }}>{alert.rule} · {alert.host}{alert.destIp ? " → " + alert.destIp + ":" + alert.port : ""}</div>
        </div>
        <button onClick={onPickAlert} className="inline-flex h-8 items-center gap-1.5 rounded-lg px-2.5 text-[12px] font-medium transition-colors hover:opacity-80" style={{ color: E.text2, border: `1px solid ${E.border}` }}>
          <window.Icon name="ListChecks" size={14} /> Change alert
        </button>
        <button onClick={() => setRaw((v) => !v)} className="inline-flex h-8 items-center rounded-lg px-2.5 text-[12px] transition-colors hover:opacity-80" style={{ color: E.muted, border: `1px solid ${E.border}` }}>{raw ? "Hide" : "Raw"}</button>
        <button onClick={() => (started && !running ? onReset() : onRun())} disabled={running}
          className="inline-flex h-9 shrink-0 items-center gap-2 whitespace-nowrap rounded-lg px-4 text-[13px] font-bold transition-all active:scale-95 disabled:cursor-not-allowed"
          style={{ background: running ? E.fill : lc, color: running ? E.muted : (E.isDark ? "#050508" : "#fff") }}>
          {running ? <><window.Icon name="Loader" size={15} className="animate-spin" /> Running…</> : started ? <><window.Icon name="RotateCcw" size={15} /> Run Again</> : <><window.Icon name="Play" size={15} /> {runLabel}</>}
        </button>
      </div>
      <div className="flex items-center gap-2 border-t px-3.5 py-1.5 text-[10.5px]" style={{ borderColor: E.border, color: E.muted }}>
        <kbd className="rounded px-1.5 py-0.5" style={{ fontFamily: E.mono, background: E.fill, color: E.text2 }}>⌘ + ↵</kbd> to run
      </div>
      {raw && <pre className="lr-scroll overflow-x-auto border-t px-3.5 py-3 text-[11px] leading-relaxed" style={{ borderColor: E.border, color: E.text2, fontFamily: E.mono }}>{alert.alertText}</pre>}
    </div>
  );
}

/* ---- telemetry panel ---------------------------------------- */
function TelemRow({ ev }) {
  const E = useE(); const [open, setOpen] = React.useState(false); const c = E[ev.ck] || E.muted;
  if (ev.phase) return (
    <div className="mt-3 flex items-center gap-2 first:mt-0">
      <span className="text-[10px] font-bold uppercase tracking-[0.16em]" style={{ color: c, fontFamily: E.mono }}>{ev.label}</span>
      <span className="h-px flex-1" style={{ background: `linear-gradient(90deg, ${c}66, transparent)` }} />
    </div>
  );
  if (ev.doc) { const d = ev.doc; return (
    <div className="rounded-lg" style={{ background: E.elevated, border: `1px solid ${c}33` }}>
      <button onClick={() => setOpen((v) => !v)} className="flex w-full items-center gap-2 px-2.5 py-2 text-left">
        <window.Icon name="FileText" size={13} style={{ color: c }} />
        <span className="flex-1 text-[12px] font-medium" style={{ color: E.text }}>{d.title}</span>
        <span className="rounded px-1.5 py-0.5 text-[10px] tabular-nums" style={{ fontFamily: E.mono, color: c, background: c + "1f" }}>{d.score.toFixed(2)}</span>
        <window.Icon name={open ? "ChevronDown" : "ChevronRight"} size={13} style={{ color: E.muted }} />
      </button>
      {open && <div className="border-t px-2.5 py-2 text-[11.5px] leading-relaxed" style={{ borderColor: E.border, color: E.muted }}>{d.snippet}</div>}
    </div>
  ); }
  const expandable = !!ev.payload;
  return (
    <div className="flex gap-2.5">
      <span className="mt-1 shrink-0 text-[10px] tabular-nums" style={{ color: E.muted, fontFamily: E.mono, minWidth: 44 }}>+{ev.ts.toFixed(2)}s</span>
      <span className="mt-1.5 h-1.5 w-1.5 shrink-0 rounded-full" style={{ background: c, boxShadow: `0 0 6px ${c}` }} />
      <div className="min-w-0 flex-1">
        <div className="flex items-center gap-1.5">
          <button onClick={() => expandable && setOpen((v) => !v)} className={"flex min-w-0 flex-1 items-center gap-1.5 text-left " + (expandable ? "cursor-pointer" : "cursor-default")}>
            {expandable && <window.Icon name={open ? "ChevronDown" : "ChevronRight"} size={12} style={{ color: E.muted }} />}
            <span className="truncate text-[12.5px] font-medium" style={{ color: E.text }}>{ev.label}</span>
            {ev.spinner && <window.Icon name="Loader" size={11} className="animate-spin" style={{ color: c }} />}
            {ev.ok && <window.Icon name="Check" size={12} style={{ color: E.success }} />}
          </button>
          {ev.value && <span className="shrink-0 text-[11.5px] font-semibold tabular-nums" style={{ fontFamily: E.mono, color: c }}>{ev.value}</span>}
        </div>
        {ev.detail && <div className="mt-0.5 truncate text-[11px]" style={{ color: E.muted, fontFamily: E.mono }}>{ev.detail}</div>}
        {expandable && open && <pre className="lr-scroll mt-1.5 overflow-x-auto rounded-md px-2.5 py-2 text-[10.5px] leading-relaxed" style={{ background: E.codeBg, border: `1px solid ${E.border}`, color: E.isDark ? E.text : "#e8e8f2", fontFamily: E.mono }}>{ev.payload}</pre>}
      </div>
    </div>
  );
}

function TelemetryPanel({ events, onClear, title = "Under the hood", empty = "Telemetry will stream here as the alert is analysed." }) {
  const E = useE(); const ref = React.useRef(null); const stick = React.useRef(true);
  React.useEffect(() => { const el = ref.current; if (el && stick.current) el.scrollTop = el.scrollHeight; }, [events]);
  const onScroll = () => { const el = ref.current; if (el) stick.current = el.scrollHeight - el.scrollTop - el.clientHeight < 40; };
  return (
    <div className="flex h-full flex-col overflow-hidden rounded-xl" style={{ background: E.surface, border: `1px solid ${E.border}` }}>
      <div className="flex items-center justify-between border-b px-3.5 py-2.5" style={{ borderColor: E.border }}>
        <span className="inline-flex items-center gap-2 text-[11px] font-bold uppercase tracking-[0.16em]" style={{ color: E.muted, fontFamily: E.mono }}><window.Icon name="Activity" size={13} /> {title}</span>
        <div className="flex items-center gap-2">
          <span className="text-[10.5px] tabular-nums" style={{ color: E.muted, fontFamily: E.mono }}>{events.length} events</span>
          <button onClick={onClear} className="inline-flex items-center gap-1 rounded-md px-2 py-1 text-[11px] transition-colors hover:opacity-80" style={{ color: E.muted, border: `1px solid ${E.border}` }}><window.Icon name="Eraser" size={11} /> Clear</button>
        </div>
      </div>
      <div ref={ref} onScroll={onScroll} className="lr-scroll flex-1 space-y-2 overflow-y-auto px-3.5 py-3" style={{ minHeight: 0 }}>
        {events.length === 0 ? (
          <div className="flex h-full flex-col items-center justify-center text-center" style={{ color: E.muted }}>
            <window.Icon name="Radio" size={22} /><p className="mt-2 max-w-[200px] text-[12px] leading-relaxed">{empty}</p>
          </div>
        ) : events.map((ev) => <TelemRow key={ev._id} ev={ev} />)}
      </div>
    </div>
  );
}

Object.assign(window, { EagleThemeCtx, useE, SevChip, Markdown, EInline, CopyBtn, EagleThemeToggle, ScreenTabs, MeterChip, EagleNav, RunBar, TelemetryPanel });
