// ════════════════════════════════════════════════════════════════════
// THE FRONTIER LEDGER — React app (transpiled in-browser by Babel)
// Filters: by TOPIC (primary axis) and by COMPANY (secondary axis),
// plus Recency/Magnitude sort and Grid/Timeline view.
// Skins + day/night live in the APPEARANCE hologram widget (static DOM,
// bottom-right) which writes data-skin/data-mode to <html>; this app
// listens for the 'fl-appearance' event to recolor. The filter controls
// live in a second hologram widget (bottom-left, React-driven).
// ════════════════════════════════════════════════════════════════════ */
const { useState, useMemo, useEffect } = React;

const SKINS = {
  observatory: { phos: "#39ff14", cyan: "#00f5ff", ink: "#0c2e18", glow: "0 0 12px rgba(57,255,20,.5)" },
  tokyo:      { phos: "#00f5ff", cyan: "#2bd6ff", ink: "#0a2e44", glow: "0 0 12px rgba(0,245,255,.5)" },
  outrun:     { phos: "#ff2bd6", cyan: "#ff5be0", ink: "#2a0a2e", glow: "0 0 12px rgba(255,43,214,.5)" },
  mainframe:  { phos: "#ffb000", cyan: "#ffd166", ink: "#3a2400", glow: "0 0 12px rgba(255,176,0,.5)" },
  sentinel:   { phos: "#ff3b3b", cyan: "#ff7a7a", ink: "#2a0c0c", glow: "0 0 12px rgba(255,59,59,.5)" },
};
const SKIN_NAMES = Object.keys(SKINS);

// Per-company accent for the card logo box (restores pre-hologram look)
const LOGO_COLORS = {
  "OpenAI": "#00f5ff",
  "Google DeepMind": "#4285f4",
  "Anthropic": "#d9663a",
  "Meta AI (FAIR)": "#a259ff",
  "Microsoft Research": "#2b9fe0",
  "xAI": "#cfd8dc",
  "Mistral AI": "#ff8c42",
  "DeepSeek": "#3b6ef5",
  "Nvidia Research": "#76b900",
  "IBM Research": "#2c7be5",
  "Amazon Science / AWS AI": "#ff9900",
};

function App() {
  const [topic, setTopic] = useState("All");
  const [company, setCompany] = useState("All");
  const [sort, setSort] = useState("recency"); // recency | magnitude
  const [expandedId, setExpandedId] = useState(null);
  const [view, setView] = useState("grid"); // grid | timeline
  const [controlsOpen, setControlsOpen] = useState(false);
  // skin/mode are owned by the appearance hologram widget (bottom-right);
  // we mirror them here so the grid can recolor.
  const [skin, setSkin] = useState(
    () => document.documentElement.getAttribute("data-skin") || "observatory"
  );
  const [mode, setMode] = useState(
    () => document.documentElement.getAttribute("data-mode") || "night"
  );

  useEffect(() => {
    const onApp = (e) => {
      if (e.detail && e.detail.skin) setSkin(e.detail.skin);
      if (e.detail && e.detail.mode) setMode(e.detail.mode);
    };
    window.addEventListener("fl-appearance", onApp);
    return () => window.removeEventListener("fl-appearance", onApp);
  }, []);

  const c = SKINS[skin] || SKINS.observatory;

  const filtered = useMemo(() => {
    let list = PUBLICATIONS.filter((p) => {
      if (topic !== "All" && !p.topics.includes(topic)) return false;
      if (company !== "All" && p.company !== company) return false;
      return true;
    });
    list = [...list].sort((a, b) =>
      sort === "magnitude"
        ? (b.openYears || 0) - (a.openYears || 0)
        : b.date.localeCompare(a.date)
    );
    return list;
  }, [topic, company, sort]);

  const activeFilters = (topic !== "All" ? 1 : 0) + (company !== "All" ? 1 : 0) + (sort !== "recency" ? 1 : 0) + (view !== "grid" ? 1 : 0);

  return (
    <div className="fl-root">
      <header className="fl-header">
        <div className="fl-brand">
          <span className="fl-logo-big" style={{ borderColor: c.cyan, color: c.cyan }}>DOAI</span>
          <div>
            <div className="fl-eyebrow"><span className="fl-live-dot"></span> RESEARCH ATLAS · LIVE INTEL</div>
            <h1 className="fl-h1">THE FRONTIER LEDGER</h1>
            <p className="fl-sub">A research atlas of landmark AI publications — not a blog feed.</p>
          </div>
        </div>
      </header>

      {/* Live cards ARE today's signals (newest per company). No separate strip. */}
      <div className="fl-count">{filtered.length} publication{filtered.length !== 1 ? "s" : ""} shown</div>

      {view === "grid" ? (
        <div className="fl-grid">
          {filtered.map((p) => (
            <Card key={p.id} pub={p} expanded={expandedId === p.id} onToggle={() => setExpandedId(expandedId === p.id ? null : p.id)} />
          ))}
        </div>
      ) : (
        <div className="fl-timeline">
          {filtered.map((p) => (
            <div key={p.id} className="fl-tl-row">
              <div className="fl-tl-date" style={{ color: c.phos }}>{p.date}</div>
              <div className="fl-tl-node" style={{ background: c.phos }} />
              <div className="fl-tl-card">
                <Card pub={p} expanded={expandedId === p.id} onToggle={() => setExpandedId(expandedId === p.id ? null : p.id)} />
              </div>
            </div>
          ))}
        </div>
      )}

      {filtered.length === 0 && <p className="fl-empty">No publications match this filter.</p>}

      <footer className="fl-footer">
        <span>THE FRONTIER LEDGER · D.O.A.I. research atlas</span>
        <a href="https://doaiorbit.com" style={{ color: c.cyan }}>doaiorbit.com ↗</a>
      </footer>

      {/* ════ CONTROLS HOLOGRAM (bottom-left) — filters, sort, view ════ */}
      <div id="controls-widget" className={"holo-widget" + (controlsOpen ? " open" : "")} aria-label="filters">
        <button className="holo-launch" title="Filters / Sort / View" aria-expanded={controlsOpen}
          onClick={() => setControlsOpen((o) => !o)}>
          <span className="holo-launch-core"></span>
          <span className="holo-launch-ring"></span>
          {activeFilters > 0 && <span className="flc-badge">{activeFilters}</span>}
        </button>
        <div className="holo-panel" role="dialog" aria-label="Filters and sort">
          <div className="holo-head">
            <span className="holo-title">⬡ CONTROLS</span>
            <button className="holo-x" aria-label="Close" onClick={() => setControlsOpen(false)}>✕</button>
          </div>
          <div className="holo-body">
            <div className="fl-filter-group">
              <label>TOPIC AXIS</label>
              <div className="fl-chips fl-chips-wrap">
                <button className={"fl-chip" + (topic === "All" ? " active" : "")} onClick={() => setTopic("All")}>All</button>
                {TOPIC_AXES.map((t) => (
                  <button key={t} className={"fl-chip" + (topic === t ? " active" : "")} onClick={() => setTopic(t)}>{t}</button>
                ))}
              </div>
            </div>
            <div className="fl-filter-group">
              <label>COMPANY</label>
              <div className="fl-chips fl-chips-wrap">
                <button className={"fl-chip" + (company === "All" ? " active" : "")} onClick={() => setCompany("All")}>All</button>
                {COMPANIES.map((co) => (
                  <button key={co} className={"fl-chip" + (company === co ? " active" : "")} onClick={() => setCompany(co)}>{co}</button>
                ))}
              </div>
            </div>
            <div className="fl-filter-group">
              <label>SORT</label>
              <div className="fl-chips">
                <button className={"fl-chip" + (sort === "recency" ? " active" : "")} onClick={() => setSort("recency")}>🕑 Recency</button>
                <button className={"fl-chip" + (sort === "magnitude" ? " active" : "")} onClick={() => setSort("magnitude")}>⚡ Magnitude</button>
              </div>
              <label style={{ marginTop: "10px" }}>VIEW</label>
              <div className="fl-chips">
                <button className={"fl-chip" + (view === "grid" ? " active" : "")} onClick={() => setView("grid")}>▦ Grid</button>
                <button className={"fl-chip" + (view === "timeline" ? " active" : "")} onClick={() => setView("timeline")}>▤ Timeline</button>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

function Card({ pub, expanded, onToggle }) {
  const c = SKINS[document.documentElement.getAttribute("data-skin")] || SKINS.observatory;
  const acc = LOGO_COLORS[pub.company] || c.cyan;
  return (
    <article className={"fl-card" + (expanded ? " is-open" : "")} style={{ "--acc": acc }}>
      <span className="fl-corner tl"></span>
      <span className="fl-corner tr"></span>
      <span className="fl-corner bl"></span>
      <span className="fl-corner br"></span>
      <span className="fl-rail"></span>
      <div className="fl-card-head" onClick={onToggle}>
        <div className="fl-logo">{pub.logo}</div>
        <div className="fl-card-meta">
          <div className="fl-company">{pub.company}</div>
          <div className="fl-title">{pub.title}</div>
          <div className="fl-date">{pub.date}{pub.openYears ? "  ·  " + pub.openYears + "y open" : ""}</div>
        </div>
        <div className="fl-arrow">{expanded ? "▾" : "▸"}</div>
      </div>
      <div className="fl-result-line">{pub.result}</div>
      {expanded && (
        <div className="fl-card-body">
          <p className="fl-notable"><span className="fl-tag-lbl">WHY NOTABLE</span> — {pub.notable}</p>
          <div className="fl-topics">
            {pub.topics.map((t) => (
              <span key={t} className="fl-topic-chip">{t}</span>
            ))}
          </div>
          {pub.source && (
            <a className="fl-source" href={pub.source} target="_blank" rel="noopener">
              ↗ primary source
            </a>
          )}
        </div>
      )}
    </article>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<App />);
