/* global React, AppHeader, Btn, Eyebrow, Display, FigureNum, Rule, Monogram */
const { useState: useStatePH, useEffect: useEffectPH } = React;

// Shared shell — one screen, different content. Each placeholder uses the
// real AppHeader so navigation between dead-end screens still works.
function PlaceholderShell({ theme, user, current, onNav, onLogout, onAdmin, eyebrow, title, lede, columns, cta }) {
  return (
    <div>
      <AppHeader theme={theme} user={user} onLogout={onLogout} current={current} onNav={onNav} onAdmin={onAdmin} />
      <main style={{ maxWidth: 1320, margin: "0 auto", padding: "32px 40px 80px" }}>
        <section style={{
          borderTop: `3px double ${theme.rule}`,
          borderBottom: `1px solid ${theme.rule}`,
          padding: "32px 0 36px",
        }}>
          <Eyebrow theme={theme} style={{ color: theme.accent, marginBottom: 14 }}>── {eyebrow}</Eyebrow>
          <Display theme={theme} size={88} style={{ maxWidth: 900 }}>{title}</Display>
          <p style={{
            marginTop: 24, maxWidth: 740,
            fontSize: 17, lineHeight: 1.55, color: theme.fg,
          }}>{lede}</p>
          {cta && (
            <div style={{ marginTop: 28, display: "flex", gap: 12, flexWrap: "wrap" }}>
              {cta.map((c, i) => (
                <Btn key={c.label} theme={theme} variant={i === 0 ? "primary" : "outline"} onClick={c.onClick}>
                  {c.label}
                </Btn>
              ))}
            </div>
          )}
        </section>

        <section style={{
          display: "grid",
          gridTemplateColumns: `repeat(${columns.length}, 1fr)`,
          gap: 0,
          marginTop: 40,
        }}>
          {columns.map((col, i) => (
            <article key={col.title} style={{
              padding: "24px 28px",
              borderRight: i < columns.length - 1 ? `1px solid ${theme.rule}` : "none",
            }}>
              <FigureNum theme={theme} size={26}>{("0" + (i + 1)).slice(-2)}</FigureNum>
              <Eyebrow theme={theme} style={{ marginTop: 6, marginBottom: 8 }}>── {col.kicker}</Eyebrow>
              <h3 style={{
                margin: 0,
                fontFamily: theme.fonts.display,
                fontSize: 22,
                lineHeight: 1.15,
                letterSpacing: "-0.015em",
              }}>{col.title}</h3>
              <p style={{
                marginTop: 10,
                fontSize: 14, lineHeight: 1.6, color: theme.fgDim,
              }}>{col.body}</p>
            </article>
          ))}
        </section>

        <section style={{
          marginTop: 48,
          borderTop: `1px solid ${theme.rule}`,
          paddingTop: 18,
          display: "flex",
          justifyContent: "space-between",
          fontFamily: theme.fonts.mono,
          fontSize: 11,
          letterSpacing: "0.1em",
          color: theme.fgDim,
        }}>
          <span>STATUS · IN DE STEIGERS</span>
          <span>VOLG DE ROADMAP IN <code>backlog.md</code></span>
          <span>Nº NIEUW</span>
        </section>
      </main>
    </div>
  );
}

function LibraryScreen({ theme, user, onNav, onLogout, onAdmin, onCreate, onPlay }) {
  const [quizzes, setQuizzes] = React.useState([]);
  const [loading, setLoading] = React.useState(true);
  const [preview, setPreview] = React.useState(null);

  React.useEffect(() => {
    window.kwistApi.get("/api/library").then((r) => {
      setQuizzes(r.quizzes || []);
    }).catch(() => {}).finally(() => setLoading(false));
  }, []);

  const handlePlay = async (q) => {
    try {
      const sess = await window.kwistApi.post("/api/sessions", { quizId: q.id, teams: false });
      onPlay?.({ ...q, code: sess.session.code, sessionId: sess.session.id, teamsEnabled: false });
    } catch (e) {
      window.kwistDialog?.alert("Sessie starten mislukt: " + e.message, { kind: "error" });
    }
  };

  const handleCopy = async (q) => {
    try {
      const full = await window.kwistApi.get(`/api/library/${q.id}`);
      const src = full.quiz;
      const copy = await window.kwistApi.post("/api/quizzes", {
        title: src.title + " (kopie)",
        subtitle: src.subtitle,
        category: src.category,
        type: src.type,
        color: src.color,
        glyph: src.glyph,
        questions: (src.questions || []).map((qq) => ({
          type: qq.type, prompt: qq.prompt, options: qq.options,
          answer: qq.answer, timeLimit: qq.timeLimit,
        })),
      });
      window.kwistDialog?.alert(`"${copy.quiz.title}" is aangemaakt als concept in jouw collectie.`, { title: "Gekopieerd" });
    } catch (e) {
      window.kwistDialog?.alert("Kopiëren mislukt: " + e.message, { kind: "error" });
    }
  };

  return (
    <div>
      <AppHeader theme={theme} user={user} onLogout={onLogout} current="library" onNav={onNav} onAdmin={onAdmin} />
      <main style={{ maxWidth: 1320, margin: "0 auto", padding: "32px 40px 80px" }}>
        <section style={{ borderTop: `3px double ${theme.rule}`, padding: "40px 0 32px" }}>
          <Eyebrow theme={theme} style={{ color: theme.accent, marginBottom: 10 }}>── DE BIBLIOTHEEK</Eyebrow>
          <h1 style={{
            fontFamily: theme.fonts.display, fontWeight: 800, fontStyle: "italic",
            fontSize: 56, lineHeight: 0.95, letterSpacing: "-0.04em",
            textTransform: "lowercase", margin: "0 0 12px",
          }}>
            kant-en-klare <span style={{ color: theme.accent }}>quizzes</span>.
          </h1>
          <p style={{ fontSize: 17, lineHeight: 1.55, color: theme.fgDim, maxWidth: 600, margin: 0 }}>
            Kies een quiz, speel 'm meteen of kopieer 'm naar je eigen collectie om aan te passen.
          </p>
        </section>

        {loading ? (
          <div style={{ padding: 60, textAlign: "center", border: `1px dashed ${theme.rule}` }}>
            <Eyebrow theme={theme}>LADEN…</Eyebrow>
          </div>
        ) : quizzes.length === 0 ? (
          <div style={{ padding: 60, textAlign: "center", border: `1px dashed ${theme.rule}` }}>
            <Eyebrow theme={theme}>DE BIBLIOTHEEK IS NOG LEEG</Eyebrow>
            <p style={{ color: theme.fgDim, marginTop: 12 }}>Binnenkort verschijnen hier kant-en-klare quizzes.</p>
          </div>
        ) : (
          <div style={{
            display: "grid", gridTemplateColumns: "repeat(auto-fill, minmax(280px, 1fr))",
            gap: 20, borderTop: `1px solid ${theme.rule}`, paddingTop: 24,
          }}>
            {quizzes.map((q) => (
              <LibraryCard key={q.id} theme={theme} q={q}
                onPlay={() => handlePlay(q)}
                onCopy={() => handleCopy(q)}
                onPreview={() => setPreview(preview?.id === q.id ? null : q)} />
            ))}
          </div>
        )}

        {preview && (
          <LibraryPreview theme={theme} quiz={preview} onClose={() => setPreview(null)}
            onPlay={() => handlePlay(preview)} onCopy={() => handleCopy(preview)} />
        )}
      </main>
    </div>
  );
}

function LibraryCard({ theme, q, onPlay, onCopy, onPreview }) {
  const [hover, setHover] = React.useState(false);
  return (
    <article
      onMouseEnter={() => setHover(true)} onMouseLeave={() => setHover(false)}
      style={{
        border: `1.5px solid ${theme.rule}`,
        background: theme.card,
        transition: "transform .12s, box-shadow .12s",
        transform: hover ? "translateY(-3px)" : "none",
        boxShadow: hover ? `0 4px 0 0 ${theme.rule}` : "none",
        display: "flex", flexDirection: "column",
        overflow: "hidden",
      }}>
      <div style={{
        background: q.color || theme.accent, color: "#fff",
        padding: "20px 20px 16px", position: "relative", overflow: "hidden",
      }}>
        <div style={{
          fontFamily: theme.fonts.mono, fontSize: 10, letterSpacing: "0.12em",
          opacity: 0.8, marginBottom: 8,
        }}>{(q.category || "ALGEMEEN").toUpperCase()} · {q.questions} VRAGEN</div>
        <div style={{
          fontFamily: theme.fonts.display, fontWeight: 800, fontStyle: "italic",
          fontSize: 28, lineHeight: 1.05, letterSpacing: "-0.02em",
          textTransform: "lowercase",
        }}>{q.title}</div>
        {q.subtitle && (
          <div style={{ fontSize: 13, opacity: 0.85, marginTop: 6 }}>{q.subtitle}</div>
        )}
      </div>
      <div style={{ padding: "14px 20px 18px", display: "flex", flexDirection: "column", gap: 10, flex: 1 }}>
        <div style={{
          fontFamily: theme.fonts.mono, fontSize: 10, letterSpacing: "0.08em", color: theme.fgDim,
        }}>DOOR {(q.author || "Kwist het!").toUpperCase()} · {q.plays || 0} SESSIES</div>
        <div style={{ display: "flex", gap: 8, marginTop: "auto" }}>
          <Btn theme={theme} size="sm" onClick={onPlay}>speel →</Btn>
          <Btn theme={theme} size="sm" variant="outline" onClick={onCopy}>+ kopieer</Btn>
          <Btn theme={theme} size="sm" variant="ghost" onClick={onPreview}>bekijk</Btn>
        </div>
      </div>
    </article>
  );
}

function LibraryPreview({ theme, quiz, onClose, onPlay, onCopy }) {
  const [full, setFull] = React.useState(null);
  React.useEffect(() => {
    window.kwistApi.get(`/api/library/${quiz.id}`).then((r) => setFull(r.quiz)).catch(() => {});
  }, [quiz.id]);
  const qs = full?.questions || [];
  return (
    <div style={{
      marginTop: 32, border: `2px solid ${theme.fg}`,
      boxShadow: `8px 8px 0 0 ${theme.fg}`,
      background: theme.bg, padding: "28px 32px",
    }}>
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", marginBottom: 20 }}>
        <div>
          <Eyebrow theme={theme} style={{ color: theme.accent, marginBottom: 6 }}>── PREVIEW</Eyebrow>
          <Display theme={theme} size={36}>{quiz.title}</Display>
        </div>
        <div style={{ display: "flex", gap: 10 }}>
          <Btn theme={theme} size="sm" onClick={onPlay}>speel →</Btn>
          <Btn theme={theme} size="sm" variant="outline" onClick={onCopy}>+ kopieer</Btn>
          <Btn theme={theme} size="sm" variant="ghost" onClick={onClose}>sluiten</Btn>
        </div>
      </div>
      {qs.length === 0 ? (
        <Eyebrow theme={theme}>LADEN…</Eyebrow>
      ) : (
        <div style={{ display: "grid", gap: 0 }}>
          {qs.map((q, i) => (
            <div key={q.id} style={{
              padding: "14px 0",
              borderBottom: i < qs.length - 1 ? `1px solid ${theme.rule}` : "none",
              display: "grid", gridTemplateColumns: "40px 1fr", gap: 12, alignItems: "baseline",
            }}>
              <FigureNum theme={theme} size={18} accent>{String(i + 1).padStart(2, "0")}</FigureNum>
              <div>
                <div style={{ fontSize: 15, lineHeight: 1.45, fontFamily: theme.fonts.body }}>{q.prompt}</div>
                {q.options && q.options.length > 0 && (
                  <div style={{ display: "flex", gap: 8, marginTop: 6, flexWrap: "wrap" }}>
                    {q.options.map((o) => (
                      <span key={o.id} style={{
                        fontFamily: theme.fonts.mono, fontSize: 11, letterSpacing: "0.05em",
                        padding: "2px 10px",
                        border: `1px solid ${o.correct ? theme.accent : theme.rule}`,
                        background: o.correct ? `${theme.accent}15` : "transparent",
                        color: o.correct ? theme.accent : theme.fgDim,
                      }}>{o.text}</span>
                    ))}
                  </div>
                )}
              </div>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

function StatsScreen({ theme, user, onNav, onLogout, onAdmin }) {
  const [sessions, setSessions] = useStatePH([]);
  const [loading, setLoading] = useStatePH(true);
  const [detail, setDetail] = useStatePH(null);
  const [quizHistory, setQuizHistory] = useStatePH(null);
  const [detailLoading, setDetailLoading] = useStatePH(false);
  const [tab, setTab] = useStatePH("sessions"); // sessions | quizzes

  useEffectPH(() => {
    (async () => {
      try {
        const r = await window.kwistApi.get("/api/sessions");
        setSessions(r.sessions || []);
      } catch { /* ignore */ }
      setLoading(false);
    })();
  }, []);

  const openDetail = async (s) => {
    setDetailLoading(true);
    try {
      const r = await window.kwistApi.get(`/api/sessions/${s.id}/results`);
      setDetail(r);
    } catch { /* ignore */ }
    setDetailLoading(false);
  };

  const openQuizHistory = async (quizId) => {
    setDetailLoading(true);
    try {
      const r = await window.kwistApi.get(`/api/quizzes/${quizId}/history`);
      setQuizHistory(r);
    } catch { /* ignore */ }
    setDetailLoading(false);
  };

  const fmt = (d) => {
    if (!d) return "—";
    const dt = new Date(d);
    return dt.toLocaleDateString("nl-BE", { day: "numeric", month: "short", year: "numeric" });
  };

  const statusLabel = { lobby: "Lobby", running: "Live", finished: "Afgelopen" };

  // Group sessions by quiz for the quiz tab (STA-01)
  const quizStats = React.useMemo(() => {
    const map = {};
    for (const s of sessions) {
      const key = s.quiz_id;
      if (!map[key]) {
        map[key] = { id: key, title: s.quiz_title, category: s.quiz_category, sessions: [], totalPlayers: 0, topScore: 0 };
      }
      map[key].sessions.push(s);
      map[key].totalPlayers += s.player_count;
      if (s.top_score > map[key].topScore) map[key].topScore = s.top_score;
    }
    return Object.values(map).sort((a, b) => b.sessions.length - a.sessions.length);
  }, [sessions]);

  return (
    <div>
      <AppHeader theme={theme} user={user} onLogout={onLogout} current="stats" onNav={onNav} onAdmin={onAdmin} />
      <main style={{ maxWidth: 1320, margin: "0 auto", padding: "32px 40px 80px" }}>
        <section style={{
          borderTop: `3px double ${theme.rule}`,
          padding: "32px 0 36px",
        }}>
          <Eyebrow theme={theme} style={{ color: theme.accent, marginBottom: 14 }}>── DE RESULTATEN</Eyebrow>
          <Display theme={theme} size={88} style={{ maxWidth: 900 }}>
            De <span style={{ color: theme.accent }}>cijfers</span>, in volle breedte.
          </Display>
        </section>

        {detail ? (
          <SessionDetail theme={theme} data={detail} onBack={() => setDetail(null)} />
        ) : quizHistory ? (
          <QuizHistoryDetail theme={theme} data={quizHistory} onBack={() => setQuizHistory(null)} fmt={fmt} />
        ) : (
          <>
            <div style={{ display: "flex", gap: 0, borderBottom: `2px solid ${theme.rule}`, marginBottom: 24 }}>
              {[{ key: "sessions", label: "Sessies" }, { key: "quizzes", label: "Per quiz" }].map((t) => (
                <button key={t.key} onClick={() => setTab(t.key)} style={{
                  padding: "10px 20px",
                  background: tab === t.key ? theme.fg : "transparent",
                  color: tab === t.key ? theme.bg : theme.fg,
                  border: "none", cursor: "pointer",
                  fontFamily: theme.fonts.display, fontSize: 16,
                  borderBottom: tab === t.key ? `2px solid ${theme.accent}` : "none",
                }}>{t.label}</button>
              ))}
            </div>

            {loading ? (
              <Eyebrow theme={theme} style={{ marginTop: 24 }}>LADEN…</Eyebrow>
            ) : sessions.length === 0 ? (
              <div style={{ padding: "48px 0", textAlign: "center" }}>
                <Display theme={theme} size={36}>Nog geen sessies gespeeld.</Display>
                <p style={{ color: theme.fgDim, marginTop: 12, fontSize: 15 }}>
                  Start een quiz vanuit je dashboard — de resultaten verschijnen hier automatisch.
                </p>
              </div>
            ) : tab === "sessions" ? (
              <div>
                <div style={{
                  display: "grid",
                  gridTemplateColumns: "2fr 1fr 80px 80px 80px 120px",
                  gap: 12,
                  padding: "10px 0",
                  borderBottom: `1px solid ${theme.rule}`,
                  fontFamily: theme.fonts.mono, fontSize: 11, letterSpacing: "0.1em", color: theme.fgDim,
                }}>
                  <span>QUIZ</span><span>DATUM</span><span>STATUS</span><span>SPELERS</span><span>TOP</span><span></span>
                </div>
                {sessions.map((s) => (
                  <div key={s.id} style={{
                    display: "grid",
                    gridTemplateColumns: "2fr 1fr 80px 80px 80px 120px",
                    gap: 12,
                    padding: "14px 0",
                    borderBottom: `1px dashed ${theme.rule}`,
                    alignItems: "center",
                  }}>
                    <div>
                      <div style={{ fontFamily: theme.fonts.display, fontSize: 18 }}>{s.quiz_title}</div>
                      <Eyebrow theme={theme}>{(s.quiz_category || "").toUpperCase()} · {s.code}</Eyebrow>
                    </div>
                    <div style={{ fontFamily: theme.fonts.mono, fontSize: 13, color: theme.fgDim }}>{fmt(s.started_at || s.created_at)}</div>
                    <Eyebrow theme={theme} style={{ color: s.status === "finished" ? theme.fg : theme.accent }}>
                      {statusLabel[s.status] || s.status}
                    </Eyebrow>
                    <FigureNum theme={theme} size={20}>{s.player_count}</FigureNum>
                    <FigureNum theme={theme} size={20} accent>{(s.top_score || 0).toLocaleString("nl-NL")}</FigureNum>
                    <Btn theme={theme} variant="outline" onClick={() => openDetail(s)} style={{ fontSize: 12, padding: "6px 12px" }}>
                      {detailLoading ? "…" : "Bekijk →"}
                    </Btn>
                  </div>
                ))}
              </div>
            ) : (
              <div>
                <div style={{
                  display: "grid",
                  gridTemplateColumns: "2fr 100px 100px 100px 120px",
                  gap: 12,
                  padding: "10px 0",
                  borderBottom: `1px solid ${theme.rule}`,
                  fontFamily: theme.fonts.mono, fontSize: 11, letterSpacing: "0.1em", color: theme.fgDim,
                }}>
                  <span>QUIZ</span><span>SESSIES</span><span>SPELERS</span><span>TOP SCORE</span><span></span>
                </div>
                {quizStats.map((q) => (
                  <div key={q.id} style={{
                    display: "grid",
                    gridTemplateColumns: "2fr 100px 100px 100px 120px",
                    gap: 12,
                    padding: "14px 0",
                    borderBottom: `1px dashed ${theme.rule}`,
                    alignItems: "center",
                  }}>
                    <div>
                      <div style={{ fontFamily: theme.fonts.display, fontSize: 18 }}>{q.title}</div>
                      <Eyebrow theme={theme}>{(q.category || "").toUpperCase()}</Eyebrow>
                    </div>
                    <FigureNum theme={theme} size={20}>{q.sessions.length}</FigureNum>
                    <FigureNum theme={theme} size={20}>{q.totalPlayers}</FigureNum>
                    <FigureNum theme={theme} size={20} accent>{(q.topScore || 0).toLocaleString("nl-NL")}</FigureNum>
                    <Btn theme={theme} variant="outline" onClick={() => openQuizHistory(q.id)} style={{ fontSize: 12, padding: "6px 12px" }}>
                      Historie →
                    </Btn>
                  </div>
                ))}
              </div>
            )}
          </>
        )}
      </main>
    </div>
  );
}

function QuizHistoryDetail({ theme, data, onBack, fmt }) {
  const { quiz, sessions, questions, totals } = data;
  return (
    <div style={{ marginTop: 24 }}>
      <button onClick={onBack} style={{
        background: "transparent", border: "none",
        fontFamily: theme.fonts.display, fontSize: 16, color: theme.fg, cursor: "pointer",
        marginBottom: 20,
      }}>← terug naar overzicht</button>

      <Display theme={theme} size={42}>{quiz.title}</Display>
      <Eyebrow theme={theme} style={{ marginTop: 4 }}>{(quiz.category || "").toUpperCase()}</Eyebrow>

      <div style={{
        display: "grid", gridTemplateColumns: "repeat(4, 1fr)", gap: 16,
        marginTop: 24, marginBottom: 36,
      }}>
        {[
          { label: "SESSIES", value: totals.totalPlays },
          { label: "TOTAAL SPELERS", value: totals.totalPlayers },
          { label: "GEM. SCORE", value: totals.avgScore },
          { label: "TOP SCORE", value: totals.topScore, sub: totals.topPlayer },
        ].map((s) => (
          <div key={s.label} style={{
            padding: "18px 20px",
            border: `1px solid ${theme.rule}`,
          }}>
            <Eyebrow theme={theme} style={{ marginBottom: 6 }}>── {s.label}</Eyebrow>
            <FigureNum theme={theme} size={36} accent>{(s.value || 0).toLocaleString("nl-NL")}</FigureNum>
            {s.sub && <div style={{ fontFamily: theme.fonts.display, fontSize: 14, color: theme.fgDim, marginTop: 4 }}>{s.sub}</div>}
          </div>
        ))}
      </div>

      {questions.length > 0 && (
        <>
          <Eyebrow theme={theme} style={{ marginBottom: 12 }}>── ANTWOORDDISTRIBUTIE PER VRAAG</Eyebrow>
          {questions.map((q) => {
            const pct = q.totalAnswers ? Math.round((q.correctCount / q.totalAnswers) * 100) : 0;
            const distEntries = Object.entries(q.distribution).sort((a, b) => b[1].count - a[1].count);
            return (
              <div key={q.id} style={{ marginBottom: 24, padding: "16px 0", borderBottom: `1px solid ${theme.rule}` }}>
                <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline" }}>
                  <div>
                    <Eyebrow theme={theme} style={{ color: theme.accent }}>VRAAG {q.position + 1} · {q.type.toUpperCase()}</Eyebrow>
                    <div style={{ fontFamily: theme.fonts.display, fontSize: 20, marginTop: 4 }}>{q.prompt}</div>
                  </div>
                  <div style={{ textAlign: "right" }}>
                    <FigureNum theme={theme} size={28} accent>{pct}%</FigureNum>
                    <div style={{ fontFamily: theme.fonts.mono, fontSize: 11, color: theme.fgDim }}>juist ({q.correctCount}/{q.totalAnswers})</div>
                  </div>
                </div>
                {distEntries.length > 0 && (
                  <div style={{ marginTop: 12, display: "flex", flexDirection: "column", gap: 4 }}>
                    {distEntries.slice(0, 6).map(([answer, info]) => {
                      const barPct = q.totalAnswers ? (info.count / q.totalAnswers) * 100 : 0;
                      return (
                        <div key={answer} style={{ display: "grid", gridTemplateColumns: "200px 1fr 60px", alignItems: "center", gap: 10 }}>
                          <div style={{
                            fontFamily: theme.fonts.body, fontSize: 13,
                            overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap",
                            color: info.correct ? theme.accent : theme.fgDim,
                            fontWeight: info.correct ? "bold" : "normal",
                          }}>{info.correct ? "✓ " : ""}{answer}</div>
                          <div style={{ height: 10, background: theme.rule, position: "relative" }}>
                            <div style={{
                              position: "absolute", top: 0, left: 0, height: "100%",
                              width: `${barPct}%`,
                              background: info.correct ? theme.accent : theme.fgDim,
                            }} />
                          </div>
                          <div style={{ fontFamily: theme.fonts.mono, fontSize: 12, color: theme.fgDim, textAlign: "right" }}>
                            {info.count}x ({Math.round(barPct)}%)
                          </div>
                        </div>
                      );
                    })}
                  </div>
                )}
              </div>
            );
          })}
        </>
      )}

      {sessions.length > 0 && (
        <>
          <Eyebrow theme={theme} style={{ marginTop: 36, marginBottom: 12 }}>── SESSIE-HISTORIE</Eyebrow>
          {sessions.map((s) => (
            <div key={s.id} style={{
              display: "grid", gridTemplateColumns: "1fr 100px 100px 100px",
              gap: 12, padding: "10px 0",
              borderBottom: `1px dashed ${theme.rule}`,
              alignItems: "center",
            }}>
              <div>
                <div style={{ fontFamily: theme.fonts.mono, fontSize: 13, color: theme.fgDim }}>{fmt(s.started_at || s.created_at)}</div>
                <Eyebrow theme={theme}>{s.code}</Eyebrow>
              </div>
              <FigureNum theme={theme} size={18}>{s.player_count} spelers</FigureNum>
              <FigureNum theme={theme} size={18}>{s.avg_score} gem.</FigureNum>
              <div style={{ textAlign: "right" }}>
                <FigureNum theme={theme} size={18} accent>{(s.top_score || 0).toLocaleString("nl-NL")}</FigureNum>
                {s.top_player && <div style={{ fontFamily: theme.fonts.mono, fontSize: 11, color: theme.fgDim }}>{s.top_player}</div>}
              </div>
            </div>
          ))}
        </>
      )}
    </div>
  );
}

// SES-09: PDF export. We bouwen een schone HTML-print-pagina en triggeren
// window.print() — de browser doet de rest ("Bewaar als PDF" in de print-dialog).
// Dit vermijdt server-side PDF-libs en houdt de styling in één hand.
function exportSessionPdf(data) {
  const { session, players, answers } = data;
  const questionMap = {};
  (answers || []).forEach((a) => {
    if (!questionMap[a.question_id]) questionMap[a.question_id] = { position: a.position, prompt: a.prompt, type: a.type, answers: [] };
    questionMap[a.question_id].answers.push(a);
  });
  const questions = Object.values(questionMap).sort((a, b) => a.position - b.position);
  const esc = (s) => String(s ?? "").replace(/[&<>"']/g, (c) => ({ "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;", "'": "&#39;" }[c]));
  const fmt = (d) => d ? new Date(d).toLocaleString("nl-BE") : "—";
  const playerRows = players.map((p, i) => `
    <tr>
      <td class="rank">${i + 1}</td>
      <td>${esc(p.name)}${p.team ? ` <span class="team">${esc(p.team)}</span>` : ""}</td>
      <td class="num">${(p.score || 0).toLocaleString("nl-NL")}</td>
    </tr>`).join("");
  const questionBlocks = questions.map((q) => {
    const total = q.answers.length;
    const correct = q.answers.filter((a) => a.correct).length;
    const pct = total ? Math.round((correct / total) * 100) : 0;
    return `
      <div class="q">
        <div class="q-head">
          <div>
            <div class="kicker">VRAAG ${q.position + 1} · ${q.type.toUpperCase()}</div>
            <div class="q-prompt">${esc(q.prompt)}</div>
          </div>
          <div class="pct">${pct}%<small>juist</small></div>
        </div>
        <div class="bar"><div class="bar-fill" style="width:${pct}%"></div></div>
      </div>`;
  }).join("");
  const html = `<!DOCTYPE html><html lang="nl"><head><meta charset="utf-8">
<title>Resultaten — ${esc(session.quiz_title)} — ${esc(session.code)}</title>
<style>
  @page { size: A4; margin: 18mm 16mm; }
  * { box-sizing: border-box; }
  body { font-family: -apple-system, "Helvetica Neue", Arial, sans-serif; color: #0a0a0a; margin: 0; padding: 0; line-height: 1.4; }
  header { border-bottom: 3px double #0a0a0a; padding-bottom: 12px; margin-bottom: 18px; }
  .kicker { font-family: ui-monospace, "SFMono-Regular", monospace; font-size: 10px; letter-spacing: 0.18em; color: #555; text-transform: uppercase; }
  h1 { font-size: 28px; margin: 4px 0 6px; letter-spacing: -0.02em; }
  .meta { font-size: 11px; color: #555; }
  h2 { font-size: 14px; letter-spacing: 0.18em; text-transform: uppercase; margin: 22px 0 10px; padding-bottom: 6px; border-bottom: 1px solid #0a0a0a; }
  table { width: 100%; border-collapse: collapse; margin-bottom: 20px; }
  th, td { padding: 6px 4px; border-bottom: 1px dashed #bbb; vertical-align: middle; }
  th { text-align: left; font-size: 10px; letter-spacing: 0.12em; text-transform: uppercase; color: #555; }
  td.rank { width: 28px; font-weight: 700; }
  td.num { text-align: right; font-weight: 700; font-size: 16px; }
  .team { font-size: 9px; letter-spacing: 0.1em; color: #777; text-transform: uppercase; margin-left: 6px; }
  .q { padding: 10px 0; border-bottom: 1px solid #ddd; page-break-inside: avoid; }
  .q-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 16px; }
  .q-prompt { font-size: 14px; margin-top: 2px; }
  .pct { font-size: 22px; font-weight: 800; text-align: right; line-height: 1; }
  .pct small { display: block; font-size: 9px; color: #777; letter-spacing: 0.1em; text-transform: uppercase; font-weight: 400; margin-top: 4px; }
  .bar { height: 4px; background: #eee; margin-top: 8px; }
  .bar-fill { height: 100%; background: #0a0a0a; }
  footer { margin-top: 28px; padding-top: 10px; border-top: 1px solid #0a0a0a; font-size: 9px; color: #777; letter-spacing: 0.12em; text-transform: uppercase; display: flex; justify-content: space-between; }
  @media print { .no-print { display: none !important; } }
  .no-print { background: #f0e9d6; padding: 10px 14px; margin: 0 0 16px; border: 1px solid #0a0a0a; font-size: 12px; display: flex; justify-content: space-between; align-items: center; }
  .no-print button { font-family: inherit; padding: 6px 14px; border: 2px solid #0a0a0a; background: #0a0a0a; color: #fff; cursor: pointer; font-size: 12px; letter-spacing: 0.06em; }
</style></head><body>
<div class="no-print">
  <span><strong>Tip:</strong> kies "Opslaan als PDF" als bestemming in de print-dialog.</span>
  <button onclick="window.print()">Print → PDF</button>
</div>
<header>
  <div class="kicker">KWIST HET! · RESULTATEN · ${esc(session.code)}</div>
  <h1>${esc(session.quiz_title)}</h1>
  <div class="meta">${esc((session.quiz_category || "").toUpperCase())} · ${players.length} spelers · gespeeld op ${esc(fmt(session.started_at || session.created_at))}</div>
</header>
<h2>Klassement</h2>
<table>
  <thead><tr><th>#</th><th>Speler</th><th style="text-align:right">Score</th></tr></thead>
  <tbody>${playerRows || `<tr><td colspan="3" style="color:#777">Geen spelers</td></tr>`}</tbody>
</table>
${questions.length ? `<h2>Per vraag</h2>${questionBlocks}` : ""}
<footer>
  <span>Geëxporteerd ${esc(new Date().toLocaleString("nl-BE"))}</span>
  <span>kwisthet.be</span>
</footer>
<script>window.addEventListener("load", () => setTimeout(() => window.print(), 300));</script>
</body></html>`;
  const w = window.open("", "_blank", "width=900,height=1200");
  if (!w) {
    alert("Popups blokkeren staan aan — sta popups toe om de PDF-export te openen.");
    return;
  }
  w.document.open();
  w.document.write(html);
  w.document.close();
}

function SessionDetail({ theme, data, onBack }) {
  const { session, players, answers } = data;
  const questionMap = {};
  (answers || []).forEach((a) => {
    if (!questionMap[a.question_id]) questionMap[a.question_id] = { position: a.position, prompt: a.prompt, type: a.type, answers: [] };
    questionMap[a.question_id].answers.push(a);
  });
  const questions = Object.values(questionMap).sort((a, b) => a.position - b.position);

  return (
    <div style={{ marginTop: 24 }}>
      <button onClick={onBack} style={{
        background: "transparent", border: "none",
        fontFamily: theme.fonts.display, fontSize: 16, color: theme.fg, cursor: "pointer",
        marginBottom: 20,
      }}>← terug naar overzicht</button>

      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", marginBottom: 24 }}>
        <div>
          <Display theme={theme} size={42}>{session.quiz_title}</Display>
          <Eyebrow theme={theme} style={{ marginTop: 4 }}>{(session.quiz_category || "").toUpperCase()} · {session.code}</Eyebrow>
        </div>
        <div style={{ display: "flex", alignItems: "center", gap: 16 }}>
          <Eyebrow theme={theme}>{players.length} SPELERS</Eyebrow>
          <button onClick={() => exportSessionPdf(data)} style={{
            background: "transparent", color: theme.fg,
            border: `2px solid ${theme.fg}`, padding: "8px 16px",
            fontFamily: theme.fonts.display, fontSize: 13, cursor: "pointer",
            letterSpacing: "0.04em", textTransform: "uppercase",
          }}>↓ Download PDF</button>
        </div>
      </div>

      <Eyebrow theme={theme} style={{ marginBottom: 12 }}>── KLASSEMENT</Eyebrow>
      <div style={{ marginBottom: 36 }}>
        {players.map((p, i) => (
          <div key={p.id} style={{
            display: "grid", gridTemplateColumns: "32px 36px 1fr auto",
            alignItems: "center", gap: 14,
            padding: "10px 0",
            borderBottom: `1px dashed ${theme.rule}`,
          }}>
            <FigureNum theme={theme} size={18}>{i + 1}</FigureNum>
            <Monogram theme={theme} text={p.initials} size={32} color={i < 3 ? theme.accent : theme.fg} />
            <div>
              <span style={{ fontFamily: theme.fonts.display, fontSize: 18 }}>{p.name}</span>
              {p.team && <Eyebrow theme={theme} style={{ marginLeft: 8 }}>{p.team}</Eyebrow>}
            </div>
            <FigureNum theme={theme} size={22} accent>{(p.score || 0).toLocaleString("nl-NL")}</FigureNum>
          </div>
        ))}
      </div>

      {questions.length > 0 && (
        <>
          <Eyebrow theme={theme} style={{ marginBottom: 12 }}>── PER VRAAG</Eyebrow>
          {questions.map((q, qi) => {
            const total = q.answers.length;
            const correctCount = q.answers.filter((a) => a.correct).length;
            const pct = total ? Math.round((correctCount / total) * 100) : 0;
            return (
              <div key={qi} style={{ marginBottom: 20, padding: "14px 0", borderBottom: `1px solid ${theme.rule}` }}>
                <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline" }}>
                  <div>
                    <Eyebrow theme={theme} style={{ color: theme.accent }}>VRAAG {q.position + 1} · {q.type.toUpperCase()}</Eyebrow>
                    <div style={{ fontFamily: theme.fonts.display, fontSize: 20, marginTop: 4 }}>{q.prompt}</div>
                  </div>
                  <div style={{ textAlign: "right" }}>
                    <FigureNum theme={theme} size={28} accent>{pct}%</FigureNum>
                    <div style={{ fontFamily: theme.fonts.mono, fontSize: 11, color: theme.fgDim }}>juist</div>
                  </div>
                </div>
                <div style={{ marginTop: 8, height: 6, background: theme.rule, position: "relative" }}>
                  <div style={{
                    position: "absolute", top: 0, left: 0, height: "100%",
                    width: `${pct}%`,
                    background: pct >= 50 ? theme.accent : theme.signal || theme.accent,
                  }} />
                </div>
              </div>
            );
          })}
        </>
      )}
    </div>
  );
}

function TrendingScreen({ theme, user, onNav, onLogout, onAdmin }) {
  return (
    <PlaceholderShell
      theme={theme} user={user} onLogout={onLogout} onAdmin={onAdmin} onNav={onNav} current="trending"
      eyebrow="TRENDING"
      title={<>Wat <span style={{ color: theme.accent }}>iedereen</span> deze week speelt.</>}
      lede="Ranglijsten op basis van plays, deelnemers en gem. score. Een redactionele top-tien, automatisch ververst. Komt eraan zodra er voldoende publieke quizzes zijn."
      columns={[
        { kicker: "TOP-10 QUIZZES", title: "Meeste plays", body: "Live ranking van wat het hardst loopt — per week en per jaar. Filterbaar op categorie." },
        { kicker: "TOP HOSTS", title: "De redacteuren", body: "Welke maker zet de meeste sessies neer? Met links naar hun publieke quizzes." },
        { kicker: "OPKOMEND", title: "Net binnen", body: "Quizzes die plotseling pieken, zodat je ze kunt pakken voordat ze mainstream worden." },
      ]}
    />
  );
}

function TeamScreen({ theme, user, onNav, onLogout, onAdmin }) {
  const [invitee, setInvitee] = useStatePH("");
  return (
    <PlaceholderShell
      theme={theme} user={user} onLogout={onLogout} onAdmin={onAdmin} onNav={onNav} current="team"
      eyebrow="HET TEAM"
      title={<>Quizzes maak je <span style={{ color: theme.accent }}>samen</span>.</>}
      lede="Nodig collega's of vrienden uit om mee te schrijven. Iedereen ziet dezelfde drafts, dezelfde plays-stats. Functionaliteit komt na de huidige iteratie — onderstaand alvast hoe het zal voelen."
      columns={[
        { kicker: "WERKRUIMTES", title: "Eén space per organisatie", body: "Gedeelde quizzes, gedeelde brand, gedeelde billing. Met rollen: editor / viewer / admin." },
        { kicker: "UITNODIGINGEN", title: "Op e-mail of magic link", body: "Geen onboarding-friction — accepteer en je staat in de juiste workspace." },
        { kicker: "AUDIT-LOG", title: "Wie wijzigde wat", body: "Voor teams die compliance nodig hebben — wie wat aanpaste, en wanneer." },
      ]}
      cta={[
        { label: "Vraag vroege toegang", onClick: () => alert(`Bedankt — we koppelen je terug zodra teams live gaan.${invitee ? "\n(genoteerd: " + invitee + ")" : ""}`) },
      ]}
    />
  );
}

window.LibraryScreen = LibraryScreen;
window.StatsScreen = StatsScreen;
window.TrendingScreen = TrendingScreen;
window.TeamScreen = TeamScreen;
