/* global React, Btn, Eyebrow, Display, Field, Wordmark, FigureNum, QuestionRow */
const { useState: useStateQE, useEffect: useEffectQE, useRef: useRefQE } = React;

// QuizEditor — gebruikt voor custom quizzes maken én voor het bewerken van
// bestaande drafts. Werkt op Concept-quizzes (publiceren maakt ze immutable).
function QuizEditorScreen({ theme, mode, quizId, onClose, onLaunch }) {
  // mode: "create" → maak een nieuwe draft aan; "edit" → laad bestaande draft
  const [meta, setMeta] = useStateQE({
    title: "",
    subtitle: "",
    category: "Algemeen",
    type: "party",
    color: theme.accent || "#0a0a0a",
    glyph: "♣",
  });
  const [questions, setQuestions] = useStateQE([]);
  const [savedQuizId, setSavedQuizId] = useStateQE(quizId || null);
  const [draft, setDraft] = useStateQE(true);
  const [loading, setLoading] = useStateQE(mode === "edit");
  const [saving, setSaving] = useStateQE(false);
  const [publishing, setPublishing] = useStateQE(false);
  const [error, setError] = useStateQE(null);
  const [savedFlash, setSavedFlash] = useStateQE(false);
  const [expanded, setExpanded] = useStateQE(0);
  const csvRef = useRefQE(null);

  const handleCsvImport = async (file) => {
    if (!file) return;
    try {
      const text = await file.text();
      const rows = text.split(/\r?\n/).map((line) => {
        const cells = [];
        let cur = "", inQ = false;
        for (let i = 0; i < line.length; i++) {
          const ch = line[i];
          if (ch === '"') { inQ = !inQ; continue; }
          if (ch === "," && !inQ) { cells.push(cur); cur = ""; continue; }
          cur += ch;
        }
        cells.push(cur);
        return cells.map((c) => c.trim());
      }).filter((r) => r.some((c) => c));
      if (rows.length < 2) { window.kwistDialog.alert("CSV bevat geen datarijen.", { kind: "error" }); return; }
      const hdr = rows[0].map((h) => h.toLowerCase().replace(/[^a-z0-9_]/g, ""));
      const pi = (name) => hdr.indexOf(name);
      const imported = rows.slice(1).filter((r) => r[pi("prompt")]).map((r) => {
        const opts = [];
        for (let n = 1; n <= 4; n++) {
          const oi = pi("option" + n);
          const ci = pi("correct" + n);
          if (oi >= 0 && r[oi]) {
            opts.push({
              id: String.fromCharCode(96 + n),
              text: r[oi],
              correct: ci >= 0 && (r[ci] === "true" || r[ci] === "1"),
            });
          }
        }
        if (opts.length && !opts.some((o) => o.correct)) opts[0].correct = true;
        const tl = pi("time_limit");
        return {
          type: r[pi("type")] || "mc",
          prompt: r[pi("prompt")],
          options: opts.length ? opts : blankQuestion().options,
          answer: pi("answer") >= 0 ? r[pi("answer")] || null : null,
          timeLimit: tl >= 0 && r[tl] ? parseInt(r[tl], 10) || 20 : 20,
        };
      });
      if (!imported.length) { window.kwistDialog.alert("Geen geldige vragen in CSV.", { kind: "error" }); return; }
      setQuestions((qs) => [...qs.filter((q) => q.prompt && q.prompt.trim()), ...imported]);
      setExpanded(null);
      window.kwistDialog.alert(`${imported.length} ${imported.length === 1 ? "vraag" : "vragen"} toegevoegd vanuit CSV.`, { title: "Import gelukt" });
    } catch (e) {
      window.kwistDialog.alert("CSV lezen mislukt: " + e.message, { kind: "error" });
    }
    if (csvRef.current) csvRef.current.value = "";
  };

  useEffectQE(() => {
    if (mode !== "edit" || !quizId) {
      // start met één lege vraag voor het gevoel
      setQuestions([blankQuestion()]);
      return;
    }
    (async () => {
      try {
        const r = await window.kwistApi.get(`/api/quizzes/${quizId}`);
        const q = r.quiz;
        setMeta({
          title: q.title || "",
          subtitle: q.subtitle || "",
          category: q.category || "Algemeen",
          type: q.type || "party",
          color: q.color || theme.accent,
          glyph: q.glyph || "♣",
        });
        setQuestions((q.questions || []).map((qq) => ({
          type: qq.type, prompt: qq.prompt, options: qq.options, answer: qq.answer, timeLimit: qq.timeLimit,
        })));
        setDraft(q.draft);
      } catch (e) {
        setError(e.message);
      } finally {
        setLoading(false);
      }
    })();
  }, [mode, quizId]);

  const updateQ = (i, patch) => setQuestions((qs) => qs.map((q, k) => k === i ? { ...q, ...patch } : q));
  const move = (i, dir) => {
    setQuestions((qs) => {
      const next = [...qs];
      const j = i + dir;
      if (j < 0 || j >= next.length) return qs;
      [next[i], next[j]] = [next[j], next[i]];
      setExpanded(j);
      return next;
    });
  };
  const removeQ = async (i) => {
    const ok = await window.kwistDialog.confirm(
      `Vraag ${i + 1} verwijderen?`,
      { title: "Vraag verwijderen?", danger: true, confirmLabel: "Verwijder" }
    );
    if (!ok) return;
    setQuestions((qs) => qs.filter((_, k) => k !== i));
    setExpanded(null);
  };
  const addQ = () => {
    setQuestions((qs) => {
      const next = [...qs, blankQuestion()];
      setExpanded(next.length - 1);
      return next;
    });
  };

  const save = async () => {
    if (!meta.title.trim()) { setError("Titel is verplicht."); return null; }
    setSaving(true); setError(null);
    try {
      const payload = {
        title: meta.title.trim(),
        subtitle: meta.subtitle || null,
        category: meta.category || null,
        type: meta.type,
        color: meta.color,
        glyph: meta.glyph || null,
        questions: questions.filter((q) => q.prompt && q.prompt.trim()).map((q) => ({
          type: q.type || "mc",
          prompt: q.prompt,
          options: q.options || null,
          answer: q.answer || null,
          timeLimit: q.timeLimit ?? 20,
        })),
      };
      let id = savedQuizId;
      if (!id) {
        const r = await window.kwistApi.post("/api/quizzes", payload);
        id = r.quiz.id;
        setSavedQuizId(id);
        setDraft(r.quiz.draft);
      } else {
        const r = await window.kwistApi.put(`/api/quizzes/${id}`, payload);
        setDraft(r.quiz.draft);
      }
      setSavedFlash(true);
      setTimeout(() => setSavedFlash(false), 1500);
      return id;
    } catch (e) {
      setError(e.message);
      return null;
    } finally {
      setSaving(false);
    }
  };

  const publishOnly = async () => {
    if (questions.filter((q) => q.prompt && q.prompt.trim()).length === 0) {
      setError("Je hebt minstens één vraag met tekst nodig.");
      return;
    }
    setPublishing(true); setError(null);
    try {
      const id = await save();
      if (!id) return;
      await window.kwistApi.post(`/api/quizzes/${id}/publish`, {});
      setDraft(false);
      setSavedFlash(true);
      setTimeout(() => setSavedFlash(false), 1500);
    } catch (e) {
      setError(e.message);
    } finally {
      setPublishing(false);
    }
  };

  const publishAndStart = async () => {
    if (questions.filter((q) => q.prompt && q.prompt.trim()).length === 0) {
      setError("Je hebt minstens één vraag met tekst nodig.");
      return;
    }
    setPublishing(true); setError(null);
    try {
      const id = await save();
      if (!id) return;
      const pub = await window.kwistApi.post(`/api/quizzes/${id}/publish`, {});
      const sess = await window.kwistApi.post("/api/sessions", { quizId: id, teams: false });
      onLaunch({
        id, title: pub.quiz.title, subtitle: pub.quiz.subtitle,
        category: pub.quiz.category, color: pub.quiz.color, glyph: pub.quiz.glyph || "♣",
        type: pub.quiz.type, questions: questions.filter((q) => q.prompt && q.prompt.trim()).length,
        plays: 0, code: sess.session.code, sessionId: sess.session.id,
        teamsEnabled: false,
      });
    } catch (e) {
      setError(e.message);
    } finally {
      setPublishing(false);
    }
  };

  if (loading) {
    return (
      <div style={{ minHeight: "100vh", background: theme.bg, display: "grid", placeItems: "center" }}>
        <Eyebrow theme={theme}>BEZIG MET LADEN…</Eyebrow>
      </div>
    );
  }

  return (
    <div style={{ minHeight: "100vh", background: theme.bg, display: "flex", flexDirection: "column" }}>
      <header style={{
        borderBottom: `1px solid ${theme.rule}`,
        padding: "16px 40px",
        display: "flex", alignItems: "center", justifyContent: "space-between",
      }}>
        <div style={{ display: "flex", alignItems: "center", gap: 20 }}>
          <button onClick={onClose} style={{
            background: "transparent", border: "none",
            fontFamily: theme.fonts.display, fontSize: 16, color: theme.fg, cursor: "pointer",
          }}>← naar dashboard</button>
          <div style={{ width: 1, height: 16, background: theme.rule }} />
          <Wordmark size={70} />
          <Eyebrow theme={theme} style={{ color: draft ? theme.fgDim : theme.accent }}>
            {draft ? "── CONCEPT" : "── GEPUBLICEERD"}
          </Eyebrow>
        </div>
        <Eyebrow theme={theme}>{mode === "edit" ? "QUIZ BEWERKEN" : "NIEUWE QUIZ — CUSTOM"}</Eyebrow>
      </header>

      <main style={{ flex: 1, maxWidth: 980, margin: "0 auto", width: "100%", padding: "32px 40px 120px" }}>
        <Eyebrow theme={theme} style={{ color: theme.accent, marginBottom: 14 }}>── DETAILS</Eyebrow>
        <div style={{ display: "grid", gridTemplateColumns: "2fr 1fr", gap: 24 }}>
          <div>
            <Field theme={theme} label="── Titel" value={meta.title} onChange={(v) => setMeta({ ...meta, title: v })} placeholder="Bv. Vrijdagavond pubquiz" />
            <div style={{ marginTop: 16 }}>
              <Field theme={theme} label="── Ondertitel (optioneel)" value={meta.subtitle} onChange={(v) => setMeta({ ...meta, subtitle: v })} />
            </div>
          </div>
          <div>
            <Field theme={theme} label="── Categorie" value={meta.category} onChange={(v) => setMeta({ ...meta, category: v })} />
            <div style={{ marginTop: 16, display: "grid", gridTemplateColumns: "1fr 1fr", gap: 10 }}>
              <div>
                <Eyebrow theme={theme} style={{ marginBottom: 4 }}>── Type</Eyebrow>
                <select value={meta.type} onChange={(e) => setMeta({ ...meta, type: e.target.value })} style={selectStyle(theme)}>
                  <option value="party">Party</option>
                  <option value="serieus">Serieus</option>
                </select>
              </div>
              <div>
                <Eyebrow theme={theme} style={{ marginBottom: 4 }}>── Glyph</Eyebrow>
                <input value={meta.glyph} onChange={(e) => setMeta({ ...meta, glyph: e.target.value.slice(0, 2) })} style={inputStyle(theme)} maxLength={2} />
              </div>
            </div>
          </div>
        </div>

        <div style={{ marginTop: 36, marginBottom: 14, display: "flex", justifyContent: "space-between", alignItems: "center" }}>
          <Eyebrow theme={theme} style={{ color: theme.accent }}>── VRAGEN ({questions.length})</Eyebrow>
          <div style={{ display: "flex", gap: 8, alignItems: "center" }}>
            <Btn theme={theme} variant="ghost" size="sm" onClick={() => csvRef.current?.click()}>↥ CSV importeren</Btn>
            <input ref={csvRef} type="file" accept=".csv,text/csv" style={{ display: "none" }}
              onChange={(e) => handleCsvImport(e.target.files?.[0])} />
            <Btn theme={theme} variant="outline" size="sm" onClick={addQ}>+ Vraag toevoegen</Btn>
          </div>
        </div>
        <div style={{ display: "flex", flexDirection: "column", gap: 10 }}>
          {questions.map((q, i) => (
            <QuestionRow
              key={i}
              theme={theme}
              index={i}
              total={questions.length}
              q={q}
              expanded={expanded === i}
              onToggle={() => setExpanded(expanded === i ? null : i)}
              onMoveUp={() => move(i, -1)}
              onMoveDown={() => move(i, +1)}
              onRemove={() => removeQ(i)}
              onChange={(patch) => updateQ(i, patch)}
            />
          ))}
        </div>

        {questions.length === 0 && (
          <div style={{ padding: 40, textAlign: "center", border: `1px dashed ${theme.rule}` }}>
            <Eyebrow theme={theme}>NOG GEEN VRAGEN</Eyebrow>
            <div style={{ marginTop: 12 }}>
              <Btn theme={theme} onClick={addQ}>+ Eerste vraag toevoegen</Btn>
            </div>
          </div>
        )}
      </main>

      <footer style={{
        borderTop: `1px solid ${theme.rule}`,
        padding: "14px 40px",
        background: theme.bg2,
        color: theme.fg,
        display: "flex", justifyContent: "space-between", alignItems: "center",
        position: "sticky", bottom: 0,
      }}>
        <Eyebrow theme={theme}>
          {error ? <span style={{ color: theme.accent }}>{error}</span> :
           savedFlash ? <span style={{ color: theme.accent }}>✓ OPGESLAGEN</span> :
           "WIJZIGINGEN WORDEN PAS BIJ OPSLAAN BEWAARD"}
        </Eyebrow>
        <div style={{ display: "flex", gap: 10 }}>
          {draft && (
            <Btn theme={theme} variant="outline" onClick={save} disabled={saving} style={{ opacity: saving ? 0.6 : 1 }}>
              {saving ? "Opslaan…" : "Opslaan als concept"}
            </Btn>
          )}
          {draft && (
            <Btn theme={theme} variant="outline" onClick={publishOnly} disabled={publishing || saving} style={{ opacity: (publishing || saving) ? 0.6 : 1 }}>
              {publishing ? "Bezig…" : "Publiceer"}
            </Btn>
          )}
          {!draft && (
            <Btn theme={theme} variant="outline" onClick={save} disabled={saving} style={{ opacity: saving ? 0.6 : 1 }}>
              {saving ? "Opslaan…" : "Opslaan"}
            </Btn>
          )}
          <Btn theme={theme} size="lg" onClick={publishAndStart} disabled={publishing || saving} style={{ opacity: (publishing || saving) ? 0.6 : 1 }}>
            {publishing ? "Bezig…" : "Publiceren & start sessie →"}
          </Btn>
        </div>
      </footer>
    </div>
  );
}

function blankQuestion() {
  return {
    type: "mc",
    prompt: "",
    options: [
      { id: "a", text: "", correct: true },
      { id: "b", text: "", correct: false },
      { id: "c", text: "", correct: false },
      { id: "d", text: "", correct: false },
    ],
    answer: null,
    timeLimit: 20,
  };
}

function selectStyle(theme) {
  return {
    width: "100%", padding: "10px 12px",
    border: `1px solid ${theme.rule}`,
    background: theme.bg, color: theme.fg,
    fontFamily: theme.fonts.body, fontSize: 14,
  };
}
function inputStyle(theme) {
  return {
    width: "100%", padding: "10px 12px",
    border: `1px solid ${theme.rule}`,
    background: theme.bg, color: theme.fg,
    fontFamily: theme.fonts.body, fontSize: 14,
  };
}

window.QuizEditorScreen = QuizEditorScreen;
