/* global React, Btn, Eyebrow, Display, Rule, FigureNum, Monogram, Masthead, AppHeader, DottedCol, Field */
const { useState: useStateDash, useMemo: useMemoDash, useEffect: useEffectDash } = React;

function humanDate(iso) {
  if (!iso) return "Nooit";
  const d = new Date(iso);
  if (isNaN(d)) return "Nooit";
  const ms = Date.now() - d.getTime();
  const day = 86400000;
  const days = Math.floor(ms / day);
  if (days < 1) return "Vandaag";
  if (days === 1) return "Gisteren";
  if (days < 7) return `${days} dagen geleden`;
  if (days < 30) return `${Math.floor(days / 7)} ${Math.floor(days / 7) === 1 ? "week" : "weken"} geleden`;
  if (days < 365) return `${Math.floor(days / 30)} ${Math.floor(days / 30) === 1 ? "maand" : "maanden"} geleden`;
  return `${Math.floor(days / 365)} jaar geleden`;
}

function mapQuiz(q) {
  return {
    ...q,
    glyph: q.glyph || "♣",
    color: q.color || "#0a0a0a",
    subtitle: q.subtitle || "",
    category: q.category || "Algemeen",
    author: q.author || "Jij",
    lastPlayed: q.lastPlayed ? humanDate(q.lastPlayed) : "Nooit",
    topScore: q.topScore || 0,
    avgScore: q.avgScore || 0,
    topPlayer: q.topPlayer || "—",
    plays: q.plays || 0,
    questions: typeof q.questions === "number" ? q.questions : 0,
    draft: !!q.draft,
    library: !!q.library,
    type: q.type || "party",
  };
}

function DashboardScreen({ theme, variant, user, onCreate, onCustom, onQuickParty, onEdit, onPlay, onLogout, onNav, onAdmin }) {
  const [filter, setFilter] = useStateDash("alle");
  const [search, setSearch] = useStateDash("");
  const [quizzes, setQuizzes] = useStateDash([]);
  const [loading, setLoading] = useStateDash(true);

  const reload = async () => {
    setLoading(true);
    try {
      const r = await window.kwistApi.get("/api/quizzes");
      setQuizzes((r.quizzes || []).map(mapQuiz));
    } catch (e) {
      // 401 → niet ingelogd; laat de lijst leeg
    } finally {
      setLoading(false);
    }
  };
  useEffectDash(() => { reload(); }, []);

  const handlePlay = async (q) => {
    if (q.draft) {
      // Concept → kan niet gespeeld worden, stuur naar editor om te publiceren
      onEdit?.(q.id);
      return;
    }
    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 aanmaken mislukt: " + e.message, { kind: "error" });
    }
  };

  const handlePublish = async (q) => {
    try {
      await window.kwistApi.post(`/api/quizzes/${q.id}/publish`, {});
      reload();
    } catch (e) {
      window.kwistDialog.alert("Publiceren mislukt: " + e.message, { kind: "error" });
    }
  };

  const handleUnpublish = async (q) => {
    const ok = await window.kwistDialog.confirm(
      `"${q.title}" terug naar concept zetten? Daarna kun je de vragen weer aanpassen.`,
      { title: "Terug naar concept", confirmLabel: "Naar concept" }
    );
    if (!ok) return;
    try {
      await window.kwistApi.post(`/api/quizzes/${q.id}/unpublish`, {});
      reload();
    } catch (e) {
      window.kwistDialog.alert("Terugzetten mislukt: " + e.message, { kind: "error" });
    }
  };

  const handleDelete = async (q) => {
    const msg = q.library
      ? `Quiz "${q.title}" staat in de publieke bibliotheek en is zichtbaar voor alle gebruikers. Weet je zeker dat je deze quiz wilt verwijderen? Dit kan niet ongedaan gemaakt worden.`
      : `Quiz "${q.title}" verwijderen? Dit kan niet ongedaan gemaakt worden.`;
    const title = q.library ? "Bibliotheek-quiz verwijderen?" : "Quiz verwijderen?";
    const ok = await window.kwistDialog.confirm(msg, {
      title,
      danger: true,
      confirmLabel: q.library ? "Ja, verwijder uit bibliotheek" : "Verwijder",
    });
    if (!ok) return;
    try {
      await window.kwistApi.del(`/api/quizzes/${q.id}`);
      reload();
    } catch (e) {
      window.kwistDialog.alert("Verwijderen mislukt: " + e.message, { kind: "error" });
    }
  };

  const handleMakePublic = async (q) => {
    if (!user.isAdmin) {
      window.kwistDialog.alert("Alleen admins kunnen quizzes in de bibliotheek zetten.", { kind: "error" });
      return;
    }
    if (q.draft) {
      window.kwistDialog.alert("Publiceer de quiz eerst voordat je hem in de bibliotheek zet.", { kind: "error" });
      return;
    }
    try {
      await window.kwistApi.patch(`/api/admin/quizzes/${q.id}`, { library: true });
      reload();
    } catch (e) {
      window.kwistDialog.alert("Publiceren naar bibliotheek mislukt: " + e.message, { kind: "error" });
    }
  };

  const handleMakePrivate = async (q) => {
    const ok = await window.kwistDialog.confirm(
      `"${q.title}" uit de publieke bibliotheek halen? Andere gebruikers kunnen deze quiz dan niet meer zien.`,
      { title: "Uit bibliotheek halen?", confirmLabel: "Uit bibliotheek halen" }
    );
    if (!ok) return;
    try {
      await window.kwistApi.patch(`/api/admin/quizzes/${q.id}`, { library: false });
      reload();
    } catch (e) {
      window.kwistDialog.alert("Mislukt: " + e.message, { kind: "error" });
    }
  };

  const handleExport = async (q) => {
    try {
      const tok = window.kwistApi.getToken();
      const res = await fetch(`/api/quizzes/${q.id}/export.csv`, {
        headers: tok ? { authorization: `Bearer ${tok}` } : {},
      });
      if (!res.ok) throw new Error(`HTTP ${res.status}`);
      const blob = await res.blob();
      const url = URL.createObjectURL(blob);
      const a = document.createElement("a");
      a.href = url;
      a.download = `${(q.title || "quiz").toLowerCase().replace(/[^a-z0-9]+/g, "-")}.csv`;
      document.body.appendChild(a); a.click(); a.remove();
      setTimeout(() => URL.revokeObjectURL(url), 1000);
    } catch (e) {
      window.kwistDialog.alert("Exporteren mislukt: " + e.message, { kind: "error" });
    }
  };

  const filtered = useMemoDash(() => quizzes.filter((q) => {
    if (filter === "party" && q.type !== "party") return false;
    if (filter === "serieus" && q.type !== "serieus") return false;
    if (filter === "drafts" && !q.draft) return false;
    if (search && !q.title.toLowerCase().includes(search.toLowerCase())) return false;
    return true;
  }), [filter, search, quizzes]);

  const draftQuizzes = useMemoDash(() => quizzes.filter(q => q.draft), [quizzes]);
  const publishedQuizzes = useMemoDash(() => quizzes.filter(q => !q.draft), [quizzes]);
  const libraryQuizzes = useMemoDash(() => quizzes.filter(q => q.library), [quizzes]);
  const recentQuizzes = useMemoDash(() =>
    [...quizzes].sort((a, b) => new Date(b.updatedAt || 0) - new Date(a.updatedAt || 0)).slice(0, 3),
    [quizzes]
  );

  const stats = {
    total: quizzes.length,
    published: publishedQuizzes.length,
    drafts: draftQuizzes.length,
    plays: quizzes.reduce((a, b) => a + b.plays, 0),
    questions: quizzes.reduce((a, b) => a + b.questions, 0),
    library: libraryQuizzes.length,
  };

  return (
    <div>
      <AppHeader theme={theme} user={user} onLogout={onLogout} current="dashboard" onNav={onNav} onAdmin={onAdmin} />

      <main style={{ maxWidth: 1320, margin: "0 auto", padding: "32px 40px 80px" }}>

        {/* HERO WELCOME BLOCK */}
        <section style={{
          borderTop: `3px double ${theme.rule}`,
          padding: "40px 0 0",
        }}>
          <Eyebrow theme={theme} style={{ color: theme.accent, marginBottom: 10 }}>
            ── WELKOM TERUG, {user.name.split(" ")[0].toUpperCase()}
          </Eyebrow>
          <div style={{
            paddingBottom: 32,
            borderBottom: `1px solid ${theme.rule}`,
          }}>
            <h1 style={{
              fontFamily: theme.fonts.display, fontWeight: 800, fontStyle: "italic",
              fontSize: 64, lineHeight: 0.95, letterSpacing: "-0.04em",
              textTransform: "lowercase", margin: 0, color: theme.fg,
            }}>
              jouw <span style={{ color: theme.accent }}>kwist</span><br/>overzicht.
            </h1>
          </div>
        </section>

        {/* STAT BLOCKS */}
        <section style={{
          display: "grid", gridTemplateColumns: "repeat(5, 1fr)", gap: 0,
          borderBottom: `2px solid ${theme.rule}`,
        }}>
          {[
            { num: String(stats.total).padStart(2, "0"), label: "QUIZZES", sub: "aangemaakt", accent: true },
            { num: String(stats.published).padStart(2, "0"), label: "GEPUBLICEERD", sub: "speelbaar" },
            { num: String(stats.questions).padStart(2, "0"), label: "VRAGEN", sub: "totaal" },
            { num: String(stats.plays).padStart(2, "0"), label: "SESSIES", sub: "gespeeld" },
            { num: stats.drafts > 0 ? String(stats.drafts).padStart(2, "0") : "—", label: "CONCEPTEN", sub: "in de wacht", warn: stats.drafts > 0 },
          ].map((s, i) => (
            <div key={s.label} style={{
              padding: "28px 24px 24px",
              borderRight: i < 4 ? `1px solid ${theme.rule}` : "none",
            }}>
              <div style={{
                fontFamily: theme.fonts.display, fontWeight: 800, fontStyle: "italic",
                fontSize: 64, lineHeight: 0.9, letterSpacing: "-0.04em",
                color: s.warn ? theme.signal || "#e67e22" : s.accent ? theme.accent : theme.fg,
              }}>{s.num}</div>
              <div style={{
                fontFamily: theme.fonts.mono, fontSize: 11, letterSpacing: "0.15em",
                marginTop: 10, color: s.warn ? theme.signal || "#e67e22" : theme.fgDim,
              }}>{s.label}</div>
              <div style={{
                fontFamily: theme.fonts.body, fontSize: 13,
                marginTop: 2, color: theme.fgDim, opacity: 0.7,
              }}>{s.sub}</div>
            </div>
          ))}
        </section>

        {/* DRAFT ALERT BANNER — show when there are draft quizzes */}
        {draftQuizzes.length > 0 && (
          <section
            onClick={() => setFilter("drafts")}
            style={{
              display: "flex", alignItems: "center", gap: 16,
              padding: "16px 24px",
              borderBottom: `2px solid ${theme.rule}`,
              background: `${(theme.signal || "#e67e22")}12`,
              cursor: "pointer",
              transition: "background .15s",
            }}
            onMouseEnter={(e) => e.currentTarget.style.background = `${(theme.signal || "#e67e22")}22`}
            onMouseLeave={(e) => e.currentTarget.style.background = `${(theme.signal || "#e67e22")}12`}
          >
            <div style={{
              width: 36, height: 36,
              background: theme.signal || "#e67e22", color: "#fff",
              display: "grid", placeItems: "center",
              fontFamily: theme.fonts.display, fontWeight: 800, fontStyle: "italic",
              fontSize: 20, lineHeight: 1,
            }}>{draftQuizzes.length}</div>
            <div style={{ flex: 1 }}>
              <div style={{
                fontFamily: theme.fonts.display, fontWeight: 800, fontStyle: "italic",
                fontSize: 16, lineHeight: 1.2, textTransform: "lowercase",
              }}>
                {draftQuizzes.length === 1 ? "1 quiz is nog een concept" : `${draftQuizzes.length} quizzes zijn nog concepten`}
              </div>
              <div style={{
                fontFamily: theme.fonts.mono, fontSize: 10, letterSpacing: "0.1em",
                color: theme.fgDim, marginTop: 2,
              }}>
                {draftQuizzes.map(q => q.title).slice(0, 3).join(" · ")}{draftQuizzes.length > 3 ? ` · +${draftQuizzes.length - 3} meer` : ""}
              </div>
            </div>
            <div style={{
              fontFamily: theme.fonts.mono, fontSize: 11, letterSpacing: "0.08em",
              color: theme.signal || "#e67e22",
            }}>TOON CONCEPTEN →</div>
          </section>
        )}

        {/* SNEL STARTEN — 3 action tiles, always visible */}
        <section style={{
          display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 16,
          padding: "24px 0",
          borderBottom: `2px solid ${theme.rule}`,
        }}>
          {[
            { icon: "✦", title: "AI-quiz", body: "Kies een thema, AI maakt de vragen. Klaar in 30 seconden.", accent: true, onClick: onCreate },
            { icon: "✎", title: "Zelf schrijven", body: "Volledige controle: maak en bewerk vragen op jouw tempo.", dark: true, onClick: onCustom || onCreate },
            { icon: "⚡", title: "Quick Party", body: "Geen voorbereiding nodig — AI genereert ter plekke een quiz.", onClick: onQuickParty },
          ].map((tip) => {
            const bg = tip.accent ? theme.accent : tip.dark ? theme.fg : "#dcd6c8";
            const fg = tip.accent || tip.dark ? "#fff" : theme.fg;
            const hoverBg = tip.accent ? "#2a3de8" : tip.dark ? "#2a2a2a" : "#cfc8b8";
            return (
              <div key={tip.title} style={{
                padding: "32px 28px",
                background: bg,
                color: fg,
                cursor: "pointer",
                transition: "all .2s ease",
                display: "flex", flexDirection: "column", justifyContent: "space-between",
                minHeight: 220,
                position: "relative",
                overflow: "hidden",
              }}
                onClick={tip.onClick}
                onMouseEnter={(e) => { e.currentTarget.style.background = hoverBg; e.currentTarget.style.transform = "translateY(-3px)"; e.currentTarget.style.boxShadow = "0 8px 24px rgba(0,0,0,.12)"; }}
                onMouseLeave={(e) => { e.currentTarget.style.background = bg; e.currentTarget.style.transform = "translateY(0)"; e.currentTarget.style.boxShadow = "none"; }}
              >
                <div>
                  <div style={{
                    fontFamily: theme.fonts.display, fontWeight: 800, fontStyle: "italic",
                    fontSize: 48, lineHeight: 1, marginBottom: 16,
                    opacity: tip.accent || tip.dark ? 0.4 : 0.2,
                  }}>{tip.icon}</div>
                  <div style={{
                    fontFamily: theme.fonts.display, fontWeight: 800, fontStyle: "italic",
                    fontSize: 28, lineHeight: 1.1, textTransform: "lowercase", marginBottom: 10,
                  }}>{tip.title}</div>
                  <p style={{
                    fontSize: 14, lineHeight: 1.6, margin: 0,
                    opacity: 0.75, maxWidth: 240,
                  }}>{tip.body}</p>
                </div>
                <div style={{
                  fontFamily: theme.fonts.mono, fontSize: 11, letterSpacing: "0.12em",
                  marginTop: 20, opacity: 0.6,
                }}>START →</div>
              </div>
            );
          })}
        </section>

        {/* RECENT QUIZZES — spotlight row */}
        {recentQuizzes.length > 0 && quizzes.length >= 3 && (
          <section style={{ borderBottom: `2px solid ${theme.rule}` }}>
            <div style={{ padding: "20px 24px 8px" }}>
              <Eyebrow theme={theme} style={{ color: theme.accent }}>── RECENT BEWERKT</Eyebrow>
            </div>
            <div style={{ display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 0 }}>
              {recentQuizzes.map((q, i) => (
                <div key={q.id} onClick={() => handlePlay(q)} style={{
                  padding: "12px 24px 20px",
                  borderRight: i < 2 ? `1px solid ${theme.rule}` : "none",
                  cursor: "pointer",
                  transition: "background .15s",
                  display: "flex", gap: 14, alignItems: "center",
                }}
                  onMouseEnter={(e) => e.currentTarget.style.background = theme.bg2}
                  onMouseLeave={(e) => e.currentTarget.style.background = "transparent"}
                >
                  <div style={{
                    width: 44, height: 44, flexShrink: 0,
                    background: q.draft ? `${q.color}66` : q.color,
                    color: "#fff",
                    display: "grid", placeItems: "center",
                    fontFamily: theme.fonts.display, fontWeight: 800, fontStyle: "italic",
                    fontSize: 20, lineHeight: 1,
                    border: q.draft ? `2px dashed ${theme.signal || "#e67e22"}` : "none",
                  }}>{q.glyph}</div>
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{
                      fontFamily: theme.fonts.display, fontWeight: 800, fontStyle: "italic",
                      fontSize: 16, lineHeight: 1.15, textTransform: "lowercase",
                      whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis",
                    }}>{q.title}</div>
                    <div style={{
                      display: "flex", gap: 8, alignItems: "center", marginTop: 3,
                      fontFamily: theme.fonts.mono, fontSize: 9, letterSpacing: "0.1em", color: theme.fgDim,
                    }}>
                      <span>{q.questions} vragen</span>
                      <span>·</span>
                      {q.draft ? (
                        <span style={{
                          color: theme.signal || "#e67e22", fontWeight: 700,
                          background: `${(theme.signal || "#e67e22")}18`,
                          padding: "1px 5px",
                        }}>CONCEPT</span>
                      ) : (
                        <span style={{ color: "#27ae60" }}>GEPUBLICEERD</span>
                      )}
                    </div>
                  </div>
                  <div style={{
                    fontFamily: theme.fonts.display, fontStyle: "italic",
                    fontSize: 13, color: theme.accent,
                  }}>{q.draft ? "bewerk →" : "speel →"}</div>
                </div>
              ))}
            </div>
          </section>
        )}

        {/* SECTION HEADER */}
        <div style={{ marginTop: 40 }}>
          <Masthead theme={theme} eyebrow="── JOUW COLLECTIE"
            title={<>Mijn <span style={{ }}>quizzes</span></>}
            right={
              <div style={{ display: "flex", gap: 16, alignItems: "center" }}>
                <Eyebrow theme={theme}>{filtered.length} VAN {quizzes.length}</Eyebrow>
                <div style={{ display: "flex", gap: 4, padding: 4, background: theme.bg2, border: `1px solid ${theme.rule}`, borderRadius: 999 }}>
                  {[
                    { id: "alle", label: "Alle" },
                    { id: "party", label: "Party" },
                    { id: "serieus", label: "Werk" },
                    { id: "drafts", label: "Concept" },
                  ].map((f) => (
                    <button key={f.id} onClick={() => setFilter(f.id)} style={{
                      background: filter === f.id ? theme.fg : "transparent",
                      color: filter === f.id ? theme.bg : theme.fg,
                      border: "none",
                      borderRadius: 999,
                      padding: "6px 14px",
                      fontFamily: theme.fonts.body,
                      fontWeight: 600,
                      fontSize: 12,
                      cursor: "pointer",
                      transition: "background .15s",
                    }}>{f.label}</button>
                  ))}
                </div>
                <div style={{ width: 180 }}>
                  <Field theme={theme} value={search} onChange={setSearch} placeholder="Zoek…" />
                </div>
              </div>
            }
          />
        </div>

        {loading && quizzes.length === 0 ? (
          <div style={{ padding: 60, textAlign: "center", border: `1px dashed ${theme.rule}`, marginTop: 16 }}>
            <Eyebrow theme={theme}>BEZIG MET LADEN…</Eyebrow>
          </div>
        ) : quizzes.length === 0 ? (
          <EmptyDashboard theme={theme} onCreate={onCreate} />
        ) : filtered.length === 0 ? (
          <div style={{ padding: 60, textAlign: "center", border: `1px dashed ${theme.rule}`, marginTop: 16 }}>
            <Eyebrow theme={theme}>NIETS GEVONDEN — FILTER OF ZOEKTERM AANPASSEN</Eyebrow>
          </div>
        ) : (
          <>
            {variant === "magazine" && <MagazineLayout theme={theme} items={filtered} onPlay={handlePlay} onCreate={onCreate} onDelete={handleDelete} onExport={handleExport} onPublish={handlePublish} onUnpublish={handleUnpublish} onEdit={onEdit} onMakePublic={user.isAdmin ? handleMakePublic : null} onMakePrivate={user.isAdmin ? handleMakePrivate : null} />}
            {variant === "index" && <IndexLayout theme={theme} items={filtered} onPlay={handlePlay} onDelete={handleDelete} onExport={handleExport} onPublish={handlePublish} onUnpublish={handleUnpublish} onEdit={onEdit} onMakePublic={user.isAdmin ? handleMakePublic : null} onMakePrivate={user.isAdmin ? handleMakePrivate : null} />}
            {variant === "shelf" && <ShelfLayout theme={theme} items={filtered} onPlay={handlePlay} onDelete={handleDelete} onExport={handleExport} onPublish={handlePublish} onUnpublish={handleUnpublish} onEdit={onEdit} onMakePublic={user.isAdmin ? handleMakePublic : null} onMakePrivate={user.isAdmin ? handleMakePrivate : null} />}
          </>
        )}
      </main>

      {/* Footer */}
      <footer style={{
        borderTop: `3px double ${theme.rule}`,
        padding: "24px 40px",
        display: "flex",
        justifyContent: "space-between",
        fontFamily: theme.fonts.mono,
        fontSize: 11,
        letterSpacing: "0.1em",
        color: theme.fgDim,
      }}>
        <span>KWIST HET! · UITGEGEVEN IN ANTWERPEN</span>
        <span>HALLO@KWISTHET.BE</span>
      </footer>
    </div>
  );
}

function EmptyDashboard({ theme, onCreate }) {
  return (
    <div style={{
      marginTop: 16,
      padding: "60px 40px",
      border: `2px solid ${theme.rule}`,
      textAlign: "center",
      background: theme.bg2,
      color: theme.fg,
    }}>
      <FigureNum theme={theme} size={88} accent>00</FigureNum>
      <Display theme={theme} size={42} style={{ marginTop: 8, color: theme.fg }}>Nog geen quizzes.</Display>
      <p style={{ color: theme.fgDim, fontSize: 15, lineHeight: 1.55, maxWidth: 480, margin: "12px auto 24px" }}>
        Maak er eentje met de AI-wizard, schrijf 'm zelf, of importeer een bestaande CSV.
      </p>
      <div style={{ display: "flex", gap: 12, justifyContent: "center", flexWrap: "wrap" }}>
        <Btn theme={theme} onClick={onCreate}>✦ Met AI maken</Btn>
        <Btn theme={theme} variant="outline" onClick={onCreate}>+ Custom / CSV</Btn>
      </div>
    </div>
  );
}

// -------- MAGAZINE variant: row-based list view --------
function MagazineLayout({ theme, items, onPlay, onCreate, onDelete, onExport, onPublish, onUnpublish, onEdit, onMakePublic, onMakePrivate }) {
  if (!items.length) return null;
  const draftColor = theme.signal || "#e67e22";
  return (
    <div style={{ marginTop: 8 }}>
      {/* Table header */}
      <div style={{
        display: "grid",
        gridTemplateColumns: "6px 44px 1fr 90px 70px 100px auto",
        padding: "8px 12px 8px 0",
        fontFamily: theme.fonts.mono, fontSize: 10, letterSpacing: "0.15em",
        color: theme.fgDim,
        borderBottom: `2px solid ${theme.rule}`,
        gap: 12,
        alignItems: "center",
      }}>
        <span />
        <span />
        <span>TITEL</span>
        <span>VRAGEN</span>
        <span>SESSIES</span>
        <span>STATUS</span>
        <span style={{ textAlign: "right" }}>ACTIES</span>
      </div>

      {items.map((q, i) => (
        <QuizListRow key={q.id} theme={theme} q={q} index={i + 1} draftColor={draftColor}
          onPlay={onPlay} onDelete={onDelete} onExport={onExport}
          onPublish={onPublish} onUnpublish={onUnpublish} onEdit={onEdit}
          onMakePublic={onMakePublic} onMakePrivate={onMakePrivate} />
      ))}
    </div>
  );
}

function QuizListRow({ theme, q, index, draftColor, onPlay, onDelete, onExport, onPublish, onUnpublish, onEdit, onMakePublic, onMakePrivate }) {
  const [hover, setHover] = useStateDash(false);
  const [menuOpen, setMenuOpen] = useStateDash(false);
  const isDraft = q.draft;

  return (
    <div
      onMouseEnter={() => setHover(true)}
      onMouseLeave={() => { setHover(false); setMenuOpen(false); }}
      style={{
        display: "grid",
        gridTemplateColumns: "6px 44px 1fr 90px 70px 100px auto",
        gap: 12,
        alignItems: "center",
        padding: "14px 12px 14px 0",
        borderBottom: `1px solid ${theme.rule}`,
        background: hover ? theme.bg2 : "transparent",
        transition: "background .12s",
        cursor: "pointer",
        borderLeft: isDraft ? `4px solid ${draftColor}` : "4px solid transparent",
      }}
      onClick={() => onPlay(q)}
    >
      {/* Color accent bar */}
      <div style={{ width: 6, alignSelf: "stretch", background: q.color, borderRadius: 2 }} />

      {/* Index number */}
      <div style={{
        fontFamily: theme.fonts.display, fontWeight: 800, fontStyle: "italic",
        fontSize: 24, lineHeight: 1, color: theme.fgDim, textAlign: "center",
      }}>{("0" + index).slice(-2)}</div>

      {/* Title & meta */}
      <div style={{ minWidth: 0 }}>
        <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
          <div style={{
            fontFamily: theme.fonts.display, fontSize: 20, lineHeight: 1.2,
            fontStyle: "italic", textTransform: "lowercase",
            whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis",
          }}>{q.title}</div>
          {q.library && (
            <span style={{
              fontFamily: theme.fonts.mono, fontSize: 9, letterSpacing: "0.1em",
              background: theme.accent, color: "#fff", padding: "2px 6px",
              flexShrink: 0,
            }}>BIEB</span>
          )}
        </div>
        <div style={{
          fontFamily: theme.fonts.mono, fontSize: 10, letterSpacing: "0.08em",
          color: theme.fgDim, marginTop: 3,
        }}>
          {(q.category || "ALGEMEEN").toUpperCase()} · DOOR {q.author.toUpperCase()} · {q.lastPlayed.toUpperCase()}
        </div>
      </div>

      {/* Questions count */}
      <div style={{
        fontFamily: theme.fonts.display, fontWeight: 800, fontStyle: "italic",
        fontSize: 22, color: theme.fg,
      }}>{q.questions}</div>

      {/* Sessions count */}
      <div style={{
        fontFamily: theme.fonts.display, fontWeight: 800, fontStyle: "italic",
        fontSize: 22, color: q.plays > 0 ? theme.fg : theme.fgDim,
      }}>{q.plays || "—"}</div>

      {/* Status badge */}
      <div onClick={(e) => e.stopPropagation()}>
        {isDraft ? (
          <span style={{
            fontFamily: theme.fonts.mono, fontSize: 10, letterSpacing: "0.1em", fontWeight: 700,
            color: draftColor, border: `1.5px solid ${draftColor}`, padding: "3px 8px",
            display: "inline-block",
          }}>✎ CONCEPT</span>
        ) : (
          <span style={{
            fontFamily: theme.fonts.mono, fontSize: 10, letterSpacing: "0.1em", fontWeight: 700,
            color: "#27ae60", border: `1.5px solid #27ae60`, padding: "3px 8px",
            display: "inline-block",
          }}>GEPUBLICEERD</span>
        )}
      </div>

      {/* Action buttons */}
      <div style={{ display: "flex", gap: 6, alignItems: "center", position: "relative" }} onClick={(e) => e.stopPropagation()}>
        {isDraft ? (
          <>
            <RowBtn theme={theme} onClick={() => onEdit?.(q.id)} primary>✎ Bewerk</RowBtn>
            <RowBtn theme={theme} onClick={() => onPublish?.(q)} accent>Publiceer</RowBtn>
          </>
        ) : (
          <>
            <RowBtn theme={theme} onClick={() => onPlay(q)} primary>▶ Speel</RowBtn>
          </>
        )}
        {/* More menu */}
        <div style={{ position: "relative" }}>
          <RowBtn theme={theme} onClick={() => setMenuOpen(!menuOpen)}>⋯</RowBtn>
          {menuOpen && (
            <div style={{
              position: "absolute", top: "100%", right: 0, zIndex: 20, marginTop: 4,
              background: theme.bg, border: `1.5px solid ${theme.rule}`,
              boxShadow: `4px 4px 0 0 ${theme.rule}`,
              padding: "6px 0", minWidth: 200,
            }}>
              {isDraft ? (
                <>
                  <DropdownItem theme={theme} onClick={() => { onEdit?.(q.id); setMenuOpen(false); }}>✎ Bewerk</DropdownItem>
                  <DropdownItem theme={theme} accent onClick={() => { onPublish?.(q); setMenuOpen(false); }}>↑ Publiceer</DropdownItem>
                </>
              ) : (
                <>
                  <DropdownItem theme={theme} onClick={() => { onUnpublish?.(q); setMenuOpen(false); }}>↺ Naar concept zetten</DropdownItem>
                </>
              )}
              {onMakePublic && !q.library && !isDraft && (
                <DropdownItem theme={theme} accent onClick={() => { onMakePublic(q); setMenuOpen(false); }}>📚 In bibliotheek zetten</DropdownItem>
              )}
              {onMakePrivate && q.library && (
                <DropdownItem theme={theme} onClick={() => { onMakePrivate(q); setMenuOpen(false); }}>📚 Uit bibliotheek halen</DropdownItem>
              )}
              <DropdownItem theme={theme} onClick={() => { onExport(q); setMenuOpen(false); }}>↧ CSV exporteren</DropdownItem>
              <div style={{ height: 1, background: theme.rule, margin: "4px 0" }} />
              <DropdownItem theme={theme} danger onClick={() => { onDelete(q); setMenuOpen(false); }}>× Verwijderen</DropdownItem>
            </div>
          )}
        </div>
      </div>
    </div>
  );
}

function RowBtn({ theme, children, onClick, primary, accent }) {
  const [hover, setHover] = useStateDash(false);
  return (
    <button
      onMouseEnter={() => setHover(true)} onMouseLeave={() => setHover(false)}
      onClick={onClick}
      style={{
        background: primary ? (hover ? theme.fg : theme.accent) : hover ? theme.bg2 : "transparent",
        border: primary ? "none" : `1px solid ${accent ? theme.accent : theme.rule}`,
        color: primary ? "#fff" : accent ? theme.accent : theme.fg,
        padding: "5px 12px", cursor: "pointer",
        fontFamily: theme.fonts.mono, fontSize: 11, letterSpacing: "0.06em",
        whiteSpace: "nowrap", transition: "background .1s, color .1s",
      }}
    >{children}</button>
  );
}

function DropdownItem({ theme, children, onClick, accent, danger }) {
  const [hover, setHover] = useStateDash(false);
  return (
    <button
      onMouseEnter={() => setHover(true)} onMouseLeave={() => setHover(false)}
      onClick={onClick}
      style={{
        display: "block", width: "100%", textAlign: "left",
        background: hover ? theme.bg2 : "transparent",
        border: "none", cursor: "pointer",
        padding: "8px 16px",
        fontFamily: theme.fonts.mono, fontSize: 12, letterSpacing: "0.04em",
        color: danger ? theme.accent : accent ? theme.accent : theme.fg,
      }}>{children}</button>
  );
}

// -------- INDEX & SHELF variants: reuse row layout --------
function IndexLayout(props) { return React.createElement(MagazineLayout, props); }
function ShelfLayout(props) { return React.createElement(MagazineLayout, props); }

window.DashboardScreen = DashboardScreen;
