/* Endoxa — arbejdsværktøj (prototype). Klinisk beslutningsstøtte, RAG-stil.
   Pilotdomæne: hæmatologi · myelomatose & MGUS. */
const { useState, useRef, useEffect, useCallback } = React;
const KB = window.ENDOXA_KB;

/* ── Matchning af fri-tekst mod vidensgrundlaget ── */
function matchResponse(raw) {
  const t = raw.toLowerCase();
  // scenarie først
  if (KB.scenario.keywords.some((k) => t.includes(k))) {
    return { kind: "scenario", question: KB.scenario.question, answer: KB.scenario.answer };
  }
  // emner
  for (const topic of KB.topics) {
    if (topic.keywords.some((k) => t.includes(k))) {
      return { kind: "topic", question: topic.question, answer: topic.answer };
    }
  }
  // out of scope
  if (KB.outOfScopeKeywords.some((k) => t.includes(k.trim()))) {
    return { kind: "oos" };
  }
  return { kind: "fallback" };
}

/* ── Render af svar-blokke ── */
function Blocks({ blocks }) {
  return blocks.map((b, i) =>
    b.type === "para" ? (
      <p key={i} className="ai-para">{b.text}</p>
    ) : (
      <div key={i} className="ai-listwrap">
        <div className="ai-listtitle">{b.title}</div>
        <ul className="ai-list">
          {b.items.map((it, j) => <li key={j}>{it}</li>)}
        </ul>
      </div>
    )
  );
}

/* ── Kilde-chips ── */
function Citations({ ids, onOpen }) {
  if (!ids || !ids.length) return null;
  return (
    <div className="cites">
      <span className="cites-label">Kilder</span>
      {ids.map((id) => {
        const s = KB.sources[id];
        return (
          <button key={id} className="cite" onClick={() => onOpen(id)}>
            <span className="cite-lvl">{s.level}</span>
            <span className="cite-title">{s.title}</span>
          </button>
        );
      })}
    </div>
  );
}

/* ── En AI-besked ── */
function AiMessage({ msg, onOpen, onAction, onFollowup }) {
  if (msg.kind === "oos") {
    return (
      <div className="msg msg-ai">
        <div className="ai-avatar">E</div>
        <div className="ai-body ai-oos">
          <div className="oos-tag">Uden for vidensgrundlaget</div>
          <p className="ai-para">
            Det spørgsmål ligger uden for det aktuelle vidensgrundlag (hæmatologi: myelomatose og MGUS).
            Jeg finder ikke på et svar her. Kontakt relevant instans — fx hæmatologisk bagvagt eller
            den relevante specialrådgivning — eller vælg et hæmatologisk emne nedenfor.
          </p>
        </div>
      </div>
    );
  }
  if (msg.kind === "referral") {
    const d = KB.referralDraft;
    return (
      <div className="msg msg-ai">
        <div className="ai-avatar">E</div>
        <div className="ai-body">
          <div className="draft">
            <div className="draft-head">
              <span className="draft-dot" />{d.title}
            </div>
            <div className="draft-fields">
              {d.fields.map(([k, v], i) => (
                <div className="draft-row" key={i}>
                  <span className="draft-k">{k}</span>
                  <span className="draft-v">{v}</span>
                </div>
              ))}
            </div>
            <div className="draft-note">{d.note}</div>
          </div>
        </div>
      </div>
    );
  }
  return (
    <div className="msg msg-ai">
      <div className="ai-avatar">E</div>
      <div className="ai-body">
        {msg.note && <div className="ai-note">{msg.note}</div>}
        <Blocks blocks={msg.answer.blocks} />
        <Citations ids={msg.answer.citations} onOpen={onOpen} />
        {msg.answer.followup && !msg.followAnswered && (
          <div className="followup">
            <div className="followup-q">{msg.answer.followup.question}</div>
            <div className="followup-opts">
              {msg.answer.followup.options.map((o) => (
                <button key={o.label} className="fu-btn" onClick={() => onFollowup(msg, o)}>
                  {o.label}
                </button>
              ))}
            </div>
          </div>
        )}
        {msg.answer.actions && msg.answer.actions.includes("referral") && (
          <div className="ai-actions">
            <button className="act-btn" onClick={() => onAction("referral")}>
              <span className="act-ico">+</span> Generér henvisningsudkast
            </button>
            <div className="fb">
              <button className="fb-btn" title="Nyttigt svar">↑</button>
              <button className="fb-btn" title="Markér som muligt fejlagtigt">↓</button>
            </div>
          </div>
        )}
      </div>
    </div>
  );
}

/* ── Kilde-panel (skydeind) ── */
function SourcePanel({ id, onClose }) {
  if (!id) return null;
  const s = KB.sources[id];
  return (
    <>
      <div className="src-scrim" onClick={onClose} />
      <aside className="src-panel">
        <div className="src-top">
          <span className="src-kicker">Kilde i vidensgrundlaget</span>
          <button className="src-close" onClick={onClose}>✕</button>
        </div>
        <div className="src-badge">
          <span className="src-lvl">{s.level}</span>
          <span className="src-tag">{s.tag}</span>
        </div>
        <h3 className="src-title">{s.title}</h3>
        <div className="src-org">{s.org}</div>
        <div className="src-divider" />
        <div className="src-passage-label">Citeret passage</div>
        <p className="src-passage">{s.passage}</p>
        <div className="src-foot">
          Endoxa svarer udelukkende ud fra kuraterede kilder som denne. Indholdet her er
          illustrativt i prototypen.
        </div>
      </aside>
    </>
  );
}

/* ── Composer ── */
function Composer({ onSend, onImage }) {
  const [text, setText] = useState("");
  const [cpr, setCpr] = useState(false);
  const taRef = useRef(null);

  const check = (v) => { setText(v); setCpr(KB.cprRegex.test(v)); };
  const redact = () => { const v = text.replace(KB.cprRegex, "●●●●●●-●●●●"); setText(v); setCpr(false); };
  const submit = () => {
    if (!text.trim() || cpr) return;
    onSend(text.trim());
    setText(""); setCpr(false);
  };
  const onKey = (e) => {
    if (e.key === "Enter" && !e.shiftKey) { e.preventDefault(); submit(); }
  };
  useEffect(() => {
    const ta = taRef.current; if (!ta) return;
    ta.style.height = "auto"; ta.style.height = Math.min(ta.scrollHeight, 160) + "px";
  }, [text]);

  return (
    <div className="composer-wrap">
      {cpr && (
        <div className="cpr-warn">
          <span className="cpr-ico">!</span>
          <span>Personhenførbare oplysninger registreret (CPR-mønster). Fjern dem, før du sender.</span>
          <button className="cpr-fix" onClick={redact}>Fjern automatisk</button>
        </div>
      )}
      <div className={"composer" + (cpr ? " composer-flag" : "")}>
        <button className="comp-attach" title="Vedhæft laboratorieskema eller scanningssvar" onClick={onImage}>
          <svg viewBox="0 0 24 24" width="19" height="19" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M21 11.5l-8.6 8.6a5 5 0 0 1-7-7l8.5-8.6a3 3 0 0 1 4.3 4.3l-8.6 8.5a1 1 0 0 1-1.4-1.4l7.9-7.9"/></svg>
        </button>
        <textarea
          ref={taRef}
          className="comp-input"
          rows="1"
          autoFocus
          placeholder="Stil et klinisk spørgsmål om myelomatose eller MGUS…"
          value={text}
          onChange={(e) => check(e.target.value)}
          onKeyDown={onKey}
        />
        <button className="comp-send" disabled={!text.trim() || cpr} onClick={submit}>
          <svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"><path d="M5 12h14M13 6l6 6-6 6"/></svg>
        </button>
      </div>
      <div className="comp-hint">Ingen patientdata gemmes · CPR og navne afvises automatisk · Lægen har det sidste ord</div>
    </div>
  );
}

/* ── Hurtigknapper ── */
function QuickRow({ onPick }) {
  return (
    <div className="quickrow">
      {KB.starters.map((id) => {
        const t = KB.topics.find((x) => x.id === id);
        return <button key={id} className="quick" onClick={() => onPick(t)}>{t.label}</button>;
      })}
    </div>
  );
}

/* ── Velkomst ── */
function Welcome({ onPick }) {
  return (
    <div className="welcome">
      <div className="welcome-mark">E</div>
      <h1 className="welcome-h">Hvad kan jeg hjælpe med?</h1>
      <p className="welcome-sub">
        Start en dialog på dit eget sprog og få svar, der bygger på gældende danske
        vejledninger og forløbsbeskrivelser — med tydelig kildehenvisning.
      </p>
      <div className="welcome-chips-label">Hyppige spørgsmål</div>
      <div className="welcome-chips">
        {KB.topics.map((t) => (
          <button key={t.id} className="quick" onClick={() => onPick(t)}>{t.label}</button>
        ))}
      </div>
    </div>
  );
}

/* ── Sidebar ── */
function Sidebar() {
  const convos = [
    { t: "M-komponent 18 g/L — MGUS?", active: true, time: "Nu" },
    { t: "Blodprøver ved knoglesmerter", time: "I dag" },
    { t: "Kontrolinterval lavrisiko-MGUS", time: "I går" },
    { t: "Henvisning ved anæmi + M-komp.", time: "2 dage" },
  ];
  return (
    <aside className="sidebar">
      <div className="sb-brand">
        <svg className="sb-mark" viewBox="0 0 100 100" aria-hidden="true">
          <rect x="20" y="18" width="11" height="64" rx="4" fill="var(--ink)" />
          <rect x="31" y="18" width="46" height="12" rx="4" fill="color-mix(in oklab, var(--accent), white 52%)" />
          <rect x="31" y="44" width="33" height="12" rx="4" fill="color-mix(in oklab, var(--accent), white 22%)" />
          <rect x="31" y="70" width="46" height="12" rx="4" fill="var(--accent)" />
        </svg>
        Endoxa
      </div>
      <button className="sb-new"><span className="sb-plus">+</span> Ny samtale</button>
      <div className="sb-section">Seneste</div>
      <div className="sb-list">
        {convos.map((c, i) => (
          <button key={i} className={"sb-item" + (c.active ? " active" : "")}>
            <span className="sb-item-t">{c.t}</span>
            <span className="sb-item-time">{c.time}</span>
          </button>
        ))}
      </div>
      <div className="sb-kb">
        <div className="sb-kb-row"><span className="sb-kb-dot" /> Vidensgrundlag</div>
        <div className="sb-kb-meta">5 godkendte kilder · hæmatologi</div>
        <div className="sb-kb-meta">Vedligeholdt af klinisk styregruppe</div>
      </div>
    </aside>
  );
}

/* ── Topbar ── */
function TopBar() {
  return (
    <header className="topbar">
      <div className="tb-domain">
        <span className="tb-dot" />
        <div>
          <div className="tb-dname">Hæmatologi</div>
          <div className="tb-dsub">Myelomatose &amp; MGUS</div>
        </div>
        <span className="tb-caret">▾</span>
      </div>
      <div className="tb-right">
        <span className="tb-pill">Pilot · Region Nordjylland</span>
        <div className="tb-user">JK</div>
      </div>
    </header>
  );
}

/* ── App ── */
function App() {
  const [messages, setMessages] = useState([]);
  const [sourceId, setSourceId] = useState(null);
  const threadRef = useRef(null);

  const push = useCallback((m) => setMessages((prev) => [...prev, m]), []);

  useEffect(() => {
    const el = threadRef.current;
    if (el) el.scrollTop = el.scrollHeight;
  }, [messages]);

  const ask = useCallback((text) => {
    push({ role: "user", text });
    const r = matchResponse(text);
    setTimeout(() => {
      if (r.kind === "oos") push({ role: "ai", kind: "oos" });
      else if (r.kind === "fallback")
        push({
          role: "ai",
          note: "Jeg kunne ikke knytte spørgsmålet til en konkret kilde. Prøv at være mere specifik, eller vælg et emne:",
          answer: { blocks: [], citations: [] },
        });
      else push({ role: "ai", answer: r.answer, id: Math.random() });
    }, 240);
  }, [push]);

  const pickTopic = useCallback((topic) => {
    push({ role: "user", text: topic.question });
    setTimeout(() => push({ role: "ai", answer: topic.answer, id: Math.random() }), 240);
  }, [push]);

  const onImage = useCallback(() => {
    push({ role: "user", image: "Laboratorieskema.jpg" });
    setTimeout(() =>
      push({
        role: "ai",
        note: "Billedet er modtaget og anonymiseret automatisk — ingen CPR eller navne gemmes. Jeg tolker ikke billeder i denne prototype, men her er de prøver, der typisk vurderes:",
        answer: KB.topics.find((t) => t.id === "blodprover").answer,
      }), 300);
  }, [push]);

  const onAction = useCallback((kind) => {
    if (kind === "referral") setTimeout(() => push({ role: "ai", kind: "referral" }), 180);
  }, [push]);

  const onFollowup = useCallback((msg, opt) => {
    setMessages((prev) => prev.map((m) => (m === msg ? { ...m, followAnswered: true } : m)));
    push({ role: "user", text: opt.label });
    const resp = KB.followupResponses[opt.responseId];
    setTimeout(() => push({ role: "ai", answer: resp, id: Math.random() }), 240);
  }, [push]);

  const empty = messages.length === 0;

  return (
    <div className="app">
      <Sidebar />
      <main className="main">
        <div className="demo-banner">
          <span className="demo-dot" />
          <span><b>Demo</b> · indholdet er illustrativt og <b>ikke fagligt valideret</b> — ikke til klinisk brug. Indtast ikke patientidentificerbare data.</span>
        </div>
        <TopBar />
        <div className="thread" ref={threadRef}>
          <div className="thread-inner">
            {empty ? (
              <Welcome onPick={pickTopic} />
            ) : (
              messages.map((m, i) =>
                m.role === "user" ? (
                  <div className="msg msg-user" key={i}>
                    <div className="user-bubble">
                      {m.image ? (
                        <span className="user-img">
                          <span className="img-ico">▦</span>
                          <span>{m.image}</span>
                          <span className="img-anon">anonymiseret ✓</span>
                        </span>
                      ) : m.text}
                    </div>
                  </div>
                ) : (
                  <AiMessage key={i} msg={m} onOpen={setSourceId} onAction={onAction} onFollowup={onFollowup} />
                )
              )
            )}
          </div>
        </div>
        <div className={"dock" + (empty ? " empty-dock" : "")}>
          {!empty && <QuickRow onPick={pickTopic} />}
          <Composer onSend={ask} onImage={onImage} />
        </div>
      </main>
      <SourcePanel id={sourceId} onClose={() => setSourceId(null)} />
    </div>
  );
}

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