/* global React, Emblem */
// ============================================================
//  AI Lawyer — UI components (LIVE verzija)
// ============================================================

/* ====================== THINKING PANEL (faze + izreki) ====================== */
const LEGAL_MAXIMS = [
  { la: "Audiatur et altera pars", si: "Naj se sliši tudi druga stran.", en: "Let the other side be heard as well.", de: "Auch die andere Seite soll gehört werden." },
  { la: "In dubio pro reo", si: "V dvomu v korist obdolženca.", en: "When in doubt, for the accused.", de: "Im Zweifel für den Angeklagten." },
  { la: "Nulla poena sine lege", si: "Ni kazni brez zakona.", en: "No penalty without a law.", de: "Keine Strafe ohne Gesetz." },
  { la: "Pacta sunt servanda", si: "Dogovore je treba spoštovati.", en: "Agreements must be kept.", de: "Verträge sind einzuhalten." },
  { la: "Dura lex, sed lex", si: "Zakon je trd, a je zakon.", en: "The law is harsh, but it is the law.", de: "Das Gesetz ist hart, aber es ist Gesetz." },
  { la: "Ignorantia iuris nocet", si: "Nepoznavanje prava škoduje.", en: "Ignorance of the law is harmful.", de: "Unkenntnis des Rechts schadet." },
  { la: "Ubi ius, ibi remedium", si: "Kjer je pravica, je tudi pravno sredstvo.", en: "Where there is a right, there is a remedy.", de: "Wo ein Recht ist, ist auch ein Rechtsbehelf." },
  { la: "Onus probandi", si: "Dokazno breme nosi, kdor trdi.", en: "The burden of proof lies on who asserts.", de: "Die Beweislast trägt, wer behauptet." },
  { la: "Lex specialis derogat legi generali", si: "Posebni zakon razveljavi splošnega.", en: "A specific law overrides a general one.", de: "Das spezielle Gesetz verdrängt das allgemeine." },
  { la: "Nemo iudex in causa sua", si: "Nihče ne more biti sodnik v lastni zadevi.", en: "No one should be a judge in his own cause.", de: "Niemand soll Richter in eigener Sache sein." },
  { la: "Fiat iustitia", si: "Naj se zgodi pravica.", en: "Let justice be done.", de: "Es geschehe Gerechtigkeit." },
  { la: "Iustitia est constans voluntas", si: "Pravičnost je stalna volja vsakomur priznati svoje.", en: "Justice is the constant will to render each his due.", de: "Gerechtigkeit ist der beständige Wille, jedem das Seine zu geben." },
  { la: "Summum ius, summa iniuria", si: "Najvišje pravo je lahko največja krivica.", en: "The highest law can be the greatest injustice.", de: "Höchstes Recht, höchstes Unrecht." },
  { la: "Veritas numquam perit", si: "Resnica nikoli ne propade. (Seneka)", en: "Truth never perishes. (Seneca)", de: "Die Wahrheit geht niemals zugrunde. (Seneca)" },
  { la: "Cui bono?", si: "V čigavo korist? (Ciceron)", en: "To whose benefit? (Cicero)", de: "Wem zum Vorteil? (Cicero)" },
];

const PHASES = {
  si: ["Analiziram zadevo", "Iščem sodbe in zakone v uradnih bazah", "Modeli pišejo neodvisna mnenja", "Pripravljam konsolidirano sintezo"],
  en: ["Analyzing the case", "Searching official case-law and statutes", "Models are writing independent opinions", "Preparing the consolidated synthesis"],
  de: ["Fall wird analysiert", "Suche in amtlichen Rechtsquellen", "Modelle verfassen unabhängige Gutachten", "Konsolidierte Synthese wird erstellt"],
};

// faze za hitri Sonnet referent (krajse od panela)
const CHAT_PHASES = {
  si: ["Berem vaše sporočilo", "Pregledujem zadevo in dokumente", "Pripravljam odgovor"],
  en: ["Reading your message", "Reviewing the case and documents", "Drafting the reply"],
  de: ["Ihre Nachricht wird gelesen", "Sachverhalt und Dokumente werden geprüft", "Antwort wird vorbereitet"],
};

function SonnetThinking({ lang, label }) {
  const L = (CHAT_PHASES[lang] || CHAT_PHASES.de);
  const [phase, setPhase] = React.useState(0);
  React.useEffect(() => {
    const times = [0, 4000, 9000];
    const timers = times.map((ms, i) => setTimeout(() => setPhase(i), ms));
    return () => timers.forEach(clearTimeout);
  }, []);
  return (
    <div className="think-panel chat-think">
      <div className="think-phase">
        <span className="dots3"><span/><span/><span/></span>
        <div className="tp-steps">
          {L.map((step, i) => (
            <div key={i} className={"tp-step" + (i === phase ? " active" : "") + (i < phase ? " done" : "")}>
              <span className="tp-mark">{i < phase ? "✓" : (i === phase ? "▸" : "·")}</span> {step}
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

function ThinkingPanel({ lang, label }) {
  const L = (PHASES[lang] || PHASES.si);
  const [phase, setPhase] = React.useState(0);
  const [mIdx, setMIdx] = React.useState(() => Math.floor(Math.random() * LEGAL_MAXIMS.length));
  const [fade, setFade] = React.useState(true);
  React.useEffect(() => {
    // faze napredujejo po ocenjenem casu (ni tocna sinhronizacija z backendom)
    const times = [0, 12000, 30000, 110000]; // ~kdaj naj se prikaze posamezna faza
    const timers = times.map((ms, i) => setTimeout(() => setPhase(i), ms));
    return () => timers.forEach(clearTimeout);
  }, []);
  React.useEffect(() => {
    const iv = setInterval(() => {
      setFade(false);
      setTimeout(() => {
        setMIdx(i => (i + 1) % LEGAL_MAXIMS.length);
        setFade(true);
      }, 400);
    }, 5200);
    return () => clearInterval(iv);
  }, []);
  const m = LEGAL_MAXIMS[mIdx];
  const trans = lang === "en" ? m.en : (lang === "de" ? m.de : m.si);
  return (
    <div className="think-panel">
      <div className="think-phase">
        <span className="dots3"><span/><span/><span/></span>
        <div className="tp-steps">
          {L.map((step, i) => (
            <div key={i} className={"tp-step" + (i === phase ? " active" : "") + (i < phase ? " done" : "")}>
              <span className="tp-mark">{i < phase ? "✓" : (i === phase ? "▸" : "·")}</span> {step}
            </div>
          ))}
        </div>
      </div>
      <div className={"think-maxim" + (fade ? " in" : " out")}>
        <div className="tm-la">{m.la}</div>
        <div className="tm-tr">{trans}</div>
      </div>
    </div>
  );
}

function Icon({ name, size = 16, color = "currentColor", w = 1.8 }) {
  const p = { fill: "none", stroke: color, strokeWidth: w, strokeLinecap: "round", strokeLinejoin: "round" };
  const paths = {
    plus:  <g {...p}><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></g>,
    clip:  <g {...p}><path d="M21 11.5l-8.5 8.5a4.5 4.5 0 0 1-6.4-6.4l8.7-8.7a3 3 0 0 1 4.3 4.3l-8.7 8.7a1.5 1.5 0 0 1-2.1-2.1l7.9-7.9"/></g>,
    bolt:  <g {...p}><path d="M13 2L4.5 13.5H11l-1 8.5L19.5 10H13l0-8z"/></g>,
    scale: <g {...p}><path d="M12 3v18M7 21h10M12 5l-7 2 3 6a3 3 0 0 1-6 0l3-6M12 5l7 2-3 6a3 3 0 0 0 6 0l-3-6"/></g>,
    send:  <g {...p}><line x1="12" y1="19" x2="12" y2="5"/><path d="M6 11l6-6 6 6"/></g>,
    chev:  <g {...p}><path d="M6 9l6 6 6-6"/></g>,
    copy:  <g {...p}><rect x="9" y="9" width="11" height="11" rx="2"/><path d="M5 15V5a2 2 0 0 1 2-2h8"/></g>,
    dl:    <g {...p}><path d="M12 4v11"/><path d="M7 11l5 5 5-5"/><path d="M5 20h14"/></g>,
    out:   <g {...p}><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/><path d="M16 17l5-5-5-5"/><line x1="21" y1="12" x2="9" y2="12"/></g>,
    menu:  <g {...p}><line x1="3" y1="6" x2="21" y2="6"/><line x1="3" y1="12" x2="21" y2="12"/><line x1="3" y1="18" x2="21" y2="18"/></g>,
    mic:   <g {...p}><rect x="9" y="3" width="6" height="11" rx="3"/><path d="M5 11a7 7 0 0 0 14 0"/><line x1="12" y1="18" x2="12" y2="21"/><line x1="8" y1="21" x2="16" y2="21"/></g>,
    x:     <g {...p}><line x1="6" y1="6" x2="18" y2="18"/><line x1="18" y1="6" x2="6" y2="18"/></g>,
    pencil: <g {...p}><path d="M12 20h9"/><path d="M16.5 3.5a2.12 2.12 0 0 1 3 3L7 19l-4 1 1-4Z"/></g>,
    trash: <g {...p}><polyline points="3 6 5 6 21 6"/><path d="M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6"/><path d="M10 11v6M14 11v6"/><path d="M9 6V4a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2"/></g>,
  };
  return <svg width={size} height={size} viewBox="0 0 24 24" aria-hidden="true">{paths[name]}</svg>;
}

/* ============================== SIDEBAR ============================== */
/* ============================== DELETE MODAL ============================== */
function DeleteModal({ t, title, onCancel, onConfirm }) {
  const ui = t.ui;
  const [code] = React.useState(() => {
    const cs = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789";
    let s = ""; for (let i = 0; i < 6; i++) s += cs[Math.floor(Math.random() * cs.length)];
    return s;
  });
  const [typed, setTyped] = React.useState("");
  const match = typed.trim().toUpperCase() === code;
  React.useEffect(() => {
    const onKey = (e) => { if (e.key === "Escape") onCancel(); };
    document.addEventListener("keydown", onKey);
    return () => document.removeEventListener("keydown", onKey);
  }, [onCancel]);
  return (
    <div className="modal-overlay" onClick={onCancel}>
      <div className="modal del-modal" onClick={(e) => e.stopPropagation()}>
        <div className="modal-icon"><Icon name="trash" size={22} /></div>
        <h3>{ui.delTitle || "Izbris pogovora"}</h3>
        <p className="del-q">
          {(ui.delBody || "Res želite trajno izbrisati pogovor")} <strong>{title || "—"}</strong>?
        </p>
        <p className="del-warn">{ui.delWarn || "To dejanje je nepovratno — pogovor in vsi dokumenti bodo izbrisani z diska."}</p>
        <div className="del-code-row">
          <span className="del-code-lbl">{ui.delCodeLbl || "Za potrditev prepišite kodo:"}</span>
          <span className="del-code">{code}</span>
        </div>
        <input className="del-input" type="text" value={typed} autoFocus
          placeholder={code}
          onChange={(e) => setTyped(e.target.value)}
          onKeyDown={(e) => { if (e.key === "Enter" && match) onConfirm(); }} />
        <div className="modal-actions">
          <button className="btn-ghost" onClick={onCancel}>{ui.cancel || "Prekliči"}</button>
          <button className="btn-danger" disabled={!match} onClick={onConfirm}>
            {ui.delConfirm || "Trajno izbriši"}
          </button>
        </div>
      </div>
    </div>
  );
}

function Sidebar({ t, conversations, activeId, onSelect, onNew, onLogout, mobileOpen, onClose, search, onRename, onDelete }) {
  const ui = t.ui;
  const q = search ? search.query : "";
  const results = (search && search.results) || [];
  const searching = q.trim().length >= 2;
  return (
    <aside className={"sidebar" + (mobileOpen ? " mobile-open" : "")}>
      <div className="sb-brand">
        <Emblem size={42} variant="badge" />
        <div className="wordmark">
          <span className="name">AI <em>Lawyer</em></span>
          <span className="sub">{ui.brandSub}</span>
        </div>
        <button className="sb-close" onClick={onClose} aria-label="Close"><Icon name="x" size={20} /></button>
      </div>
      <button className="sb-new" onClick={onNew}>
        <span className="plus"><Icon name="plus" size={16} color="#c6a468" /></span>
        {ui.newConv}
      </button>
      <div className="sb-search">
        <input type="text" value={q} placeholder={ui.searchPh || "Iskanje…"}
          onChange={(e) => search && search.setQuery(e.target.value)} />
        {q && <button className="sb-search-x" onClick={() => search && search.setQuery("")} aria-label="clear"><Icon name="x" size={14} /></button>}
      </div>
      <div className="sb-list scroll scroll-navy">
        {searching ? (
          results.length === 0
            ? <div className="sb-empty">{ui.searchNo || "Ni zadetkov"}</div>
            : results.map((r) => (
                <button key={r.id} className="sb-item sb-result" onClick={() => onSelect(r.id)}>
                  <div className="t">{r.title}</div>
                  {r.matches.slice(0, 3).map((m, i) => (
                    <div key={i} className="sb-snip">
                      {m.where === "document"
                        ? <span className="sb-snip-tag">📎 {m.filename}</span>
                        : null}
                      <span className="sb-snip-txt">{m.snippet}</span>
                    </div>
                  ))}
                </button>
              ))
        ) : (
          <React.Fragment>
            <div className="sb-group-label">{ui.thisWeek}</div>
            {conversations.map((c) => (
              <div key={c.id}
                className={"sb-item" + (c.id === activeId ? " active" : "")}
                onClick={() => onSelect(c.id)}>
                <div className="sb-item-main">
                  <div className="t">{c.title}</div>
                  {(c.ago || c.count !== "") && (
                    <div className="meta">
                      <span>{c.ago}</span>
                      {c.count !== "" && <span className="pill">{c.count} ⟡</span>}
                    </div>
                  )}
                </div>
                <div className="sb-actions">
                  <button className="sb-act" title={ui.renameTitle || "Preimenuj"}
                    onClick={(e) => { e.stopPropagation(); onRename && onRename(c); }}>
                    <Icon name="pencil" size={14} />
                  </button>
                  <button className="sb-act sb-act-del" title={ui.deleteTitle || "Izbriši"}
                    onClick={(e) => { e.stopPropagation(); onDelete && onDelete(c); }}>
                    <Icon name="trash" size={14} />
                  </button>
                </div>
              </div>
            ))}
            {conversations.length === 0 && <div className="sb-empty">{ui.noConvs || "Ni pogovorov"}</div>}
          </React.Fragment>
        )}
      </div>
      <div className="sidebar-foot">
        <div className="sf-name">Rechtsanwalt Michael A.C. Ashcroft</div>
        <div className="sf-sub">Fachanwalt für Sozialrecht · Fachanwalt für Familienrecht</div>
      </div>
    </aside>
  );
}

/* ============================== TOPBAR ============================== */
function LangSwitch({ lang, setLang, busy }) {
  return null;  // SAMO NEMSCINA - stikalo skrito
  const order = ["de", "en", "si"];
  const [open, setOpen] = React.useState(false);
  const ref = React.useRef(null);
  React.useEffect(() => {
    if (!open) return;
    const onDoc = (e) => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); };
    document.addEventListener("mousedown", onDoc);
    return () => document.removeEventListener("mousedown", onDoc);
  }, [open]);
  const pick = (code) => { if (busy) return; setLang(code); setOpen(false); };
  return (
    <div className={"lang" + (open ? " open" : "")} role="group" aria-label="Language" ref={ref}>
      {/* namizje: vse tri v vrsti */}
      <div className="lang-row">
        {order.map(code => (
          <button key={code} className={lang === code ? "on" : ""} disabled={busy}
            onClick={() => { if (!busy) setLang(code); }}>
            {window.I18N[code].label}
          </button>
        ))}
      </div>
      {/* mobilno: strnjen gumb + spustni meni */}
      <div className="lang-compact">
        <button className="lang-cur" disabled={busy} onClick={() => { if (!busy) setOpen(!open); }}>
          {window.I18N[lang].label}
          <Icon name="chev" size={12} />
        </button>
        {open && (
          <div className="lang-menu">
            {order.map(code => (
              <button key={code} className={lang === code ? "on" : ""} onClick={() => pick(code)}>
                {window.I18N[code].label}
              </button>
            ))}
          </div>
        )}
      </div>
    </div>
  );
}
function TopBar({ t, title, lang, setLang, onLogout, onMenu, usage, busy }) {
  return (
    <header className="topbar">
      <button className="tb-menu" onClick={onMenu} aria-label="Menu"><Icon name="menu" size={22} /></button>
      <div className="tb-left">
        <div className="tb-title">
          <div className="h">{title}</div>
          <div className="panel-dots">
            <span className="lbl">{t.ui.brandSub}</span>
            {window.MODEL_META.map(m => (
              <span key={m.id} className="d" style={{ background: m.hue }} />
            ))}
          </div>
        </div>
      </div>
      <div className="tb-right">
        {usage && (
          <div className="usage-pill" title={t.ui.usageMonthTitle || "Poraba ta mesec"}>
            <span className="up-lbl">{usage.month_label}</span>
            <span className="up-val">${usage.month_cost.toFixed(2)}</span>
          </div>
        )}
        <LangSwitch lang={lang} setLang={setLang} busy={busy} />
        <button className="ghost-btn" onClick={onLogout}>
          <Icon name="out" size={15} /> {t.ui.logout}
        </button>
      </div>
    </header>
  );
}

/* ============================== INTAKE BLOCK ============================== */
function IntakeBlock({ t, content }) {
  const [open, setOpen] = React.useState(() => (typeof window !== "undefined" ? window.innerWidth > 860 : true));
  const ui = t.ui;
  // content je lahko JSON (@@INTAKE_JSON@@{...}) ali navaden markdown (starejsi zapisi)
  let data = null;
  if (typeof content === "string" && content.indexOf("@@INTAKE_JSON@@") === 0) {
    try { data = JSON.parse(content.slice("@@INTAKE_JSON@@".length)); } catch (e) { data = null; }
  }
  const row = (label, val) => val ? (
    <p><b>{label}:</b> {val}</p>
  ) : null;
  return (
    <div className={"intake" + (open ? " open" : "")}>
      <button className="intake-head" onClick={() => setOpen(!open)}>
        <span className="lab">{ui.intakeLabel || "Fallanalyse"}</span>
        <span className="chev"><Icon name="chev" size={14} /></span>
      </button>
      {open && (data ? (
        <div className="intake-body">
          {row(ui.inSummary || "Summary", data.summary)}
          {row(ui.inGoal || "Goal", data.goal)}
          {row(ui.inTask || "Task", data.task)}
          <p className="intake-meta">
            {(ui.inArea || "Area")}: {data.legal_area} · {(ui.inJuris || "Jurisdiction")}: {data.jurisdiction} · {(ui.inMode || "Mode")}: {(ui.modes && ui.modes[data.mode]) || data.mode}
          </p>
        </div>
      ) : (
        <div className="intake-body" dangerouslySetInnerHTML={{ __html: window.mdToHtml(content) }} />
      ))}
    </div>
  );
}

/* ============================== MODEL CARD ============================== */
function ModelCard({ meta, model, open, onToggle, t }) {
  const thinking = model.status === "thinking";
  return (
    <button className={"mcard" + (open ? " open" : "") + (thinking ? " thinking" : "")}
      onClick={() => !thinking && onToggle()}>
      <div className="top">
        <span className="dot" style={{ background: thinking ? "#c9cdd4" : (meta ? meta.hue : "#888") }} />
        <span className="nm">{model.label || (meta && meta.name) || model.model}</span>
        {!thinking && <span className="chev"><Icon name="chev" size={13} /></span>}
      </div>
      {thinking ? (
        <div className="dots3"><span/><span/><span/></div>
      ) : (
        <div className={"body" + (open ? "" : " clamp")}
          dangerouslySetInnerHTML={{ __html: window.mdToHtml(model.answer) }} />
      )}
    </button>
  );
}

/* ============================== EXCHANGE BLOCK ============================== */
// povezuje Panel (seznam modelov) in Synthesis (klik na znacko modela odpre odgovor)
function ExchangeBlock({ t, ex, lang, convId }) {
  const [sel, setSel] = React.useState(0);
  const panelRef = React.useRef(null);
  const idForModel = (mid) => {
    // mid: opus|gpt|gemini|grok|deepseek|mistral -> indeks v ex.models
    const map = { opus: "opus", gpt: "gpt", gemini: "gemini", grok: "grok", deepseek: "deepseek", mistral: "mistral" };
    const key = map[mid] || mid;
    const idx = ex.models.findIndex(m => {
      const s = ((m.model || "") + " " + (m.label || "")).toLowerCase();
      return s.includes(key);
    });
    return idx;
  };
  const onModelClick = (mid) => {
    const idx = idForModel(mid);
    if (idx >= 0) {
      setSel(idx);
      if (panelRef.current) panelRef.current.scrollIntoView({ behavior: "smooth", block: "center" });
    }
  };
  return (
    <React.Fragment>
      {(ex.models.length > 0 || ex.pending) &&
        <Panel t={t} models={ex.models} allDone={ex.allDone} pending={ex.pending}
          selIdx={ex.pending ? undefined : sel} onSel={setSel} panelRef={panelRef} />}
      {ex.allDone && ex.synthText &&
        <SynthesisHero t={t} content={ex.synthText} lang={lang} convId={convId} onModelClick={onModelClick} />}
    </React.Fragment>
  );
}

/* ============================== PANEL ============================== */
function ModelRow({ meta, model, active, onClick, thinking }) {
  return (
    <button className={"mrow" + (active ? " active" : "") + (thinking ? " thinking" : "")}
      onClick={() => !thinking && onClick()}>
      <span className="dot" style={{ background: thinking ? "#c9cdd4" : (meta ? meta.hue : "#888") }} />
      <span className="nm">{model.label || (meta && meta.name) || model.model}</span>
      {thinking ? <span className="dots3 mini"><span/><span/><span/></span>
                : <span className="chev"><Icon name="chev" size={12} /></span>}
    </button>
  );
}

function Panel({ t, models, allDone, pending, selIdx, onSel, panelRef }) {
  const metaFor = (m) => window.MODEL_META.find(x =>
    (m.label && x.name && m.label.toLowerCase().includes(x.id)) ||
    (m.model && m.model.toLowerCase().includes(x.id)) ||
    (m.label && x.name && m.label.toLowerCase().startsWith(x.name.toLowerCase().split(" ")[0]))
  ) || null;
  const list = pending && models.length === 0
    ? window.MODEL_META.map(meta => ({ label: meta.name, status: "thinking" }))
    : models;
  // izbrani model za desni panel; privzeto prvi koncani (lahko nadzorovan od zunaj)
  const [selInner, setSelInner] = React.useState(0);
  const sel = (typeof selIdx === "number") ? selIdx : selInner;
  const setSel = onSel || setSelInner;
  const isThinking = (m) => m.status === "thinking";

  return (
    <div className="panel" ref={panelRef}>
      <div className="panel-head">
        <span className="lab">{allDone ? t.ui.panelDone : t.ui.panelLabel}</span>
        <span className="rule" />
        <span className="count">{list.length} ⟡</span>
      </div>

      {pending ? (
        // med cakanjem: mreza kartic (kaze napredek vseh hkrati)
        <div className="model-grid">
          {list.map((model, i) => (
            <div key={i} className={"mcard thinking"}>
              <div className="top">
                <span className="dot" style={{ background: "#c9cdd4" }} />
                <span className="nm">{model.label || (window.MODEL_META[i] && window.MODEL_META[i].name)}</span>
              </div>
              <div className="dots3"><span/><span/><span/></div>
            </div>
          ))}
        </div>
      ) : (
        // koncano: seznam levo + odgovor desno
        <div className="panel-split">
          <div className="ps-list">
            {list.map((model, i) => (
              <ModelRow key={i} meta={metaFor(model)} model={model}
                active={sel === i} thinking={isThinking(model)}
                onClick={() => setSel(i)} />
            ))}
          </div>
          <div className="ps-detail">
            {list[sel] ? (
              <React.Fragment>
                <div className="ps-detail-head">
                  <span className="dot" style={{ background: (metaFor(list[sel]) ? metaFor(list[sel]).hue : "#888") }} />
                  <span className="nm">{list[sel].label || (metaFor(list[sel]) && metaFor(list[sel]).name) || list[sel].model}</span>
                </div>
                <div className="ps-detail-body"
                  dangerouslySetInnerHTML={{ __html: window.mdToHtml(list[sel].answer || "") }} />
              </React.Fragment>
            ) : <div className="ps-empty">{t.ui.panelLabel}</div>}
          </div>
        </div>
      )}
    </div>
  );
}

/* ============================== SYNTHESIS ============================== */
function SynthesisHero({ t, content, lang, convId, onModelClick }) {
  const ui = t.ui;
  const [copied, setCopied] = React.useState(false);
  const [shown, setShown] = React.useState(content);
  const [translated, setTranslated] = React.useState(false);
  const [busy, setBusy] = React.useState(false);
  const [expOpen, setExpOpen] = React.useState(false);
  const [usage, setUsage] = React.useState(null);
  const [usageOpen, setUsageOpen] = React.useState(false);
  React.useEffect(() => {
    if (convId) window.AILAPI.usageConversation(convId).then(u => { if (u) setUsage(u); }).catch(() => {});
  }, [convId, content]);
  React.useEffect(() => { setShown(content); setTranslated(false); }, [content]);
  const hasDoc = typeof content === "string" && content.indexOf("===DOKUMENT===") !== -1;
  const doExport = (what, fmt) => {
    setExpOpen(false);
    if (!convId) return;
    const url = "/api/conversation/" + convId + "/export?what=" + what + "&fmt=" + fmt + "&lang=" + (lang || "si");
    window.open(url, "_blank");
  };
  const copy = () => {
    navigator.clipboard.writeText(shown).then(() => {
      setCopied(true); setTimeout(() => setCopied(false), 1500);
    });
  };
  const doTranslate = async () => {
    if (translated) { setShown(content); setTranslated(false); return; }
    setBusy(true);
    try {
      const tx = await window.AILAPI.translate(content, lang);
      setShown(tx); setTranslated(true);
    } catch (e) {}
    setBusy(false);
  };
  return (
    <div className="synth enter">
      <div className="synth-head">
        <Emblem size={38} variant="badge" />
        <div className="meta">
          <div className="k">{ui.synthLabel}</div>
          <div className="by">{ui.synthBy}</div>
        </div>
      </div>
      <div className="synth-body">
        <div className="synth-md"
          onClick={(e) => {
            const tag = e.target.closest && e.target.closest(".model-tag");
            if (tag && onModelClick) { e.preventDefault(); onModelClick(tag.getAttribute("data-model")); }
          }}
          dangerouslySetInnerHTML={{ __html: window.mdToHtml(shown) }} />
        <div className="synth-foot">
          <div className="acts">
            <button onClick={copy}><Icon name="copy" size={14} />{copied ? (ui.copied || "Kopirano") : ui.copy}</button>
            <button onClick={doTranslate} disabled={busy}>
              <Icon name="chev" size={14} />
              {busy ? (ui.translating || "…") : (translated ? (ui.showOriginal || "Original") : (ui.translate || "Prevedi"))}
            </button>
            {usage && (
              <button className="cost-btn" onClick={() => setUsageOpen(!usageOpen)} title={ui.usageCaseTitle || "Poraba za to zadevo"}>
                <Icon name="chev" size={13} /> ${usage.total_cost.toFixed(3)}
              </button>
            )}
            <div className="exp-wrap">
              <button className="exp-pdf" onClick={() => setExpOpen(!expOpen)}><Icon name="dl" size={14} />{ui.export}</button>
              {expOpen && (
                <div className="exp-menu">
                  <div className="exp-group">
                    <div className="exp-lbl">{ui.exportSynth || "Sinteza"}</div>
                    <button onClick={() => doExport("synthesis", "pdf")}>PDF</button>
                    <button onClick={() => doExport("synthesis", "docx")}>Word</button>
                  </div>
                  <div className="exp-group">
                    <div className="exp-lbl">{ui.exportAll || "Vse (s panelom)"}</div>
                    <button onClick={() => doExport("all", "pdf")}>PDF</button>
                    <button onClick={() => doExport("all", "docx")}>Word</button>
                  </div>
                  {hasDoc && (
                    <div className="exp-group exp-doc">
                      <div className="exp-lbl">{ui.exportDoc || "Končni dokument"}</div>
                      <button onClick={() => doExport("document", "pdf")}>PDF</button>
                      <button onClick={() => doExport("document", "docx")}>Word</button>
                    </div>
                  )}
                </div>
              )}
            </div>
          </div>
          {usageOpen && usage && (
            <div className="cost-detail">
              {usage.models.map((m, i) => (
                <div key={i} className="cost-row">
                  <span className="cm-name">{m.label}</span>
                  <span className="cm-tok">{(m.prompt_tokens + m.completion_tokens).toLocaleString()} tok</span>
                  <span className="cm-cost">${m.cost.toFixed(4)}</span>
                </div>
              ))}
              <div className="cost-row cost-total">
                <span className="cm-name">{ui.usageTotal || "Skupaj"}</span>
                <span className="cm-tok"></span>
                <span className="cm-cost">${usage.total_cost.toFixed(4)}</span>
              </div>
            </div>
          )}
        </div>
      </div>
    </div>
  );
}

/* ============================== USER MESSAGE ============================== */
function UserMessage({ t, text, docs }) {
  return (
    <div className="msg-user">
      <div className="bubble">
        <div>{text}</div>
        {docs && docs.length > 0 && docs.map((d, i) => (
          <div className="doc" key={i}>
            <span className="ic" />
            {d.filename || d.name}
          </div>
        ))}
      </div>
    </div>
  );
}

function ChatBubble({ t, text, pending, onToPanel, busy }) {
  if (pending) {
    return (
      <div className="chat-bubble">
        <div className="chat-tag"><Icon name="bolt" size={13} /> {(t.ui && t.ui.chatTag) || "Hitri klepet \u00b7 Sonnet"}</div>
        <div className="thinking-row" style={{margin:0}}><span className="dots3"><span/><span/><span/></span></div>
      </div>
    );
  }
  return (
    <div className="chat-bubble">
      <div className="chat-tag"><Icon name="bolt" size={13} /> {(t.ui && t.ui.chatTag) || "Hitri klepet \u00b7 Sonnet"}</div>
      <div className="chat-body" dangerouslySetInnerHTML={{ __html: window.mdToHtml(text || "") }} />
      {onToPanel && (
        <div className="chat-actions">
          <button className="to-panel-btn" onClick={onToPanel} disabled={busy} type="button"
            title={(t.ui && t.ui.toPanelTitle) || "Po\u0161lji to v panel (6 modelov + sinteza)"}>
            <Icon name="scale" size={14} /> {(t.ui && t.ui.toPanelBtn) || "Po\u0161lji v panel"}
          </button>
        </div>
      )}
    </div>
  );
}

Object.assign(window, {
  Icon, Sidebar, TopBar, LangSwitch, IntakeBlock, ModelCard, Panel, SynthesisHero, UserMessage, ChatBubble,
});
