// ─── WIKI — Lore Codex ────────────────────────────────────
const WikiScreen = ({ entryId, setEntryId }) => {
  const [cat, setCat] = React.useState("all");
  const [query, setQuery] = React.useState("");

  const entry = entryId ? window.WIKI.find(w => w.id === entryId) : null;

  if (entry) return <WikiDetail entry={entry} onBack={() => setEntryId(null)} setEntryId={setEntryId}/>;

  const filtered = window.WIKI.filter(w => {
    if (cat !== "all" && w.cat !== cat) return false;
    if (query && !(w.title.toLowerCase().includes(query.toLowerCase()) || w.desc.toLowerCase().includes(query.toLowerCase()))) return false;
    return true;
  });

  return (
    <div className="content-pad" data-screen-label="02 Wiki">
      <div className="page-head">
        <div>
          <div className="page-title display">Codex</div>
          <div className="page-sub">
            Gameplay systems and how they work under the hood ·
            <span className="mono" style={{ marginLeft: 6 }}>{window.WIKI.length} entries</span> ·
            <span style={{ marginLeft: 6 }}>sourced from /Obsidian/HUSK</span>
          </div>
        </div>
        <div className="right">
          <div className="search" style={{ minWidth: 220 }}>
            <Icon name="search" size={13}/>
            <input
              value={query}
              onChange={e => setQuery(e.target.value)}
              placeholder="Search the codex…"
              style={{ background: "transparent", border: 0, outline: 0, flex: 1, color: "var(--text)" }}
            />
          </div>
          <button className="btn"><Icon name="plus" size={13}/> New entry</button>
        </div>
      </div>

      <div className="wiki-layout">
        {/* SIDEBAR — categories */}
        <div className="wiki-side">
          <div className="nav-label">Categories</div>
          <button className={`wiki-cat ${cat === "all" ? "is-active" : ""}`} onClick={() => setCat("all")}>
            <span>All systems</span><span className="count">{window.WIKI.length}</span>
          </button>
          {window.WIKI_CATS.map(c => {
            const n = window.WIKI.filter(w => w.cat === c.id).length;
            return (
              <button key={c.id} className={`wiki-cat ${cat === c.id ? "is-active" : ""}`} onClick={() => setCat(c.id)}>
                <span>{c.label}</span><span className="count">{n}</span>
              </button>
            );
          })}

          <div className="nav-label" style={{ marginTop: 16 }}>Vault</div>
          <div className="muted small" style={{ padding: "4px 10px", lineHeight: 1.6 }}>
            <div><span className="status-dot done" style={{ marginRight: 6 }}/>Synced from Obsidian</div>
            <div style={{ marginTop: 4 }} className="mono">main/notes/HUSK</div>
          </div>
        </div>

        {/* CARDS */}
        <div>
          <div className="codex-grid">
            {filtered.map(w => <CodexCard key={w.id} w={w} onOpen={() => setEntryId(w.id)}/>)}
          </div>
          {filtered.length === 0 && <div className="empty">No entries match.</div>}
        </div>
      </div>
    </div>
  );
};

// Card thumbnail — abstract per category, no AI slop
const CodexThumb = ({ w }) => {
  const palettes = {
    perception:  ["#3a2647", "#7a3a8a", "#c98aff"],
    ai:          ["#3a1d20", "#6f2026", "#ff6a85"],
    world:       ["#1f2a1c", "#3a5435", "#9bc983"],
    interaction: ["#3a2a1a", "#6e4724", "#ffb16a"],
    narrative:   ["#3a1f2c", "#76304e", "#ff8ab8"],
    core:        ["#1f2933", "#365171", "#6aa6ff"],
    tech:        ["#23262d", "#3a3f4b", "#9aa3b2"],
  };
  const [a, b, c] = palettes[w.cat] || palettes.tech;
  // pick visual based on category
  if (w.cat === "perception") return (
    <svg width="100%" height="100%" viewBox="0 0 260 110" preserveAspectRatio="none" style={{ display: "block" }}>
      <defs>
        <radialGradient id={`g-${w.id}`} cx="50%" cy="55%" r="70%">
          <stop offset="0%" stopColor={c} stopOpacity="0.55"/>
          <stop offset="60%" stopColor={b} stopOpacity="0.3"/>
          <stop offset="100%" stopColor={a} stopOpacity="0.9"/>
        </radialGradient>
      </defs>
      <rect width="260" height="110" fill={a}/>
      <rect width="260" height="110" fill={`url(#g-${w.id})`}/>
      {/* concentric rings */}
      {[20, 38, 56, 74].map((r, i) => (
        <circle key={i} cx="130" cy="60" r={r} fill="none" stroke={c} strokeOpacity={0.18 + i * 0.05} strokeWidth="1"/>
      ))}
      <circle cx="130" cy="60" r="3" fill={c}/>
    </svg>
  );
  if (w.cat === "ai") return (
    <svg width="100%" height="100%" viewBox="0 0 260 110" preserveAspectRatio="none" style={{ display: "block" }}>
      <rect width="260" height="110" fill={a}/>
      {/* Husk silhouette */}
      <g fill="none" stroke={c} strokeOpacity="0.7" strokeWidth="1.2">
        <path d="M120 80 L120 30 M120 30 L110 22 M120 30 L130 22 M120 45 L100 55 M120 45 L140 55 M120 80 L108 100 M120 80 L132 100"/>
        <circle cx="120" cy="20" r="6"/>
      </g>
      <g fill={b} opacity="0.4">
        <circle cx="60" cy="40" r="2"/><circle cx="200" cy="35" r="2"/>
        <circle cx="40" cy="80" r="1.5"/><circle cx="220" cy="75" r="2.5"/>
        <circle cx="180" cy="90" r="1.5"/><circle cx="80" cy="90" r="2"/>
      </g>
    </svg>
  );
  if (w.cat === "world") return (
    <svg width="100%" height="100%" viewBox="0 0 260 110" preserveAspectRatio="none" style={{ display: "block" }}>
      <rect width="260" height="110" fill={a}/>
      {/* horizon + grain */}
      <rect x="0" y="60" width="260" height="50" fill={b} opacity="0.6"/>
      <g stroke={c} strokeWidth="0.8" opacity="0.4">
        {Array.from({ length: 24 }).map((_, i) => (
          <line key={i} x1={i * 12} y1="60" x2={i * 12 - 4} y2="105"/>
        ))}
      </g>
      <circle cx="200" cy="40" r="14" fill={c} opacity="0.25"/>
    </svg>
  );
  if (w.cat === "interaction") return (
    <svg width="100%" height="100%" viewBox="0 0 260 110" preserveAspectRatio="none" style={{ display: "block" }}>
      <rect width="260" height="110" fill={a}/>
      <radialGradient id={`l-${w.id}`} cx="50%" cy="50%" r="40%">
        <stop offset="0%" stopColor={c} stopOpacity="0.7"/>
        <stop offset="100%" stopColor={a} stopOpacity="0"/>
      </radialGradient>
      <circle cx="130" cy="55" r="50" fill={`url(#l-${w.id})`}/>
      {/* lantern */}
      <g fill="none" stroke={c} strokeWidth="1.2">
        <rect x="122" y="48" width="16" height="20" rx="1"/>
        <line x1="130" y1="44" x2="130" y2="48"/>
        <path d="M122 56 L138 56"/>
      </g>
    </svg>
  );
  if (w.cat === "narrative") return (
    <svg width="100%" height="100%" viewBox="0 0 260 110" preserveAspectRatio="none" style={{ display: "block" }}>
      <rect width="260" height="110" fill={a}/>
      <g fill={c} opacity="0.7">
        <rect x="80" y="30" width="100" height="2"/>
        <rect x="80" y="40" width="80" height="2"/>
        <rect x="80" y="50" width="90" height="2"/>
        <rect x="80" y="60" width="70" height="2"/>
        <rect x="80" y="70" width="85" height="2"/>
        <rect x="80" y="80" width="60" height="2"/>
      </g>
    </svg>
  );
  if (w.cat === "core") return (
    <svg width="100%" height="100%" viewBox="0 0 260 110" preserveAspectRatio="none" style={{ display: "block" }}>
      <rect width="260" height="110" fill={a}/>
      {/* loop diagram */}
      <g fill="none" stroke={c} strokeOpacity="0.7" strokeWidth="1.5">
        <path d="M70 55 a40 25 0 1 1 120 0 a40 25 0 1 1 -120 0" strokeDasharray="4 4"/>
        <polygon points="186,50 196,55 186,60" fill={c}/>
      </g>
      <g fill={c}>
        <circle cx="70" cy="55" r="3"/>
        <circle cx="130" cy="30" r="3"/>
        <circle cx="190" cy="55" r="3"/>
        <circle cx="130" cy="80" r="3"/>
      </g>
    </svg>
  );
  // tech default
  return (
    <svg width="100%" height="100%" viewBox="0 0 260 110" preserveAspectRatio="none" style={{ display: "block" }}>
      <rect width="260" height="110" fill={a}/>
      <g fill={c} opacity="0.5" fontFamily="monospace" fontSize="8">
        {Array.from({ length: 11 }).map((_, i) => (
          <text key={i} x="20" y={14 + i * 8}>{`> ${"████░▒▓".repeat(2).slice(i, i + 18)}`}</text>
        ))}
      </g>
    </svg>
  );
};

const CodexCard = ({ w, onOpen }) => {
  const cat = (window.WIKI_CATS.find(c => c.id === w.cat) || {}).label || w.cat;
  return (
    <div className="codex-card" onClick={onOpen}>
      <div className="codex-thumb">
        <CodexThumb w={w}/>
        <span className="codex-id">{w.id}</span>
        <span className="codex-cat chip" style={{ background: "var(--bg-2)", borderColor: "var(--line)" }}>{cat}</span>
      </div>
      <div className="codex-body">
        <div className="codex-title">{w.title}</div>
        <div className="codex-desc">{w.desc}</div>
        <div className="codex-meta">
          {w.tags.map(t => <TagChip key={t} tag={t}/>)}
          <span className="chip muted" style={{ marginLeft: "auto" }}>{w.updated}</span>
        </div>
      </div>
    </div>
  );
};

const WikiDetail = ({ entry, onBack, setEntryId }) => {
  const cat = (window.WIKI_CATS.find(c => c.id === entry.cat) || {}).label || entry.cat;
  const author = window.TEAM.find(t => t.id === entry.author);
  return (
    <div className="content-pad" data-screen-label="02 Wiki — entry">
      <div className="row" style={{ marginBottom: 18, gap: 8, color: "var(--text-mute)", fontSize: 12.5 }}>
        <button className="btn ghost small" onClick={onBack}><Icon name="chevron-l" size={13}/> Codex</button>
        <span>/</span>
        <span>{cat}</span>
        <span>/</span>
        <span className="mono">{entry.id}</span>
        <div className="spacer"/>
        <button className="btn ghost small"><Icon name="link" size={12}/> Copy link</button>
        <button className="btn ghost small"><Icon name="edit" size={12}/> Edit in Obsidian</button>
      </div>

      <div className="wiki-detail">
        <div className="wiki-doc">
          <h1>{entry.title}</h1>
          <div className="doc-sub">{entry.desc}</div>
          <div className="row" style={{ gap: 6, flexWrap: "wrap" }}>
            {entry.tags.map(t => <TagChip key={t} tag={t}/>)}
          </div>

          <hr className="hr"/>

          {entry.body.map((b, i) => {
            if (b.type === "h2") return <h2 key={i}>{b.text}</h2>;
            if (b.type === "h3") return <h3 key={i}>{b.text}</h3>;
            if (b.type === "p") return <p key={i}>{renderInline(b.text, setEntryId)}</p>;
            if (b.type === "ul") return <ul key={i}>{b.items.map((it, j) => <li key={j}>{renderInline(it, setEntryId)}</li>)}</ul>;
            if (b.type === "callout") return <div className="callout" key={i}>{b.text}</div>;
            return null;
          })}
        </div>

        <aside className="wiki-meta-panel">
          <div className="card">
            <div className="card-head"><div className="card-title">Metadata</div></div>
            <div className="card-body" style={{ paddingTop: 4, paddingBottom: 4 }}>
              <div className="meta-row"><div className="k">ID</div><div className="v mono">{entry.id}</div></div>
              <div className="meta-row"><div className="k">Category</div><div className="v">{cat}</div></div>
              <div className="meta-row"><div className="k">Owner</div><div className="v"><Avatar id={entry.author} size={18}/> <span style={{ marginLeft: 6 }}>{author?.name}</span></div></div>
              <div className="meta-row"><div className="k">Updated</div><div className="v">{entry.updated}</div></div>
              <div className="meta-row"><div className="k">Tags</div><div className="v"><div className="tag-strip">{entry.tags.map(t => <TagChip key={t} tag={t}/>)}</div></div></div>
            </div>
          </div>

          <div className="card" style={{ marginTop: 14 }}>
            <div className="card-head"><div className="card-title">Related</div></div>
            <div className="card-body" style={{ padding: 6 }}>
              <div className="backlinks-list">
                {(entry.related || []).map(rid => {
                  const r = window.WIKI.find(w => w.id === rid);
                  if (!r) return null;
                  return (
                    <a key={rid} onClick={() => setEntryId(rid)}>
                      <Icon name="branch" size={12} className="muted"/>
                      <span className="mono small muted">{rid}</span>
                      <span>{r.title}</span>
                    </a>
                  );
                })}
                {(!entry.related || entry.related.length === 0) && <div className="muted small" style={{ padding: "6px 8px" }}>No links yet.</div>}
              </div>
            </div>
          </div>

          <div className="card" style={{ marginTop: 14 }}>
            <div className="card-head"><div className="card-title">Linked tasks</div></div>
            <div className="card-body" style={{ padding: 6 }}>
              <div className="backlinks-list">
                {window.TASKS.filter(t => t.desc.includes(entry.id) || t.title.toLowerCase().includes(entry.title.split(" ")[0].toLowerCase())).slice(0, 4).map(t => (
                  <a key={t.id}>
                    <StatusDot status={t.col}/>
                    <span className="mono small muted">{t.id}</span>
                    <span style={{ overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{t.title}</span>
                  </a>
                ))}
              </div>
            </div>
          </div>
        </aside>
      </div>
    </div>
  );
};

// Render inline text, converting [[wiki links]] to clickable spans
function renderInline(text, setEntryId) {
  // simple parser for SYS-XXX or [[Title]] references — convert SYS-XXX into wlinks
  const parts = text.split(/(SYS-\d+[a-z]?|LORE-\d+|TECH-\d+)/g);
  return parts.map((p, i) => {
    if (/^(SYS|LORE|TECH)-\d+[a-z]?$/.test(p)) {
      const found = window.WIKI.find(w => w.id === p);
      if (found) return <span key={i} className="wlink mono" onClick={() => setEntryId(p)}>{p}</span>;
    }
    return <React.Fragment key={i}>{p}</React.Fragment>;
  });
}

window.WikiScreen = WikiScreen;
