const { useState, useEffect, useRef, useCallback } = React;

const api = {
    token: null,
    async get(url) {
        const r = await fetch(url, { headers: { 'X-Admin-Token': this.token } });
        if (!r.ok) throw new Error((await r.json().catch(() => ({}))).error || r.statusText);
        return r.json();
    },
    async post(url, data) {
        const r = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Admin-Token': this.token }, body: JSON.stringify(data) });
        if (!r.ok) throw new Error((await r.json().catch(() => ({}))).error || r.statusText);
        return r.json();
    },
};

function wsUrl() {
    return `${location.protocol === 'https:' ? 'wss:' : 'ws:'}//${location.host}`;
}

function fieldVal(field, fallback) {
    if (!field) return fallback || '';
    if (typeof field === 'string') return field;
    if (typeof field === 'object' && field.value !== undefined) return field.value;
    return String(field);
}

/* ================================================================== */
/*  Login                                                              */
/* ================================================================== */

function LoginPage({ onLogin }) {
    const [pw, setPw] = useState('');
    const [err, setErr] = useState('');
    const submit = async () => {
        try {
            const res = await api.post('/api/admin/login', { password: pw });
            api.token = res.token;
            onLogin(res.token);
        } catch (e) { setErr(e.message); }
    };
    return (
        <div className="min-h-screen flex items-center justify-center bg-stone-100">
            <div className="bg-white rounded-2xl shadow-lg p-8 w-full max-w-sm border-t-4 border-red-600">
                <img src="/img/logo.png" alt="Quizalarm" className="w-16 h-16 mx-auto mb-2" />
                <h1 className="text-2xl font-bold mb-6 text-center">Quizalarm Admin</h1>
                <input type="password" className="w-full p-3 border rounded-lg mb-3 text-center focus:border-red-500 outline-none" placeholder="Passwort" value={pw} onChange={(e) => setPw(e.target.value)} onKeyDown={(e) => e.key === 'Enter' && submit()} autoFocus />
                {err && <p className="text-red-500 text-sm mb-3 text-center">{err}</p>}
                <button onClick={submit} className="w-full py-3 bg-red-600 text-white rounded-lg font-bold hover:bg-red-700">Anmelden</button>
            </div>
        </div>
    );
}

/* ================================================================== */
/*  Config Page                                                        */
/* ================================================================== */

function ConfigPage({ config, setConfig, saveConfig }) {
    const [newSetName, setNewSetName] = useState('');
    const [newSetTableId, setNewSetTableId] = useState('');
    const [newSetWettkampfCount, setNewSetWettkampfCount] = useState('');
    const [newSetColor, setNewSetColor] = useState('#d97706');
    const [newSetTimer, setNewSetTimer] = useState('');
    const [msg, setMsg] = useState('');
    const [debugResult, setDebugResult] = useState(null);

    const addSet = () => {
        if (!newSetName || !newSetTableId) return;
        const wkCount = parseInt(newSetWettkampfCount) || null;
        const wkTimer = parseInt(newSetTimer) || null;
        const updated = {
            ...config,
            sets: [...(config.sets || []), { id: Date.now().toString(36), name: newSetName, tableId: parseInt(newSetTableId), wettkampfCount: wkCount, color: newSetColor, wettkampfTimer: wkTimer }],
        };
        setConfig(updated);
        saveConfig(updated);
        setNewSetName('');
        setNewSetTableId('');
        setNewSetWettkampfCount('');
        setNewSetColor('#d97706');
        setNewSetTimer('');
        setMsg('Fragenset hinzugefügt!');
        setTimeout(() => setMsg(''), 3000);
    };

    const removeSet = (id) => {
        const updated = { ...config, sets: config.sets.filter((s) => s.id !== id) };
        setConfig(updated);
        saveConfig(updated);
    };

    const updateSetWettkampfCount = (setId, val) => {
        const wkCount = parseInt(val) || null;
        const updated = { ...config, sets: config.sets.map((s) => s.id === setId ? { ...s, wettkampfCount: wkCount } : s) };
        setConfig(updated);
        saveConfig(updated);
    };

    const updateSetColor = (setId, val) => {
        const updated = { ...config, sets: config.sets.map((s) => s.id === setId ? { ...s, color: val } : s) };
        setConfig(updated);
        saveConfig(updated);
    };

    const updateSetTimer = (setId, val) => {
        const wkTimer = parseInt(val) || null;
        const updated = { ...config, sets: config.sets.map((s) => s.id === setId ? { ...s, wettkampfTimer: wkTimer } : s) };
        setConfig(updated);
        saveConfig(updated);
    };

    const updateAnswersTable = (val) => {
        const updated = { ...config, answersTableId: val ? parseInt(val) : null };
        setConfig(updated);
        saveConfig(updated);
    };

    const testConnection = async () => {
        try {
            setDebugResult('Teste...');
            const result = await api.get('/api/admin/debug-baserow');
            setDebugResult(JSON.stringify(result, null, 2));
        } catch (e) {
            setDebugResult('Fehler: ' + e.message);
        }
    };

    return (
        <div className="space-y-6">
            <div className="bg-white rounded-xl shadow p-6 border-l-4 border-red-600">
                <h2 className="text-xl font-bold mb-4">📋 Fragensets</h2>
                {(config.sets || []).length === 0 && <p className="text-gray-500 mb-3">Noch keine Fragensets konfiguriert.</p>}
                {(config.sets || []).map((s) => (
                    <div key={s.id} className="py-3 border-b last:border-0">
                        <div className="flex items-center justify-between">
                            <div className="flex items-center gap-2">
                                <div style={{ backgroundColor: s.color || '#d97706', width: 16, height: 16, borderRadius: 4, flexShrink: 0 }} />
                                <span className="font-semibold">{s.name}</span>
                                <span className="text-gray-400 text-sm">(Table ID: {s.tableId})</span>
                            </div>
                            <button onClick={() => removeSet(s.id)} className="text-red-500 hover:text-red-700 text-sm">Entfernen</button>
                        </div>
                        <div className="flex flex-wrap items-center gap-3 mt-2">
                            <div className="flex items-center gap-1">
                                <span className="text-sm text-gray-500">🎨</span>
                                <input type="color" value={s.color || '#d97706'} onChange={(e) => updateSetColor(s.id, e.target.value)} className="w-8 h-8 border rounded cursor-pointer" style={{ padding: 0 }} />
                            </div>
                            <div className="flex items-center gap-1">
                                <span className="text-sm text-gray-500">⚔️ Fragen:</span>
                                <input className="w-16 p-1 border rounded text-center text-sm focus:border-emerald-500 outline-none" type="number" min="1" placeholder="—" value={s.wettkampfCount || ''} onChange={(e) => updateSetWettkampfCount(s.id, e.target.value)} />
                            </div>
                            <div className="flex items-center gap-1">
                                <span className="text-sm text-gray-500">⏱ Timer (Min):</span>
                                <input className="w-16 p-1 border rounded text-center text-sm focus:border-emerald-500 outline-none" type="number" min="1" placeholder="—" value={s.wettkampfTimer || ''} onChange={(e) => updateSetTimer(s.id, e.target.value)} />
                            </div>
                        </div>
                    </div>
                ))}
                <div className="mt-4 space-y-2">
                    <div className="flex gap-2 flex-wrap">
                        <input className="flex-1 min-w-0 p-2 border rounded-lg focus:border-red-500 outline-none" placeholder="Name" value={newSetName} onChange={(e) => setNewSetName(e.target.value)} />
                        <input className="w-24 p-2 border rounded-lg focus:border-red-500 outline-none" placeholder="Table ID" type="number" value={newSetTableId} onChange={(e) => setNewSetTableId(e.target.value)} />
                        <input type="color" value={newSetColor} onChange={(e) => setNewSetColor(e.target.value)} className="w-10 h-10 border rounded cursor-pointer" style={{ padding: 0 }} />
                    </div>
                    <div className="flex gap-2 flex-wrap">
                        <input className="w-24 p-2 border rounded-lg focus:border-emerald-500 outline-none" placeholder="⚔️ Anz." type="number" min="1" value={newSetWettkampfCount} onChange={(e) => setNewSetWettkampfCount(e.target.value)} />
                        <input className="w-28 p-2 border rounded-lg focus:border-emerald-500 outline-none" placeholder="⏱ Timer (Min)" type="number" min="1" value={newSetTimer} onChange={(e) => setNewSetTimer(e.target.value)} />
                        <button onClick={addSet} className="px-4 py-2 bg-red-600 text-white rounded-lg font-bold hover:bg-red-700">+ Hinzufügen</button>
                    </div>
                </div>
                {msg && <p className="text-green-600 text-sm mt-2">{msg}</p>}
            </div>

            <div className="bg-white rounded-xl shadow p-6 border-l-4 border-amber-500">
                <h2 className="text-xl font-bold mb-4">💾 Antworten-Tabelle</h2>
                <div className="flex gap-2 items-center">
                    <span className="text-gray-600">Table ID:</span>
                    <input className="w-32 p-2 border rounded-lg focus:border-amber-500 outline-none" type="number" value={config.answersTableId || ''} onChange={(e) => updateAnswersTable(e.target.value)} placeholder="Table ID" />
                </div>
            </div>

            <div className="bg-white rounded-xl shadow p-6 border-l-4 border-gray-400">
                <h2 className="text-xl font-bold mb-4">🔧 Verbindungstest</h2>
                <button onClick={testConnection} className="px-4 py-2 bg-gray-700 text-white rounded-lg hover:bg-gray-800">Baserow-Verbindung testen</button>
                {debugResult && (
                    <pre className="mt-3 bg-gray-100 p-3 rounded-lg text-sm overflow-x-auto max-h-64 whitespace-pre-wrap">{debugResult}</pre>
                )}
            </div>
        </div>
    );
}

/* ================================================================== */
/*  Stats Page                                                         */
/* ================================================================== */

function StatsPage() {
    const [data, setData] = useState(null);
    const [filter, setFilter] = useState('');
    const [err, setErr] = useState('');

    useEffect(() => {
        api.get('/api/admin/stats').then(setData).catch((e) => setErr(e.message));
    }, []);

    if (err) return <div className="bg-white rounded-xl shadow p-6"><p className="text-red-500">{err}</p></div>;
    if (!data) return <p className="text-center py-8">Lade Statistiken...</p>;
    if (!data.answers.length) return <p className="text-center py-8 text-gray-500">Noch keine Ergebnisse vorhanden.</p>;

    const sessions = {};
    data.answers.forEach((a) => {
        const sid = a['Session_ID'] || 'Unbekannt';
        if (!sessions[sid]) sessions[sid] = { modus: fieldVal(a['Modus'], ''), fragenset: fieldVal(a['Fragenset'], ''), date: a['Zeitstempel'], answers: [] };
        sessions[sid].answers.push(a);
    });

    const users = {};
    data.answers.forEach((a) => {
        const u = a['Nutzername'] || 'Unbekannt';
        if (!users[u]) users[u] = { total: 0, correct: 0, points: 0 };
        users[u].total++;
        const richtig = a['Richtig'];
        if (richtig === true || richtig === 'true' || richtig === 1) users[u].correct++;
        users[u].points += Number(a['Punkte']) || 0;
    });

    return (
        <div className="space-y-6">
            <div className="bg-white rounded-xl shadow p-6">
                <h2 className="text-xl font-bold mb-4">📊 Übersicht</h2>
                <div className="grid grid-cols-3 gap-4 text-center">
                    <div className="bg-red-50 rounded-lg p-4"><div className="text-2xl font-bold text-red-600">{Object.keys(sessions).length}</div><div className="text-sm text-gray-500">Sessions</div></div>
                    <div className="bg-amber-50 rounded-lg p-4"><div className="text-2xl font-bold text-amber-600">{Object.keys(users).length}</div><div className="text-sm text-gray-500">Teilnehmer</div></div>
                    <div className="bg-orange-50 rounded-lg p-4"><div className="text-2xl font-bold text-orange-600">{data.answers.length}</div><div className="text-sm text-gray-500">Antworten</div></div>
                </div>
            </div>
            <div className="bg-white rounded-xl shadow p-6">
                <h3 className="text-lg font-bold mb-3">👤 Pro Teilnehmer</h3>
                <input className="w-full p-2 border rounded-lg mb-3 focus:border-red-500 outline-none" placeholder="Filtern..." value={filter} onChange={(e) => setFilter(e.target.value)} />
                <div className="overflow-x-auto">
                    <table className="w-full text-sm">
                        <thead><tr className="border-b"><th className="text-left py-2">Name</th><th>Richtig</th><th>Gesamt</th><th>Quote</th><th>Punkte</th></tr></thead>
                        <tbody>
                            {Object.entries(users).filter(([u]) => !filter || u.toLowerCase().includes(filter.toLowerCase())).sort(([, a], [, b]) => b.points - a.points).map(([u, v]) => (
                                <tr key={u} className="border-b last:border-0">
                                    <td className="py-2 font-medium">{u}</td>
                                    <td className="text-center text-green-600">{v.correct}</td>
                                    <td className="text-center">{v.total}</td>
                                    <td className="text-center">{Math.round((v.correct / v.total) * 100)}%</td>
                                    <td className="text-center font-bold">{v.points.toLocaleString('de')}</td>
                                </tr>
                            ))}
                        </tbody>
                    </table>
                </div>
            </div>
            <div className="bg-white rounded-xl shadow p-6">
                <h3 className="text-lg font-bold mb-3">📁 Sessions</h3>
                {Object.entries(sessions).reverse().map(([sid, s]) => {
                    const total = s.answers.length;
                    const correct = s.answers.filter((a) => {
                        const v = a['Richtig'];
                        return v === true || v === 'true' || v === 1;
                    }).length;
                    const uniqueUsers = new Set(s.answers.map((a) => a['Nutzername'])).size;
                    return (
                        <div key={sid} className="border-b last:border-0 py-3">
                            <div className="flex justify-between">
                                <span><span className={`text-xs px-2 py-0.5 rounded-full text-white ${s.modus === 'Live' ? 'bg-red-600' : 'bg-amber-600'}`}>{s.modus}</span> <strong>{s.fragenset}</strong></span>
                                <span className="text-sm text-gray-400">{s.date ? new Date(s.date).toLocaleString('de') : ''}</span>
                            </div>
                            <div className="text-sm text-gray-500 mt-1">{uniqueUsers} Teilnehmer — {correct}/{total} richtig gesamt</div>
                        </div>
                    );
                })}
            </div>
        </div>
    );
}

/* ================================================================== */
/*  Live Setup Page — with custom code + reconnect                     */
/* ================================================================== */

function LiveSetupPage({ config, token, onSessionCreated }) {
    const [setId, setSetId] = useState('');
    const [shuffle, setShuffle] = useState(true);
    const [scoring, setScoring] = useState('binary');
    const [timeLimit, setTimeLimit] = useState(30);
    const [customCode, setCustomCode] = useState('');
    const [error, setError] = useState('');
    const [loading, setLoading] = useState(false);

    // Reconnect state
    const [reconnectCode, setReconnectCode] = useState('');
    const [reconnectError, setReconnectError] = useState('');
    const [reconnecting, setReconnecting] = useState(false);

    const create = () => {
        if (!setId) return setError('Bitte ein Fragenset waehlen');
        setLoading(true);
        setError('');
        const ws = new WebSocket(wsUrl());
        ws.onopen = () => {
            ws.send(JSON.stringify({
                type: 'admin-create', token, setId,
                options: { shuffle, scoring, timeLimit },
                customCode: customCode.trim() || null,
            }));
        };
        ws.onmessage = (e) => {
            const msg = JSON.parse(e.data);
            if (msg.type === 'session-created') {
                ws.onmessage = null;
                onSessionCreated(msg.code, ws, {
                    code: msg.code,
                    setName: msg.setName,
                    questionCount: msg.questionCount,
                    options: msg.options,
                    players: [],
                    playerCount: 0,
                    presentToken: msg.presentToken,
                });
            } else if (msg.type === 'error') {
                setError(msg.message);
                setLoading(false);
                ws.close();
            }
        };
        ws.onerror = () => { setError('WebSocket Verbindungsfehler'); setLoading(false); };
    };

    const reconnect = () => {
        const code = reconnectCode.trim().replace(/[^a-zA-Z0-9]/g, '').toUpperCase();
        if (!code) return setReconnectError('Bitte Code eingeben');
        setReconnecting(true);
        setReconnectError('');

        const ws = new WebSocket(wsUrl());
        ws.onopen = () => {
            ws.send(JSON.stringify({ type: 'admin-join', token, code }));
        };
        ws.onmessage = (e) => {
            const msg = JSON.parse(e.data);
            if (msg.type === 'admin-joined') {
                ws.onmessage = null;
                onSessionCreated(msg.session.code, ws, msg.session);
            } else if (msg.type === 'error') {
                setReconnectError(msg.message);
                setReconnecting(false);
                ws.close();
            }
        };
        ws.onerror = () => { setReconnectError('Verbindungsfehler'); setReconnecting(false); };
    };

    return (
        <div className="space-y-6 max-w-md mx-auto">
            {/* Create new session */}
            <div className="bg-white rounded-xl shadow p-6 border-t-4 border-red-600">
                <h2 className="text-xl font-bold mb-4">🎮 Neue Live-Session</h2>
                <div className="space-y-4">
                    <div>
                        <label className="block text-sm font-medium mb-1">Fragenset</label>
                        <select className="w-full p-3 border rounded-lg focus:border-red-500 outline-none" value={setId} onChange={(e) => setSetId(e.target.value)}>
                            <option value="">— Bitte wählen —</option>
                            {(config.sets || []).map((s) => <option key={s.id} value={s.id}>{s.name}</option>)}
                        </select>
                    </div>
                    <div>
                        <label className="block text-sm font-medium mb-1">Session-Code <span className="text-gray-400">(optional)</span></label>
                        <input
                            className="w-full p-3 border rounded-lg focus:border-red-500 outline-none uppercase tracking-wider"
                            placeholder="z.B. FEUERWEHR oder leer für Zufall"
                            value={customCode}
                            onChange={(e) => setCustomCode(e.target.value)}
                            maxLength={20}
                        />
                        <p className="text-xs text-gray-400 mt-1">Nur Buchstaben und Zahlen. Mind. 3 Zeichen. Leer = zufällig generiert.</p>
                    </div>
                    <label className="flex items-center gap-2 cursor-pointer">
                        <input type="checkbox" checked={shuffle} onChange={() => setShuffle(!shuffle)} className="w-5 h-5 accent-red-600" />
                        Fragen mischen
                    </label>
                    <div>
                        <label className="block text-sm font-medium mb-1">Punktevergabe</label>
                        <select className="w-full p-3 border rounded-lg focus:border-red-500 outline-none" value={scoring} onChange={(e) => setScoring(e.target.value)}>
                            <option value="binary">Binär (1000 / 0)</option>
                            <option value="time">Zeitbasiert (schneller = mehr Punkte)</option>
                        </select>
                    </div>
                    {scoring === 'time' && (
                        <div>
                            <label className="block text-sm font-medium mb-1">Sekunden pro Frage</label>
                            <input type="number" className="w-full p-3 border rounded-lg focus:border-red-500 outline-none" value={timeLimit} onChange={(e) => setTimeLimit(parseInt(e.target.value) || 30)} min={5} max={120} />
                        </div>
                    )}
                    {error && <p className="text-red-500 text-sm bg-red-50 p-2 rounded">{error}</p>}
                    <button onClick={create} disabled={loading} className="w-full py-3 bg-red-600 text-white rounded-lg font-bold hover:bg-red-700 disabled:opacity-50">
                        {loading ? 'Erstelle...' : 'Session erstellen'}
                    </button>
                </div>
            </div>

            {/* Reconnect to existing session */}
            <div className="bg-white rounded-xl shadow p-6 border-t-4 border-amber-500">
                <h2 className="text-xl font-bold mb-4">🔄 Bestehende Session übernehmen</h2>
                <p className="text-sm text-gray-500 mb-3">Falls die Verbindung unterbrochen wurde, kannst du dich hier wieder mit einer laufenden Session verbinden.</p>
                <div className="space-y-3">
                    <input
                        className="w-full p-3 border rounded-lg focus:border-amber-500 outline-none uppercase tracking-wider text-center text-lg"
                        placeholder="Session-Code eingeben"
                        value={reconnectCode}
                        onChange={(e) => setReconnectCode(e.target.value)}
                        maxLength={20}
                        onKeyDown={(e) => e.key === 'Enter' && reconnect()}
                    />
                    {reconnectError && <p className="text-red-500 text-sm bg-red-50 p-2 rounded">{reconnectError}</p>}
                    <button onClick={reconnect} disabled={reconnecting} className="w-full py-3 bg-amber-500 text-white rounded-lg font-bold hover:bg-amber-600 disabled:opacity-50">
                        {reconnecting ? 'Verbinde...' : 'Verbinden'}
                    </button>
                </div>
            </div>
        </div>
    );
}

/* ================================================================== */
/*  Live Control Page                                                  */
/* ================================================================== */

function LiveControlPage({ token, code, ws, initialSession }) {
    const [session, setSession] = useState(initialSession || null);
    const [phase, setPhase] = useState('waiting');
    const [answerCount, setAnswerCount] = useState(0);
    const [result, setResult] = useState(null);
    const [leaderboardData, setLeaderboardData] = useState([]);
    const refreshRef = useRef(null);

    useEffect(() => {
        if (!ws) return;

        ws.onmessage = (e) => {
            const msg = JSON.parse(e.data);
            switch (msg.type) {
                case 'session-created':
                    setSession({
                        code: msg.code, setName: msg.setName, questionCount: msg.questionCount,
                        options: msg.options, players: [], playerCount: 0, presentToken: msg.presentToken,
                    });
                    setPhase('waiting');
                    break;
                case 'admin-joined':
                    setSession(msg.session);
                    setLeaderboardData(msg.session.leaderboard || []);
                    if (msg.session.status === 'waiting') setPhase('waiting');
                    else if (msg.session.status === 'ended') setPhase('ended');
                    else if (msg.session.status === 'showing-result') setPhase('result');
                    else setPhase('question');
                    break;
                case 'player-joined':
                case 'player-left':
                    setSession((s) => {
                        const base = s || { code };
                        return { ...base, players: msg.players, playerCount: msg.playerCount };
                    });
                    break;
                case 'game-start': setPhase('active'); break;
                case 'question': setPhase('question'); setAnswerCount(0); setResult(null); break;
                case 'answer-count': setAnswerCount(msg.count); break;
                case 'question-result':
                    setResult(msg); setLeaderboardData(msg.leaderboard); setPhase('result'); break;
                case 'game-end':
                    setLeaderboardData(msg.leaderboard); setPhase('ended'); break;
                case 'error': console.error('Admin error:', msg.message); break;
            }
        };

        ws.send(JSON.stringify({ type: 'admin-join', token, code }));

        refreshRef.current = setInterval(() => {
            if (ws.readyState === WebSocket.OPEN) {
                ws.send(JSON.stringify({ type: 'admin-join', token, code }));
            }
        }, 5000);

        return () => { clearInterval(refreshRef.current); ws.onmessage = null; };
    }, [ws, code, token]);

    useEffect(() => {
        if (phase !== 'waiting') clearInterval(refreshRef.current);
    }, [phase]);

    const start = () => ws.send(JSON.stringify({ type: 'admin-start', token, code }));
    const showResultAction = () => ws.send(JSON.stringify({ type: 'admin-show-result', token, code }));
    const next = () => ws.send(JSON.stringify({ type: 'admin-next', token, code }));
    const end = () => ws.send(JSON.stringify({ type: 'admin-end', token, code }));

    const presentToken = session?.presentToken || '';
    const presentUrl = `${location.origin}/present?pt=${encodeURIComponent(presentToken)}#${code}`;
    const playerCount = session?.players?.length || session?.playerCount || 0;

    return (
        <div className="space-y-4 max-w-lg mx-auto">
            <div className="bg-white rounded-xl shadow p-6 text-center border-t-4 border-red-600">
                <h2 className="text-lg font-bold mb-2">Session-Code</h2>
                <div className="text-5xl font-mono font-extrabold tracking-widest text-red-600 mb-2">{code}</div>
                <p className="text-gray-400 text-sm">{session?.setName || '...'} — {session?.questionCount || '?'} Fragen</p>
                <a href={presentUrl} target="_blank" rel="noopener" className="inline-block mt-2 text-sm text-red-500 hover:underline">📺 Präsentations-Fenster öffnen</a>
            </div>

            <div className="bg-white rounded-xl shadow p-6">
                <h3 className="font-bold mb-2">Teilnehmer ({playerCount})</h3>
                <div className="flex flex-wrap gap-2">
                    {(session?.players || []).map((n) => <span key={n} className="px-3 py-1 bg-red-50 text-red-700 rounded-full text-sm font-medium">{n}</span>)}
                </div>
                {playerCount === 0 && <p className="text-gray-400 text-sm">Noch keine Teilnehmer...</p>}
            </div>

            {phase === 'waiting' && (
                <button onClick={start} disabled={playerCount === 0} className="w-full py-4 bg-green-600 text-white rounded-xl text-xl font-bold hover:bg-green-700 disabled:opacity-50">
                    ▶ Quiz starten ({playerCount} Teilnehmer)
                </button>
            )}

            {phase === 'question' && (
                <div className="bg-white rounded-xl shadow p-6 text-center">
                    <p className="text-lg mb-3">Antworten: <strong className="text-red-600">{answerCount}</strong> / {playerCount}</p>
                    <button onClick={showResultAction} className="w-full py-3 bg-amber-500 text-white rounded-xl font-bold hover:bg-amber-600">Ergebnis zeigen ➜</button>
                </div>
            )}

            {phase === 'result' && (
                <div className="bg-white rounded-xl shadow p-6">
                    <h3 className="font-bold text-center mb-3">Ergebnis</h3>
                    {result?.stats && (
                        <div className="grid grid-cols-2 gap-2 mb-4">
                            {Object.entries(result.stats).map(([k, v]) => (
                                <div key={k} className={`p-2 rounded-lg text-white text-center ${k === 'A' ? 'bg-blue-500' : k === 'B' ? 'bg-purple-500' : k === 'C' ? 'bg-amber-500' : 'bg-cyan-500'}`}>
                                    {k}: <strong>{v}</strong>
                                </div>
                            ))}
                        </div>
                    )}
                    <p className="text-center text-sm text-gray-400 mb-3">Richtig: <strong className="text-green-600">{result?.correctAnswer?.join(', ')}</strong></p>
                    <button onClick={next} className="w-full py-3 bg-red-600 text-white rounded-xl font-bold hover:bg-red-700">Nächste Frage ➜</button>
                </div>
            )}

            {phase === 'ended' && (
                <div className="bg-white rounded-xl shadow p-6 text-center">
                    <h3 className="text-xl font-bold mb-4">🏁 Quiz beendet</h3>
                    <p className="text-gray-500">Ergebnisse wurden gespeichert.</p>
                </div>
            )}

            {leaderboardData.length > 0 && (
                <div className="bg-white rounded-xl shadow p-6">
                    <h3 className="font-bold mb-2 text-center">🏆 Leaderboard</h3>
                    {leaderboardData.map((e, i) => (
                        <div key={e.name} className={`flex justify-between py-2 px-3 rounded-lg mb-1 ${i === 0 ? 'bg-amber-100 text-amber-800' : 'bg-gray-50'}`}>
                            <span>{i === 0 ? '🥇' : i === 1 ? '🥈' : i === 2 ? '🥉' : `${e.rank}.`} {e.name}</span>
                            <span className="font-bold">{e.score}</span>
                        </div>
                    ))}
                </div>
            )}

            {phase !== 'ended' && phase !== 'waiting' && (
                <button onClick={end} className="w-full py-3 bg-gray-800 text-white rounded-xl font-bold hover:bg-gray-900">⏹ Session beenden</button>
            )}
        </div>
    );
}

/* ================================================================== */
/*  Admin App                                                          */
/* ================================================================== */

function AdminApp() {
    const [token, setToken] = useState(null);
    const [tab, setTab] = useState('config');
    const [config, setConfig] = useState({ sets: [], answersTableId: null });
    const [liveCode, setLiveCode] = useState(null);
    const [liveWs, setLiveWs] = useState(null);
    const [liveInitialSession, setLiveInitialSession] = useState(null);

    useEffect(() => {
        if (token) {
            api.token = token;
            api.get('/api/admin/config').then(setConfig).catch(console.error);
        }
    }, [token]);

    const saveConfig = async (c) => {
        try { await api.post('/api/admin/config', c); } catch (e) { console.error(e); }
    };

    const handleSessionCreated = (code, ws, sessionData) => {
        setLiveCode(code);
        setLiveWs(ws);
        setLiveInitialSession(sessionData);
        setTab('live-control');
    };

    if (!token) return <LoginPage onLogin={setToken} />;

    const tabs = [
        { id: 'config', label: '⚙️ Konfiguration' },
        { id: 'live', label: '🎮 Live-Session' },
        { id: 'stats', label: '📊 Statistiken' },
    ];
    if (liveCode) tabs.splice(2, 0, { id: 'live-control', label: '🎛️ Steuerung' });

    return (
        <div className="min-h-screen bg-stone-100">
            <div className="bg-white shadow border-b-2 border-red-600">
                <div className="max-w-3xl mx-auto px-4 py-3 flex items-center justify-between">
                    <h1 className="text-xl font-bold flex items-center gap-2"><img src="/img/logo.png" alt="" className="w-8 h-8 inline-block" /> Quizalarm Admin</h1>
                    <a href="/" className="text-gray-400 hover:text-gray-600 text-sm">← Zur App</a>
                </div>
                <div className="max-w-3xl mx-auto px-4 flex gap-1 overflow-x-auto">
                    {tabs.map((t) => (
                        <button key={t.id} onClick={() => setTab(t.id)} className={`px-4 py-2 text-sm font-medium rounded-t-lg whitespace-nowrap ${tab === t.id ? 'bg-stone-100 text-red-600 border-b-2 border-red-600' : 'text-gray-500 hover:text-gray-700'}`}>{t.label}</button>
                    ))}
                </div>
            </div>
            <div className="max-w-3xl mx-auto p-4">
                {tab === 'config' && <ConfigPage config={config} setConfig={setConfig} saveConfig={saveConfig} />}
                {tab === 'live' && <LiveSetupPage config={config} token={token} onSessionCreated={handleSessionCreated} />}
                {tab === 'live-control' && <LiveControlPage token={token} code={liveCode} ws={liveWs} initialSession={liveInitialSession} />}
                {tab === 'stats' && <StatsPage />}
            </div>
        </div>
    );
}

ReactDOM.createRoot(document.getElementById('root')).render(<AdminApp />);