// Admin area — view all submissions + export markdown.
// Backed by the server API (/api/submissions, /api/deck-views) — admin-gated.
const AdminArea = (function () {

  async function fetchSubmissions() {
    try {
      const data = await window.api.get("/api/submissions");
      return data.submissions || [];
    } catch (ex) {
      console.warn("[admin] could not fetch submissions:", ex.message);
      return [];
    }
  }

  async function deleteSubmissionApi(id) {
    await window.api.del("/api/submissions/" + encodeURIComponent(id));
  }

  async function fetchDeckViews() {
    try {
      const data = await window.api.get("/api/deck-views");
      return data.views || [];
    } catch (ex) {
      console.warn("[admin] could not fetch deck views:", ex.message);
      return [];
    }
  }

  async function clearDeckViewsApi() {
    await window.api.del("/api/deck-views");
  }

  // ---------- Markdown export ----------
  function answerToMarkdown(q, a) {
    if (!a) return "_Not answered_";
    if (q.type === "multi") {
      const opts = a.options || [];
      let out = opts.length ? opts.map(o => "- " + o).join("\n") : "_Not answered_";
      if (a.other) out += "\n- _Other:_ " + a.other;
      return out;
    }
    if (q.type === "table") {
      const cells = Object.entries(a);
      if (cells.length === 0) return "_Not answered_";
      // Group by tool
      const byTool = {};
      for (const [k, v] of cells) {
        const [tool, col] = k.split("::");
        byTool[tool] = byTool[tool] || {};
        byTool[tool][col] = v;
      }
      let out = "| Tool | Client/personal data | Vendor agreement | Data location |\n|---|---|---|---|\n";
      for (const [tool, vals] of Object.entries(byTool)) {
        out += `| ${tool} | ${vals.data || "—"} | ${vals.dpa || "—"} | ${vals.loc || "—"} |\n`;
      }
      return out;
    }
    if (q.type === "longtext") return a.text ? "> " + a.text.split("\n").join("\n> ") : "_Not answered_";
    if (a.value) {
      let out = "**" + a.value + "**";
      if (a.text) out += "\n\n> " + a.text.split("\n").join("\n> ");
      return out;
    }
    return "_Not answered_";
  }

  function buildMarkdown(submission) {
    const { user, answers, confidences, mode, submittedAt } = submission;
    let md = `# AI & Data Governance Discovery — Response\n\n`;
    md += `**Respondent:** ${user.name}  \n`;
    md += `**Mode:** ${mode === "chat" ? "Conversational (AI assistant)" : "Standard survey"}  \n`;
    md += `**Submitted:** ${new Date(submittedAt).toLocaleString()}  \n\n`;
    md += `---\n\n`;
    for (const s of window.SURVEY.sections) {
      md += `## ${s.title}\n\n`;
      for (const q of s.questions) {
        const a = answers[q.id];
        const conf = confidences?.[q.id];
        md += `### ${q.id.toUpperCase()} — ${q.prompt}\n\n`;
        md += answerToMarkdown(q, a) + "\n\n";
        if (conf !== undefined) {
          const tag = conf >= 0.8 ? "high" : conf >= 0.65 ? "medium" : "low";
          md += `_Inferred from chat · ${Math.round(conf * 100)}% confidence (${tag})_\n\n`;
        }
      }
      md += `\n`;
    }
    return md;
  }

  function downloadFile(filename, content, mimeType) {
    const blob = new Blob([content], { type: mimeType });
    const url = URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = url; a.download = filename;
    document.body.appendChild(a); a.click(); a.remove();
    setTimeout(() => URL.revokeObjectURL(url), 1000);
  }

  // ---------- UI ----------
  function pct(submission) {
    const filled = window.SURVEY_FLAT.filter(q => {
      const a = submission.answers[q.id];
      if (!a) return false;
      if (a.options) return a.options.length > 0;
      if (a.value) return true;
      if (a.text) return true;
      if (typeof a === "object" && Object.keys(a).length > 0) return true;
      return false;
    }).length;
    return { filled, pct: Math.round((filled / window.SURVEY_FLAT.length) * 100) };
  }

  // ---------- Formatted (branded) view of a response ----------
  function confTag(c) {
    if (c === undefined) return null;
    const tag = c >= 0.8 ? "high" : c >= 0.65 ? "medium" : "low";
    const cls = c >= 0.8 ? "conf-high" : c >= 0.65 ? "conf-med" : "conf-low";
    return <span className={"conf "+cls}>{Math.round(c*100)}% · {tag}</span>;
  }

  function isAnswered(q, a) {
    if (!a) return false;
    if (q.type === "multi") return (a.options && a.options.length > 0) || a.other;
    if (q.type === "table") return Object.keys(a).length > 0;
    if (q.type === "longtext") return !!(a.text && a.text.trim());
    return !!(a.value || a.text);
  }

  function AnswerView({ q, a }) {
    if (!isAnswered(q, a)) return <div className="ans-empty">Not answered</div>;

    if (q.type === "multi") {
      return (
        <div className="ans-tags">
          {(a.options || []).map(o => <span key={o} className="ans-tag">{o}</span>)}
          {a.other && <span className="ans-tag other">+ {a.other}</span>}
        </div>
      );
    }
    if (q.type === "longtext") {
      return <div className="ans-quote">{a.text}</div>;
    }
    if (q.type === "table") {
      const byTool = {};
      for (const [k, v] of Object.entries(a)) {
        const [tool, col] = k.split("::");
        byTool[tool] = byTool[tool] || {};
        byTool[tool][col] = v;
      }
      return (
        <div className="ans-table">
          <div className="ans-trow head">
            <div>Tool</div><div>Client/personal data</div><div>Vendor agreement</div><div>Data location</div>
          </div>
          {Object.entries(byTool).map(([tool, vals]) => (
            <div key={tool} className="ans-trow">
              <div className="tool">{tool}</div>
              <div>{cellChip(vals.data)}</div>
              <div>{cellChip(vals.dpa)}</div>
              <div>{cellChip(vals.loc)}</div>
            </div>
          ))}
        </div>
      );
    }
    // single
    return (
      <div className="ans-single">
        <span className="ans-pill">{a.value}</span>
        {a.text && <div className="ans-quote">{a.text}</div>}
      </div>
    );
  }

  function cellChip(v) {
    if (!v) return <span className="ans-dash">—</span>;
    const cls = v === "Yes" ? "yes" : v === "No" ? "no" : v === "Unsure" || v === "Don't know" ? "warn" : "neutral";
    return <span className={"ans-chip "+cls}>{v}</span>;
  }

  function FormattedResponse({ submission }) {
    const { answers, confidences, mode } = submission;
    const sections = window.SURVEY.sections;
    const total = window.SURVEY_FLAT.length;
    const filled = window.SURVEY_FLAT.filter(q => isAnswered(q, answers[q.id])).length;

    return (
      <div className="resp-view">
        <div className="resp-summary">
          <div className="resp-stat">
            <div className="n">{filled}<span>/{total}</span></div>
            <div className="l">Questions answered</div>
          </div>
          <div className="resp-stat">
            <div className="n">{Math.round((filled/total)*100)}%</div>
            <div className="l">Completion</div>
          </div>
          <div className="resp-stat">
            <div className="n">{sections.length}</div>
            <div className="l">Sections</div>
          </div>
          <div className="resp-stat">
            <div className="n" style={{textTransform:"capitalize"}}>{mode === "chat" ? "Chat" : "Standard"}</div>
            <div className="l">Mode</div>
          </div>
        </div>
        {sections.map((s, i) => {
          const sFilled = s.questions.filter(q => isAnswered(q, answers[q.id])).length;
          return (
            <section key={s.id} className="resp-section">
              <div className="resp-shead">
                <div className="resp-snum">{String(i+1).padStart(2,"0")}</div>
                <div style={{flex:1}}>
                  <h3>{s.title}</h3>
                  <div className="resp-scount">{sFilled} of {s.questions.length} answered</div>
                </div>
              </div>
              {s.questions.map(q => {
                const a = answers[q.id];
                const c = confidences?.[q.id];
                return (
                  <div key={q.id} className={"resp-q "+(isAnswered(q,a)?"":"unans")}>
                    <div className="resp-qh">
                      <span className="resp-qid">{q.id.toUpperCase()}</span>
                      <span className="resp-qprompt">{q.prompt}</span>
                      {confTag(c)}
                    </div>
                    <div className="resp-qbody">
                      <AnswerView q={q} a={a} />
                    </div>
                  </div>
                );
              })}
            </section>
          );
        })}
      </div>
    );
  }

  function fmtDwell(ms) {
    if (!ms) return "—";
    const s = Math.round(ms / 1000);
    if (s < 60) return s + "s";
    const m = Math.floor(s / 60);
    const r = s % 60;
    return m + "m " + (r < 10 ? "0" : "") + r + "s";
  }
  function fmtRelative(t) {
    const diff = Date.now() - t;
    const m = Math.round(diff / 60000);
    if (m < 1) return "just now";
    if (m < 60) return m + "m ago";
    const h = Math.round(m / 60);
    if (h < 24) return h + "h ago";
    const d = Math.round(h / 24);
    if (d < 7) return d + "d ago";
    return new Date(t).toLocaleDateString();
  }

  function DeckAnalyticsView() {
    const [views, setViews] = useState([]);
    const [openId, setOpenId] = useState(null);

    useEffect(() => {
      let cancelled = false;
      async function tick() {
        const v = await fetchDeckViews();
        if (!cancelled) setViews(v);
      }
      tick();
      const i = setInterval(tick, 1500);
      return () => { cancelled = true; clearInterval(i); };
    }, []);

    const total = views.length;
    const totalSlides = (window.DECK_SLIDES || []).length || 1;
    const completed = views.filter(v => v.reachedEnd).length;
    const avgPct = total ? Math.round(views.reduce((n, v) => n + ((v.maxIndex + 1) / totalSlides), 0) / total * 100) : 0;
    const totalTime = views.reduce((n, v) => n + v.slides.reduce((a, s) => a + (s.dwellMs || 0), 0), 0);

    const open = openId ? views.find(v => v.id === openId) : null;

    async function clearAll() {
      if (!confirm("Clear all deck view records? This cannot be undone.")) return;
      try { await clearDeckViewsApi(); } catch {}
      setViews([]);
      setOpenId(null);
    }

    return (
      <>
        <div className="dv-tiles">
          <div className="dv-tile">
            <div className="dv-tile-l">Total views</div>
            <div className="dv-tile-n">{total}</div>
            <div className="dv-tile-h">all-time sessions</div>
          </div>
          <div className="dv-tile">
            <div className="dv-tile-l">Reached end</div>
            <div className="dv-tile-n">{completed}</div>
            <div className="dv-tile-h">{total ? Math.round(completed/total*100) : 0}% completion rate</div>
          </div>
          <div className="dv-tile">
            <div className="dv-tile-l">Avg progress</div>
            <div className="dv-tile-n">{avgPct}%</div>
            <div className="dv-tile-h">of the deck per visit</div>
          </div>
          <div className="dv-tile">
            <div className="dv-tile-l">Total time</div>
            <div className="dv-tile-n">{fmtDwell(totalTime)}</div>
            <div className="dv-tile-h">across all sessions</div>
          </div>
        </div>

        {total === 0 ? (
          <div className="dv-empty">
            No deck views yet. The roadmap deck is reachable from the home screen for any signed-in user. Open it once and your session will appear here.
          </div>
        ) : (
          <>
            <div className="dv-table">
              <div className="dv-row head">
                <div>Viewer</div>
                <div>Started</div>
                <div>Progress</div>
                <div>Total time</div>
                <div>Most-viewed slide</div>
                <div>Reached end</div>
              </div>
              {views.map(v => {
                const totalDwell = v.slides.reduce((a,s) => a + (s.dwellMs||0), 0);
                const progress = (v.maxIndex + 1) / v.slides.length;
                const longest = v.slides.reduce((m, s, i) => (s.dwellMs||0) > (m?.dwellMs||0) ? { ...s, idx: i } : m, null);
                return (
                  <div key={v.id} className="dv-row" style={{cursor:"pointer"}} onClick={() => setOpenId(openId === v.id ? null : v.id)}>
                    <div className="dv-name">
                      {v.user.name}
                      <span className="em">{v.reachedEnd ? "Completed deck" : "In progress"}</span>
                    </div>
                    <div className="dv-when">{fmtRelative(v.startedAt)}</div>
                    <div className="dv-completion">
                      <span>{v.maxIndex + 1}/{v.slides.length}</span>
                      <div className={"dv-bar " + (progress === 1 ? "full" : "")}><div style={{width: (progress * 100) + "%"}}/></div>
                    </div>
                    <div className="dv-dwell">{fmtDwell(totalDwell)}</div>
                    <div className="dv-dwell" style={{color:"var(--ink-2)",whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis"}}>
                      {longest ? `#${longest.idx+1} · ${fmtDwell(longest.dwellMs)}` : "—"}
                    </div>
                    <div>
                      <span className={"dv-end " + (v.reachedEnd ? "yes" : "no")}>{v.reachedEnd ? "✓ Yes" : "No"}</span>
                    </div>
                  </div>
                );
              })}
            </div>
            {open && (
              <div className="dv-detail">
                <h4>Per-slide dwell · {open.user.name}</h4>
                <div className="dv-detail-meta">
                  <span><strong>Started</strong> {new Date(open.startedAt).toLocaleString()}</span>
                  <span><strong>Furthest slide</strong> #{open.maxIndex + 1}</span>
                  <span><strong>Total time</strong> {fmtDwell(open.slides.reduce((a,s)=>a+(s.dwellMs||0),0))}</span>
                  <span><strong>Reached end</strong> {open.reachedEnd ? "Yes" : "No"}</span>
                </div>
                {(() => {
                  const max = Math.max(1, ...open.slides.map(s => s.dwellMs || 0));
                  return (
                    <div className="dv-slide-bars">
                      {open.slides.map((s, i) => (
                        <div key={i} className="dv-slide-row">
                          <div className="dv-slide-n">#{String(i+1).padStart(2,"0")}</div>
                          <div className="dv-slide-t">
                            <span style={{flexShrink:0,maxWidth:280,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}}>{s.title}</span>
                            <div className="dv-slide-bar"><div style={{width: ((s.dwellMs||0)/max*100) + "%"}}/></div>
                          </div>
                          <div className="dv-slide-dwell">{fmtDwell(s.dwellMs)}</div>
                        </div>
                      ))}
                    </div>
                  );
                })()}
              </div>
            )}
            <div style={{marginTop: 18, display: "flex", justifyContent: "flex-end"}}>
              <button className="btn ghost" onClick={clearAll}>Clear all view records</button>
            </div>
          </>
        )}
      </>
    );
  }

  function AdminArea({ user, onLogout, onLeave }) {
    const [tab, setTab] = useState("responses"); // responses | deck
    const [submissions, setSubmissions] = useState([]);
    const [selectedIdx, setSelectedIdx] = useState(-1);
    const [loaded, setLoaded] = useState(false);

    useEffect(() => {
      let cancelled = false;
      async function tick() {
        const next = await fetchSubmissions();
        if (cancelled) return;
        setSubmissions(next);
        setLoaded(true);
        // If nothing was selected yet and we now have rows, select the first.
        setSelectedIdx(prev => (prev < 0 && next.length > 0 ? 0 : prev));
      }
      tick();
      const i = setInterval(tick, 1500);
      return () => { cancelled = true; clearInterval(i); };
    }, []);

    async function deleteSub(idx) {
      if (!confirm("Delete this response? This cannot be undone.")) return;
      const sub = submissions[idx];
      if (!sub) return;
      try { await deleteSubmissionApi(sub.id); } catch (ex) {
        alert("Could not delete response: " + (ex.message || "error"));
        return;
      }
      const next = submissions.filter((_, i) => i !== idx);
      setSubmissions(next);
      if (selectedIdx >= next.length) setSelectedIdx(next.length - 1);
    }

    function exportOne(sub) {
      const md = buildMarkdown(sub);
      const safe = sub.user.name.replace(/[^a-z0-9]+/gi, "-").toLowerCase();
      downloadFile(`wbo-survey-${safe}.md`, md, "text/markdown");
    }

    function exportAll() {
      let combined = `# All Survey Responses\n\nExported: ${new Date().toLocaleString()}\n\n---\n\n`;
      for (const s of submissions) {
        combined += buildMarkdown(s) + "\n\n---\n\n";
      }
      downloadFile(`wbo-survey-all-${Date.now()}.md`, combined, "text/markdown");
    }

    function exportJson() {
      downloadFile(`wbo-survey-all-${Date.now()}.json`, JSON.stringify(submissions, null, 2), "application/json");
    }

    const selected = selectedIdx >= 0 ? submissions[selectedIdx] : null;
    const mdPreview = selected ? buildMarkdown(selected) : "";
    const [viewMode, setViewMode] = useState("formatted"); // formatted | markdown
    function copyMd() {
      navigator.clipboard.writeText(mdPreview).catch(()=>{});
    }

    // Aggregate stats
    const totalResp = submissions.length;
    const chatResp = submissions.filter(s => s.mode === "chat").length;
    const stdResp = submissions.filter(s => s.mode !== "chat").length;
    const avgPct = totalResp ? Math.round(submissions.reduce((n,s) => n + pct(s).pct, 0) / totalResp) : 0;

    return (
      <>
        <Topbar user={user} onLogout={onLogout} crumb={"Admin \u00b7 " + (tab==="deck"?"Roadmap analytics":"Survey responses")} saveLabel={false} />
        <div className="admin-shell">
          <div className="admin-head">
            <div>
              <h1>{tab==="deck" ? "Roadmap deck analytics" : "Survey responses"}</h1>
              <p className="lead">{tab==="deck" ? "Who opened the AI Transformation Roadmap, how far they got, and where they lingered." : "View, review, and export discovery survey submissions."}</p>
            </div>
            <div className="admin-actions">
              <div className="dv-tabs">
                <button className={"dv-tab " + (tab==="responses"?"on":"")} onClick={() => setTab("responses")}>Responses</button>
                <button className={"dv-tab " + (tab==="deck"?"on":"")} onClick={() => setTab("deck")}>Deck views</button>
              </div>
              <button className="btn ghost" onClick={onLeave}>← Take the survey</button>
              {tab === "responses" && <>
                <button className="btn ghost" onClick={exportJson} disabled={!totalResp}>Export JSON</button>
                <button className="btn primary" onClick={exportAll} disabled={!totalResp}>Export all as Markdown</button>
              </>}
            </div>
          </div>

          {tab === "deck" ? <DeckAnalyticsView /> : <>
          <div className="admin-stats">
            <div className="stat-card">
              <div className="n">{totalResp}</div>
              <div className="l">Responses</div>
            </div>
            <div className="stat-card">
              <div className="n">{stdResp}</div>
              <div className="l">Standard mode</div>
            </div>
            <div className="stat-card">
              <div className="n">{chatResp}</div>
              <div className="l">Chat mode</div>
            </div>
            <div className="stat-card">
              <div className="n">{avgPct}%</div>
              <div className="l">Avg completion</div>
            </div>
          </div>
          <div className="admin-grid">
            <aside className="admin-list">
              <div className="admin-list-head">All submissions</div>
              {submissions.length === 0 && (
                <div style={{padding:"40px 16px",textAlign:"center",color:"var(--muted)",fontSize:13}}>
                  No submissions yet. Responses appear here as people complete the survey.
                </div>
              )}
              {submissions.map((s, i) => {
                const p = pct(s);
                return (
                  <button key={s.id}
                    className={"admin-list-item " + (i === selectedIdx ? "active" : "")}
                    onClick={() => setSelectedIdx(i)}>
                    <div className="ali-avatar">{s.user.name.split(" ").map(x=>x[0]).join("").slice(0,2).toUpperCase()}</div>
                    <div style={{flex:1, minWidth:0}}>
                      <div className="ali-name">{s.user.name}</div>
                      <div className="ali-email">{s.mode === "chat" ? "via conversational mode" : "via standard form"}</div>
                      <div className="ali-meta">
                        <span className={"ali-mode " + (s.mode === "chat" ? "chat" : "std")}>{s.mode === "chat" ? "Chat" : "Standard"}</span>
                        <span>{p.filled}/{window.SURVEY_FLAT.length}</span>
                        <span>{new Date(s.submittedAt).toLocaleDateString()}</span>
                      </div>
                    </div>
                  </button>
                );
              })}
            </aside>
            <main className="admin-detail">
              {!selected && (
                <div style={{padding:"60px 24px",textAlign:"center",color:"var(--muted)"}}>
                  Select a response on the left to view it.
                </div>
              )}
              {selected && (
                <>
                  <div className="admin-detail-head">
                    <div>
                      <h2>{selected.user.name}</h2>
                      <div style={{color:"var(--muted)",fontSize:13}}>
                        Submitted {new Date(selected.submittedAt).toLocaleString()} · via {selected.mode === "chat" ? "Chat" : "Standard"}
                      </div>
                    </div>
                    <div style={{display:"flex",gap:8}}>
                      <div className="seg">
                        <button className={"seg-btn "+(viewMode==="formatted"?"on":"")} onClick={()=>setViewMode("formatted")}>Formatted</button>
                        <button className={"seg-btn "+(viewMode==="markdown"?"on":"")} onClick={()=>setViewMode("markdown")}>Markdown</button>
                      </div>
                      <button className="btn ghost" onClick={() => deleteSub(selectedIdx)}>Delete</button>
                      {viewMode==="markdown" && <button className="btn ghost" onClick={copyMd}>Copy</button>}
                      <button className="btn primary" onClick={() => exportOne(selected)}>Download .md</button>
                    </div>
                  </div>
                  {viewMode === "formatted"
                    ? <FormattedResponse submission={selected} />
                    : <div className="md-preview"><pre>{mdPreview}</pre></div>
                  }
                </>
              )}
            </main>
          </div>
          </>}
        </div>
      </>
    );
  }

  AdminArea.buildMarkdown = buildMarkdown;
  AdminArea.downloadFile = downloadFile;
  return AdminArea;
})();

window.AdminArea = AdminArea;
