// app.jsx - MarioKart Liga - FINAL VERSION mit allen Fixes
const { useState, useEffect } = React;

// Lucide-style Info-Icon als SVG-Komponente
const InfoIcon = ({ tooltip }) => {
    const [show, setShow] = useState(false);
    const [pos, setPos] = useState(null);
    const iconRef = React.useRef(null);

    React.useLayoutEffect(() => {
        if (!show || !iconRef.current) { setPos(null); return; }
        const rect = iconRef.current.getBoundingClientRect();
        const margin = 8;
        const maxW = Math.min(260, window.innerWidth - 2 * margin);
        const iconCenter = rect.left + rect.width / 2;
        let left = iconCenter - maxW / 2;
        if (left < margin) left = margin;
        if (left + maxW > window.innerWidth - margin) left = window.innerWidth - margin - maxW;
        setPos({ left, top: rect.bottom + 4, maxW });
    }, [show, tooltip]);

    return React.createElement('span', {
        ref: iconRef,
        style: { position: 'relative', display: 'inline-flex', alignItems: 'center', marginLeft: '2px', verticalAlign: 'middle' },
        onClick: (e) => { e.stopPropagation(); setShow(s => !s); },
        onMouseEnter: () => setShow(true),
        onMouseLeave: () => setShow(false),
    },
        React.createElement('svg', {
            width: 13, height: 13, viewBox: '0 0 24 24', fill: 'none',
            stroke: '#9B8579', strokeWidth: 2, strokeLinecap: 'round', strokeLinejoin: 'round',
            style: { cursor: 'help', display: 'block' }
        },
            React.createElement('circle', { cx: 12, cy: 12, r: 10 }),
            React.createElement('line', { x1: 12, y1: 16, x2: 12, y2: 12 }),
            React.createElement('line', { x1: 12, y1: 8, x2: 12.01, y2: 8 }),
        ),
        show && pos && React.createElement('span', {
            style: {
                position: 'fixed',
                left: pos.left + 'px',
                top: pos.top + 'px',
                width: pos.maxW + 'px',
                background: '#2B2931', color: 'white', fontSize: '11px', padding: '6px 10px',
                borderRadius: '6px', whiteSpace: 'normal', lineHeight: 1.35,
                zIndex: 1000, fontWeight: '400', fontStyle: 'normal',
                pointerEvents: 'none', boxSizing: 'border-box',
                boxShadow: '0 2px 8px rgba(0,0,0,0.18)'
            }
        }, tooltip)
    );
};

const API_BASE = window.location.hostname === 'localhost'
    ? 'http://localhost:8888/mariokart-liga/api'
    : window.location.origin + window.location.pathname.replace(/\/[^/]*$/, '') + '/api';

const api = {
    token: localStorage.getItem('token'),
    
    setToken(token) {
        this.token = token;
        if (token) localStorage.setItem('token', token);
        else localStorage.removeItem('token');
    },
    
    async request(endpoint, options = {}) {
        const headers = { 'Content-Type': 'application/json', ...options.headers };
        if (this.token) {
            headers['Authorization'] = `Bearer ${this.token}`;
        }

        // Token als Query-Parameter mitsenden (Fallback falls Header gefiltert wird)
        let url = `${API_BASE}${endpoint}`;
        if (this.token) {
            url += (url.includes('?') ? '&' : '?') + `token=${encodeURIComponent(this.token)}`;
        }

        try {
            const response = await fetch(url, { ...options, headers });
            const data = await response.json();
            if (!response.ok) throw new Error(data.error || 'Request failed');
            return data;
        } catch (error) {
            console.error('API Error:', error);
            throw error;
        }
    },
    
    async login(username, password) {
        const data = await this.request('/auth.php?action=login', {
            method: 'POST',
            body: JSON.stringify({ username, password })
        });
        this.setToken(data.token);
        return data;
    },
    
    async logout() {
        try { await this.request('/auth.php?action=logout', { method: 'POST' }); }
        catch (e) { }
        this.setToken(null);
    },
    
    async register(username, password, displayName, initials, email) {
        const data = { username, password, display_name: displayName, initials: initials || displayName.substring(0, 2).toUpperCase() };
        if (email) data.email = email;
        return this.request('/auth.php?action=register', {
            method: 'POST',
            body: JSON.stringify(data)
        });
    },
    
    async getCurrentUser() { return this.request('/auth.php?action=me'); },
    _playersCache: null,
    _playersCacheTime: 0,
    async getPlayers(includeInactive = false) {
        if (!includeInactive && this._playersCache && Date.now() - this._playersCacheTime < 30000) {
            return this._playersCache;
        }
        const data = await this.request(`/players.php?include_inactive=${includeInactive}`);
        if (!includeInactive) { this._playersCache = data; this._playersCacheTime = Date.now(); }
        return data;
    },
    invalidatePlayersCache() { this._playersCache = null; },
    async updatePlayer(id, data) { const r = await this.request(`/players.php?id=${id}`, { method: 'PUT', body: JSON.stringify(data) }); this.invalidatePlayersCache(); return r; },
    async deactivatePlayer(id) { const r = await this.request(`/players.php?id=${id}`, { method: 'DELETE' }); this.invalidatePlayersCache(); return r; },
    async permanentDeletePlayer(id) { const r = await this.request(`/players.php?id=${id}&permanent=true`, { method: 'DELETE' }); this.invalidatePlayersCache(); return r; },
    async getMatches(limit = 50, offset = 0) { return this.request(`/matches.php?limit=${limit}&offset=${offset}`); },
    async createMatch(matchData) { const r = await this.request('/matches.php', { method: 'POST', body: JSON.stringify(matchData) }); this.invalidatePlayersCache(); return r; },
    async deleteMatch(id) { return this.request(`/matches.php?id=${id}`, { method: 'DELETE' }); },
    async getRanking() { return this.request('/leaderboard.php?action=ranking'); },
    async getRecords() { return this.request('/leaderboard.php?action=records'); },
    async getPlayerStats(playerId) { return this.request(`/leaderboard.php?action=player-stats&player_id=${playerId}`); },
    async getGlobalStats() { return this.request('/leaderboard.php?action=stats'); },
    async getSettings() { return this.request('/settings.php'); },
    async updateSettings(data) { return this.request('/settings.php', { method: 'PUT', body: JSON.stringify(data) }); },

    async changePassword(currentPassword, newPassword) {
        return this.request('/auth.php?action=change-password', {
            method: 'POST',
            body: JSON.stringify({ current_password: currentPassword, new_password: newPassword })
        });
    },

    async resetPassword(playerId, newPassword) {
        return this.request('/auth.php?action=reset-password', {
            method: 'POST',
            body: JSON.stringify({ player_id: playerId, new_password: newPassword })
        });
    },

    async uploadAvatar(file, playerId = null) {
        const formData = new FormData();
        formData.append('avatar', file);
        let url = `${API_BASE}/auth.php?action=upload-avatar`;
        if (playerId) url += `&player_id=${playerId}`;
        if (this.token) url += `&token=${encodeURIComponent(this.token)}`;
        const response = await fetch(url, { method: 'POST', body: formData });
        const data = await response.json();
        if (!response.ok) throw new Error(data.error || 'Upload failed');
        return data;
    },
};

const s = {
    card: { background: 'white', borderRadius: '16px', padding: '24px', marginBottom: '20px', boxShadow: '0 2px 8px rgba(43,41,49,0.08)' },
    btn: { padding: '12px 24px', borderRadius: '8px', border: 'none', fontSize: '16px', fontWeight: '600', cursor: 'pointer', fontFamily: 'Montserrat,sans-serif' },
    btnPrimary: { background: '#2B2931', color: 'white' },
    btnSecondary: { background: '#F5F0EB', color: '#58595B' },
    btnDanger: { background: '#9B8579', color: 'white' },
    input: { width: '100%', padding: '12px 16px', borderRadius: '8px', border: '2px solid #E8E0D8', fontSize: '16px', marginBottom: '12px', fontFamily: 'Mulish,sans-serif', boxSizing: 'border-box' },
    title: { fontSize: '28px', fontWeight: '700', marginBottom: '24px', color: '#F5F0EB', fontFamily: 'Montserrat,sans-serif' }
};

function ConfirmDialog({ title, message, onConfirm, onCancel, confirmLabel = 'Bestätigen', confirmStyle = s.btnDanger }) {
    return (
        <div style={{ position: 'fixed', top: 0, left: 0, right: 0, bottom: 0, background: 'rgba(0,0,0,0.5)', display: 'flex', alignItems: 'center', justifyContent: 'center', zIndex: 1000, padding: '20px' }}>
            <div style={{ ...s.card, maxWidth: '440px', width: '100%', marginBottom: 0 }}>
                <h3 style={{ marginBottom: '12px', color: '#2B2931' }}>{title}</h3>
                <p style={{ color: '#58595B', marginBottom: '24px', lineHeight: '1.5' }}>{message}</p>
                <div style={{ display: 'flex', gap: '12px', justifyContent: 'flex-end' }}>
                    <button onClick={onCancel} style={{ ...s.btn, ...s.btnSecondary }}>Abbrechen</button>
                    <button onClick={onConfirm} style={{ ...s.btn, ...confirmStyle }}>{confirmLabel}</button>
                </div>
            </div>
        </div>
    );
}

function Login({ onLoginSuccess }) {
    const [username, setUsername] = useState('');
    const [password, setPassword] = useState('');
    const [error, setError] = useState('');
    const [loading, setLoading] = useState(false);
    
    const handleSubmit = async (e) => {
        e.preventDefault();
        setError('');
        setLoading(true);
        try {
            const data = await api.login(username, password);
            onLoginSuccess(data.user);
        } catch (err) {
            setError(err.message);
        } finally {
            setLoading(false);
        }
    };
    
    return (
        <div style={{ maxWidth: '400px', margin: '0 auto', paddingTop: '20px' }}>
            <div style={s.card}>
                <div style={{ textAlign: 'center', fontSize: '48px', marginBottom: '12px' }}>🏎️</div>
                <h2 style={{ textAlign: 'center', marginBottom: '24px', color: '#2B2931' }}>MK-Rangliste</h2>
                <form onSubmit={handleSubmit}>
                    <input type="text" placeholder="Alias oder E-Mail" value={username} onChange={(e) => setUsername(e.target.value)} style={s.input} autoFocus />
                    <input type="password" placeholder="Passwort" value={password} onChange={(e) => setPassword(e.target.value)} style={s.input} />
                    {error && <div style={{ color: '#c0392b', marginBottom: '12px', fontSize: '14px' }}>{error}</div>}
                    <button type="submit" style={{ ...s.btn, ...s.btnPrimary, width: '100%' }} disabled={loading}>
                        {loading ? 'Anmelden...' : 'Anmelden'}
                    </button>
                </form>
            </div>
        </div>
    );
}

function Leaderboard() {
    const [ranking, setRanking] = useState([]);
    const [loading, setLoading] = useState(true);
    const [sortKey, setSortKey] = useState('elo_rating');
    const [sortDir, setSortDir] = useState('desc');
    useEffect(() => {
        (async () => {
            try {
                const data = await api.getRanking();
                setRanking(data.ranking);
            } finally {
                setLoading(false);
            }
        })();
    }, []);

    if (loading) return <div style={s.card}>Lade MK-Rangliste...</div>;

    const hasPoints = ranking.some(p => p.avg_points !== null);

    const handleSort = (key) => {
        if (sortKey === key) {
            setSortDir(d => d === 'desc' ? 'asc' : 'desc');
        } else {
            setSortKey(key);
            setSortDir(key === 'username' ? 'asc' : 'desc');
        }
    };

    const eloSorted = [...ranking].sort((a, b) => b.elo_rating - a.elo_rating);
    const gapMap = {};
    eloSorted.forEach((p, i) => {
        gapMap[p.id] = i === 0 ? null : p.elo_rating - eloSorted[i - 1].elo_rating;
    });

    const sorted = [...ranking].sort((a, b) => {
        let va = sortKey === '_gap' ? gapMap[a.id] : a[sortKey];
        let vb = sortKey === '_gap' ? gapMap[b.id] : b[sortKey];
        if (va == null) va = -Infinity;
        if (vb == null) vb = -Infinity;
        if (typeof va === 'string') {
            const cmp = va.localeCompare(vb, 'de');
            return sortDir === 'asc' ? cmp : -cmp;
        }
        return sortDir === 'asc' ? va - vb : vb - va;
    });

    const arrow = (key) => sortKey === key ? (sortDir === 'desc' ? ' ▼' : ' ▲') : '';

    const thBase = { padding: '10px 8px', textAlign: 'center', whiteSpace: 'nowrap', cursor: 'pointer', userSelect: 'none' };
    const tdBase = { padding: '10px 8px', textAlign: 'center' };
    const stickyBase = { position: 'sticky', zIndex: 2 };
    const rowEven = '#F5F0EB';
    const rowOdd = 'white';

    const columns = [
        { key: 'username', label: 'Spieler', align: 'left' },
        { key: 'elo_rating', label: 'ELO' },
        { key: '_gap', label: 'Abstand', title: 'ELO-Abstand zum nächsten Platz' },
        { key: 'total_matches', label: 'Matches' },
        { key: 'wins', label: '🥇', title: '1. Platz', style: { color: '#ffd700' } },
        { key: 'second_places', label: '🥈', title: '2. Platz', info: 'Nur 4er-Matches', style: { color: '#c0c0c0' } },
        { key: 'third_places', label: '🥉', title: '3. Platz', info: 'Nur 4er-Matches', style: { color: '#cd7f32' } },
        { key: 'fourth_places', label: '🚨', title: 'Letzter Platz', info: 'Nur 4er-Matches' },
        { key: 'win_rate', label: 'Siegrate' },
        { key: 'last_place_rate', label: 'Verkackerrate', title: 'Nur 4er-Matches' },
    ];
    if (hasPoints) columns.push({ key: 'avg_points', label: '∅ Punkte' });
    if (hasPoints) columns.push({ key: 'avg_points_last10', label: '∅ Pkt (10)', info: 'Durchschnittliche Punkte der letzten 10 Matches — grün = aktuelle Tendenz besser als Gesamtschnitt, rot = schlechter' });

    return (
        <div>
            <style>{`
                .lb-row { transition: background 0.12s; }
                .lb-row:hover td { background: #EDE8E3 !important; }
            `}</style>
            <h2 style={s.title}>MK-Rangliste</h2>
            <div style={s.card}>
                {ranking.length === 0 ? (
                    <div style={{ textAlign: 'center', color: '#9B8579', padding: '40px' }}>Noch keine Matches gespielt</div>
                ) : (
                    <div style={{ overflowX: 'auto' }}>
                        <table style={{ width: '100%', borderCollapse: 'separate', borderSpacing: 0, fontSize: '14px' }}>
                            <thead>
                                <tr style={{ borderBottom: '2px solid #E8E0D8' }}>
                                    <th style={{ ...thBase, textAlign: 'left', cursor: 'default', ...stickyBase, left: 0, minWidth: '40px', background: 'white', zIndex: 3, borderBottom: '2px solid #E8E0D8' }}>#</th>
                                    <th onClick={() => handleSort('username')} title="Spieler" style={{ ...thBase, textAlign: 'left', ...stickyBase, left: '40px', minWidth: '160px', background: 'white', zIndex: 3, borderBottom: '2px solid #E8E0D8', boxShadow: '2px 0 4px rgba(0,0,0,0.06)' }}>Spieler{arrow('username')}</th>
                                    {columns.slice(1).map(col => (
                                        <th key={col.key} onClick={() => handleSort(col.key)} title={col.title || col.label} style={{ ...thBase, textAlign: col.align || 'center', ...(col.style || {}), borderBottom: '2px solid #E8E0D8' }}>
                                            {col.label}{col.info && <InfoIcon tooltip={col.info} />}{arrow(col.key)}
                                        </th>
                                    ))}
                                </tr>
                            </thead>
                            <tbody>
                                {sorted.map((p, idx) => {
                                    const bg = idx % 2 === 0 ? rowOdd : rowEven;
                                    return (
                                        <tr key={p.id} className="lb-row" onClick={() => navigate('player-stats/' + p.id)} style={{ cursor: 'pointer' }}>
                                            <td style={{ ...tdBase, textAlign: 'left', fontWeight: '700', fontSize: '16px', ...stickyBase, left: 0, background: bg, minWidth: '40px', borderBottom: '1px solid #EDE8E3' }}>
                                                {p.rank <= 3 ? ['🥇','🥈','🥉'][p.rank - 1] : p.rank}
                                            </td>
                                            <td style={{ ...tdBase, textAlign: 'left', fontWeight: '600', ...stickyBase, left: '40px', background: bg, minWidth: '160px', borderBottom: '1px solid #EDE8E3', boxShadow: '2px 0 4px rgba(0,0,0,0.06)' }}>
                                                <div style={{ display: 'flex', alignItems: 'center', gap: '10px' }}>
                                                    {p.profile_picture ? (
                                                        <img src={p.profile_picture} alt="" style={{ width: '32px', height: '32px', borderRadius: '50%', objectFit: 'cover', flexShrink: 0 }} />
                                                    ) : (
                                                        <div style={{ width: '32px', height: '32px', borderRadius: '50%', background: '#58595B', color: 'white', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: '12px', fontWeight: '700', flexShrink: 0 }}>{p.initials || p.username.substring(0, 2).toUpperCase()}</div>
                                                    )}
                                                    <div>
                                                        <div>{p.username}</div>
                                                        <div style={{ fontSize: '12px', color: '#9B8579', fontWeight: '400' }}>{p.display_name}</div>
                                                    </div>
                                                </div>
                                            </td>
                                            <td style={{ ...tdBase, fontWeight: '700', color: '#2B2931', background: bg, borderBottom: '1px solid #EDE8E3' }}>{p.elo_rating}</td>
                                            <td style={{ ...tdBase, fontSize: '12px', color: gapMap[p.id] == null ? '#9B8579' : '#c0392b', background: bg, borderBottom: '1px solid #EDE8E3' }}>{gapMap[p.id] == null ? '—' : gapMap[p.id]}</td>
                                            <td style={{ ...tdBase, background: bg, borderBottom: '1px solid #EDE8E3' }}>{p.total_matches}</td>
                                            <td style={{ ...tdBase, fontWeight: '600', background: bg, borderBottom: '1px solid #EDE8E3' }}>{p.wins}</td>
                                            <td style={{ ...tdBase, background: bg, borderBottom: '1px solid #EDE8E3' }}>{p.second_places}</td>
                                            <td style={{ ...tdBase, background: bg, borderBottom: '1px solid #EDE8E3' }}>{p.third_places}</td>
                                            <td style={{ ...tdBase, background: bg, borderBottom: '1px solid #EDE8E3' }}>{p.fourth_places}</td>
                                            <td style={{ ...tdBase, background: bg, borderBottom: '1px solid #EDE8E3' }}>{Math.round(p.win_rate)}%</td>
                                            <td style={{ ...tdBase, color: p.last_place_rate > 30 ? '#c0392b' : undefined, background: bg, borderBottom: '1px solid #EDE8E3' }}>{Math.round(p.last_place_rate)}%</td>
                                            {hasPoints && <td style={{ ...tdBase, fontWeight: '600', background: bg, borderBottom: '1px solid #EDE8E3' }}>{p.avg_points != null ? Number(p.avg_points).toFixed(1) : '—'}</td>}
                                            {hasPoints && (() => {
                                                const v = p.avg_points_last10;
                                                const overall = p.avg_points;
                                                let color;
                                                if (v != null && overall != null) {
                                                    if (v > overall) color = '#28a745';
                                                    else if (v < overall) color = '#c0392b';
                                                }
                                                return <td style={{ ...tdBase, fontWeight: '600', color, background: bg, borderBottom: '1px solid #EDE8E3' }}>{v != null ? Number(v).toFixed(1) : '—'}</td>;
                                            })()}
                                        </tr>
                                    );
                                })}
                            </tbody>
                        </table>
                    </div>
                )}
            </div>
        </div>
    );
}

function Records() {
    const [records, setRecords] = useState(null);
    const [loading, setLoading] = useState(true);
    const [expandedRecord, setExpandedRecord] = useState(null);

    useEffect(() => {
        (async () => {
            try {
                const data = await api.getRecords();
                setRecords(data.records);
            } finally {
                setLoading(false);
            }
        })();
    }, []);

    if (loading) return <div style={s.card}>Lade Rekorde...</div>;
    if (!records) return null;

    const formatDate = (d) => d ? new Date(d).toLocaleDateString('de-DE') : '';
    const formatDateRange = (from, to) => {
        if (!from) return '';
        const f = formatDate(from);
        const t = formatDate(to);
        return f === t ? f : `${f} – ${t}`;
    };

    const RecordCard = ({ icon, title, value, sub, date, expandKey, participants }) => (
        <div onClick={participants ? () => setExpandedRecord(expandedRecord === expandKey ? null : expandKey) : undefined}
             style={{ background: '#F5F0EB', borderRadius: '12px', padding: '16px', display: 'flex', alignItems: 'flex-start', gap: '12px', flexWrap: 'wrap', cursor: participants ? 'pointer' : 'default' }}>
            <div style={{ fontSize: '28px', flexShrink: 0 }}>{icon}</div>
            <div style={{ minWidth: 0, flex: 1 }}>
                <div style={{ fontSize: '12px', color: '#9B8579', fontWeight: '600', textTransform: 'uppercase', letterSpacing: '0.5px' }}>{title}</div>
                <div style={{ fontSize: '16px', fontWeight: '700', color: '#2B2931' }}>{value}</div>
                {sub && <div style={{ fontSize: '12px', color: '#58595B', marginTop: '2px' }}>{sub}</div>}
                {date && <div style={{ fontSize: '11px', color: '#9B8579', marginTop: '2px' }}>{date}</div>}
                {expandedRecord === expandKey && participants && participants.length > 0 && (
                    <div style={{ marginTop: '8px', borderTop: '1px solid #EDE8E3', paddingTop: '8px' }}>
                        {participants.map((p, i) => (
                            <div key={i} style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '3px 0', fontSize: '12px' }}>
                                <span style={{ color: '#2B2931' }}>{p.position}. {p.display_name} <span style={{ color: '#9B8579', fontSize: '11px' }}>({p.elo_before})</span></span>
                                <span style={{ fontWeight: '600', color: p.elo_change >= 0 ? '#28a745' : '#c0392b' }}>{p.elo_change >= 0 ? '+' : ''}{p.elo_change}</span>
                            </div>
                        ))}
                    </div>
                )}
            </div>
        </div>
    );

    return (
        <div>
            <h2 style={{ ...s.title, fontSize: '22px', marginTop: '8px' }}>Rekorde & Statistiken</h2>

            <div style={s.card}>
                <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(260px, 1fr))', gap: '12px' }}>
                    {records.longest_win_streak && records.longest_win_streak.streak > 0 && (
                        <RecordCard icon="🔥" title="Längste Siegesserie" value={records.longest_win_streak.player} sub={records.longest_win_streak.streak + ' Siege in Folge'} date={formatDateRange(records.longest_win_streak.date_from, records.longest_win_streak.date_to)} />
                    )}
                    {records.longest_last_streak && records.longest_last_streak.streak > 0 && (
                        <RecordCard icon="💩" title="Längste Verkackerserie" value={records.longest_last_streak.player} sub={records.longest_last_streak.streak + 'x Letzter in Folge'} date={formatDateRange(records.longest_last_streak.date_from, records.longest_last_streak.date_to)} />
                    )}
                    {records.most_matches && (
                        <RecordCard icon="🎮" title="Meiste Matches" value={records.most_matches.display_name} sub={records.most_matches.count + ' Matches'} />
                    )}
                    {records.most_wins && (
                        <RecordCard icon="🏆" title="Meiste Siege" value={records.most_wins.display_name} sub={records.most_wins.count + ' Siege'} />
                    )}
                    {records.most_last_places && (
                        <RecordCard icon="🚨" title="Meiste letzte Plätze" value={records.most_last_places.display_name} sub={records.most_last_places.count + 'x Letzter'} />
                    )}
                    {records.most_frequent_duel && (
                        <RecordCard icon="⚔️" title="Häufigste Duelle" value={records.most_frequent_duel.player1 + ' vs ' + records.most_frequent_duel.player2} sub={records.most_frequent_duel.count + ' gemeinsame Matches'} />
                    )}
                    {records.biggest_elo_gain && (
                        <RecordCard icon="📈" title="Stärkster Sieg" value={records.biggest_elo_gain.display_name} sub={'+' + records.biggest_elo_gain.count + ' ELO in einem Match'} date={formatDate(records.biggest_elo_gain.match_date)} expandKey="gain" participants={records.biggest_elo_gain.participants} />
                    )}
                    {records.biggest_elo_loss && (
                        <RecordCard icon="📉" title="Überraschendste Niederlage" value={records.biggest_elo_loss.display_name} sub={records.biggest_elo_loss.count + ' ELO in einem Match'} date={formatDate(records.biggest_elo_loss.match_date)} expandKey="loss" participants={records.biggest_elo_loss.participants} />
                    )}
                    {records.highest_elo_ever && (
                        <RecordCard icon="⭐" title="Höchster ELO jemals" value={records.highest_elo_ever.display_name} sub={records.highest_elo_ever.count + ' ELO'} date={formatDate(records.highest_elo_ever.match_date)} />
                    )}
                    {records.lowest_elo_ever && (
                        <RecordCard icon="🕳️" title="Niedrigster ELO jemals" value={records.lowest_elo_ever.display_name} sub={records.lowest_elo_ever.count + ' ELO'} date={formatDate(records.lowest_elo_ever.match_date)} />
                    )}
                    {records.highest_win_rate && (
                        <RecordCard icon="🎯" title="Beste Siegrate" value={records.highest_win_rate.display_name} sub={records.highest_win_rate.count + '% (min. 5 Matches)'} />
                    )}
                    {records.highest_last_rate && (
                        <RecordCard icon="💀" title="Höchste Verkackerrate" value={records.highest_last_rate.display_name} sub={records.highest_last_rate.count + '% (nur 4er-Matches, min. 5)'} />
                    )}
                    {records.best_avg_position && (
                        <RecordCard icon="📊" title="Bester Durchschnittsplatz" value={records.best_avg_position.display_name} sub={'Ø ' + records.best_avg_position.count + ' (min. 5 Matches)'} />
                    )}
                </div>

                {records.match_stats && records.match_stats.total > 0 && (
                    <div style={{ marginTop: '20px' }}>
                        <div style={{ fontSize: '14px', fontWeight: '700', color: '#2B2931', marginBottom: '12px', fontFamily: 'Montserrat,sans-serif' }}>Gespielte Matches</div>
                        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(200px, 1fr))', gap: '8px' }}>
                            <div style={{ background: '#F5F0EB', borderRadius: '12px', padding: '16px', display: 'flex', alignItems: 'center', gap: '12px' }}>
                                <div style={{ fontSize: '28px', flexShrink: 0 }}>🎮</div>
                                <div>
                                    <div style={{ fontSize: '12px', color: '#9B8579', fontWeight: '600', textTransform: 'uppercase', letterSpacing: '0.5px' }}>Gesamt</div>
                                    <div style={{ fontSize: '24px', fontWeight: '700', color: '#2B2931' }}>{records.match_stats.total}</div>
                                    <div style={{ fontSize: '12px', color: '#58595B', marginTop: '2px' }}>Matches gespielt</div>
                                </div>
                            </div>
                            {records.match_stats.matches_2p > 0 && (
                                <div style={{ background: '#F5F0EB', borderRadius: '12px', padding: '16px', display: 'flex', alignItems: 'center', gap: '12px' }}>
                                    <div style={{ fontSize: '20px', flexShrink: 0, lineHeight: '1.1' }}>🎮<br/>🎮</div>
                                    <div>
                                        <div style={{ fontSize: '12px', color: '#9B8579', fontWeight: '600', textTransform: 'uppercase', letterSpacing: '0.5px' }}>2er Matches</div>
                                        <div style={{ fontSize: '24px', fontWeight: '700', color: '#2B2931' }}>{records.match_stats.matches_2p}</div>
                                        <div style={{ fontSize: '12px', color: '#58595B', marginTop: '2px' }}>{Math.round(records.match_stats.matches_2p / records.match_stats.total * 100)}% aller Matches</div>
                                    </div>
                                </div>
                            )}
                            {records.match_stats.matches_3p > 0 && (
                                <div style={{ background: '#F5F0EB', borderRadius: '12px', padding: '16px', display: 'flex', alignItems: 'center', gap: '12px' }}>
                                    <div style={{ fontSize: '14px', flexShrink: 0, lineHeight: '1.2' }}>🎮<br/>🎮<br/>🎮</div>
                                    <div>
                                        <div style={{ fontSize: '12px', color: '#9B8579', fontWeight: '600', textTransform: 'uppercase', letterSpacing: '0.5px' }}>3er Matches</div>
                                        <div style={{ fontSize: '24px', fontWeight: '700', color: '#2B2931' }}>{records.match_stats.matches_3p}</div>
                                        <div style={{ fontSize: '12px', color: '#58595B', marginTop: '2px' }}>{Math.round(records.match_stats.matches_3p / records.match_stats.total * 100)}% aller Matches</div>
                                    </div>
                                </div>
                            )}
                            {records.match_stats.matches_4p > 0 && (
                                <div style={{ background: '#F5F0EB', borderRadius: '12px', padding: '16px', display: 'flex', alignItems: 'center', gap: '12px' }}>
                                    <div style={{ fontSize: '11px', flexShrink: 0, lineHeight: '1.2' }}>🎮<br/>🎮<br/>🎮<br/>🎮</div>
                                    <div>
                                        <div style={{ fontSize: '12px', color: '#9B8579', fontWeight: '600', textTransform: 'uppercase', letterSpacing: '0.5px' }}>4er Matches</div>
                                        <div style={{ fontSize: '24px', fontWeight: '700', color: '#2B2931' }}>{records.match_stats.matches_4p}</div>
                                        <div style={{ fontSize: '12px', color: '#58595B', marginTop: '2px' }}>{Math.round(records.match_stats.matches_4p / records.match_stats.total * 100)}% aller Matches</div>
                                    </div>
                                </div>
                            )}
                        </div>
                    </div>
                )}

                {records.most_active && Object.keys(records.most_active).length > 0 && (
                    <div style={{ marginTop: '20px' }}>
                        <div style={{ fontSize: '14px', fontWeight: '700', color: '#2B2931', marginBottom: '12px', fontFamily: 'Montserrat,sans-serif' }}>Aktivste Spieler</div>
                        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(200px, 1fr))', gap: '8px' }}>
                            {Object.entries(records.most_active).map(([key, data]) => (
                                <div key={key} style={{ background: '#F5F0EB', borderRadius: '8px', padding: '12px', fontSize: '13px' }}>
                                    <div style={{ color: '#9B8579', fontWeight: '600' }}>{data.label}</div>
                                    <div style={{ fontWeight: '700', color: '#2B2931' }}>{data.player} ({data.count} Matches)</div>
                                </div>
                            ))}
                        </div>
                    </div>
                )}

                {records.current_streaks && records.current_streaks.length > 0 && (
                    <div style={{ marginTop: '20px' }}>
                        <div style={{ fontSize: '14px', fontWeight: '700', color: '#2B2931', marginBottom: '12px', fontFamily: 'Montserrat,sans-serif' }}>Aktuelle Serien</div>
                        <div style={{ display: 'flex', flexWrap: 'wrap', gap: '8px' }}>
                            {records.current_streaks.map((streak, i) => (
                                <div key={i} style={{ background: streak.type === 'win' ? '#d4edda' : '#f8d7da', borderRadius: '8px', padding: '8px 14px', fontSize: '13px', fontWeight: '600' }}>
                                    {streak.type === 'win' ? '🔥' : '💩'} {streak.player}: {streak.streak}x {streak.type === 'win' ? 'Sieg' : 'Letzter'} in Folge
                                    {streak.date_from && <span style={{ fontWeight: '400', fontSize: '11px', color: '#6c757d', marginLeft: '6px' }}>({formatDateRange(streak.date_from, streak.date_to)})</span>}
                                </div>
                            ))}
                        </div>
                    </div>
                )}
            </div>
        </div>
    );
}

function AddMatch({ onMatchAdded }) {
    const [players, setPlayers] = useState([]);
    const [matchDate, setMatchDate] = useState(() => {
        const now = new Date();
        now.setMinutes(now.getMinutes() - now.getTimezoneOffset());
        return now.toISOString().slice(0, 16);
    });
    const [selectedPlayers, setSelectedPlayers] = useState([null, null, null, null]);
    const [playerPoints, setPlayerPoints] = useState(['', '', '', '']);
    const [notes, setNotes] = useState('');
    const [loading, setLoading] = useState(false);
    const [error, setError] = useState('');

    useEffect(() => {
        (async () => {
            try {
                const data = await api.getPlayers();
                setPlayers(data.players);
            } catch (err) {
                console.error(err);
            }
        })();
    }, []);

    const handleSubmit = async (e) => {
        e.preventDefault();
        setError('');
        setLoading(true);

        const results = selectedPlayers.map((playerId, index) => {
            if (!playerId) return null;
            const r = { player_id: playerId, position: index + 1 };
            if (playerPoints[index] !== '') {
                r.points = parseInt(playerPoints[index]);
            }
            return r;
        }).filter(Boolean);

        if (results.length === 0) {
            setError('Bitte wähle mindestens einen Spieler aus');
            setLoading(false);
            return;
        }

        // Plausibilitätsprüfung: bessere Platzierung muss >= Punkte haben
        const resultsWithPoints = results.filter(r => r.points !== undefined);
        if (resultsWithPoints.length >= 2) {
            for (let i = 0; i < resultsWithPoints.length; i++) {
                for (let j = i + 1; j < resultsWithPoints.length; j++) {
                    const a = resultsWithPoints[i];
                    const b = resultsWithPoints[j];
                    if (a.position < b.position && a.points < b.points) {
                        setError(`Platz ${a.position} darf nicht weniger Punkte haben als Platz ${b.position}`);
                        setLoading(false);
                        return;
                    }
                    if (b.position < a.position && b.points < a.points) {
                        setError(`Platz ${b.position} darf nicht weniger Punkte haben als Platz ${a.position}`);
                        setLoading(false);
                        return;
                    }
                }
            }
        }

        try {
            await api.createMatch({ match_date: matchDate, results, notes: notes || null });
            setSelectedPlayers([null, null, null, null]);
            setPlayerPoints(['', '', '', '']);
            setNotes('');
            onMatchAdded();
        } catch (err) {
            setError(err.message);
        } finally {
            setLoading(false);
        }
    };

    return (
        <div>
            <h2 style={s.title}>Match eintragen</h2>
            <div style={s.card}>
                <form onSubmit={handleSubmit}>
                    <label style={{ display: 'block', marginBottom: '8px', fontWeight: '600' }}>Datum & Uhrzeit</label>
                    <input type="datetime-local" value={matchDate} onChange={(e) => setMatchDate(e.target.value)} style={{ ...s.input, maxWidth: '100%', width: '100%', boxSizing: 'border-box' }} />

                    <label style={{ display: 'block', marginBottom: '16px', marginTop: '20px', fontWeight: '600' }}>Platzierungen</label>
                    {[0, 1, 2, 3].map((index) => (
                        <div key={index} style={{ display: 'flex', gap: '8px', marginBottom: '12px', alignItems: 'center', flexWrap: 'nowrap' }}>
                            <div style={{ width: '28px', flexShrink: 0, fontWeight: '700', fontSize: '18px' }}>{index + 1}.</div>
                            <select value={selectedPlayers[index] || ''} onChange={(e) => {
                                const newPlayers = [...selectedPlayers];
                                newPlayers[index] = e.target.value ? parseInt(e.target.value) : null;
                                setSelectedPlayers(newPlayers);
                            }} style={{ ...s.input, marginBottom: 0, flex: 1, minWidth: 0 }}>
                                <option value="">— Spieler —</option>
                                {players.map((player) => (
                                    <option key={player.id} value={player.id} disabled={selectedPlayers.includes(player.id) && selectedPlayers[index] !== player.id}>
                                        {player.username} ({player.elo_rating})
                                    </option>
                                ))}
                            </select>
                            <input type="number" placeholder="Pkt" value={playerPoints[index]} onChange={(e) => {
                                const newPoints = [...playerPoints];
                                newPoints[index] = e.target.value;
                                setPlayerPoints(newPoints);
                            }} style={{ ...s.input, marginBottom: 0, width: '64px', flexShrink: 0, textAlign: 'center' }} min="0" />
                        </div>
                    ))}

                    <label style={{ display: 'block', marginBottom: '8px', marginTop: '20px', fontWeight: '600' }}>Notizen (optional)</label>
                    <textarea value={notes} onChange={(e) => setNotes(e.target.value)} style={{ ...s.input, minHeight: '80px', resize: 'vertical' }} placeholder="z.B. Besondere Ereignisse..." />

                    {error && <div style={{ color: '#c0392b', marginBottom: '12px', fontSize: '14px' }}>{error}</div>}
                    <button type="submit" style={{ ...s.btn, ...s.btnPrimary, width: '100%' }} disabled={loading}>
                        {loading ? 'Speichere...' : 'Match speichern'}
                    </button>
                </form>
            </div>
        </div>
    );
}

function MatchHistory({ user }) {
    const [matches, setMatches] = useState([]);
    const [loading, setLoading] = useState(true);
    const [page, setPage] = useState(0);
    const [total, setTotal] = useState(0);
    const [expandedNews, setExpandedNews] = useState({});
    const perPage = 10;

    useEffect(() => { loadMatches(); }, [page]);

    const loadMatches = async () => {
        setLoading(true);
        try {
            const data = await api.getMatches(perPage, page * perPage);
            setMatches(data.matches);
            setTotal(data.total);
        } finally {
            setLoading(false);
        }
    };

    const totalPages = Math.ceil(total / perPage);

    const handleDelete = async (matchId) => {
        if (!confirm('Match wirklich löschen?')) return;
        try {
            await api.deleteMatch(matchId);
            loadMatches();
        } catch (err) {
            alert('Fehler: ' + err.message);
        }
    };

    if (loading && matches.length === 0) return <div style={s.card}>Lade Matches...</div>;

    return (
        <div>
            <h2 style={s.title}>Match-Historie</h2>
            {matches.length === 0 ? (
                <div style={s.card}><div style={{ textAlign: 'center', color: '#9B8579', padding: '40px' }}>Noch keine Matches eingetragen</div></div>
            ) : (
                matches.map((match) => (
                    <div key={match.id} style={s.card}>
                        <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: '16px' }}>
                            <div>
                                <div style={{ fontSize: '14px', color: '#9B8579' }}>{new Date(match.match_date).toLocaleString('de-DE', { day: '2-digit', month: '2-digit', year: 'numeric', hour: '2-digit', minute: '2-digit' })}</div>
                                <div style={{ fontSize: '12px', color: '#adb5bd' }}>von {match.created_by_name}</div>
                            </div>
                            {user && (
                                <button onClick={() => handleDelete(match.id)} style={{ ...s.btn, ...s.btnDanger, padding: '8px 16px', fontSize: '14px' }}>
                                    Löschen
                                </button>
                            )}
                        </div>
                        <div style={{ display: 'grid', gap: '12px' }}>
                            {match.results.map((r, idx) => {
                                const clickable = r.player_id && r.player_name !== '[Gelöscht]';
                                return (
                                <div key={r.id}
                                    onClick={clickable ? () => navigate('player-stats/' + r.player_id) : undefined}
                                    style={{ display: 'flex', alignItems: 'center', gap: '10px', padding: '12px', background: idx === 0 ? '#fff3cd' : '#F5F0EB', borderRadius: '8px', cursor: clickable ? 'pointer' : 'default' }}>
                                    <div style={{ width: '28px', flexShrink: 0, fontWeight: '700', fontSize: '18px' }}>{r.position}.</div>
                                    {r.player_picture ? (
                                        <img src={`${API_BASE}/../${r.player_picture}`} alt="" style={{ width: '36px', height: '36px', borderRadius: '50%', objectFit: 'cover', flexShrink: 0 }} />
                                    ) : (
                                        <div style={{ width: '36px', height: '36px', borderRadius: '50%', background: '#58595B', color: 'white', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: '12px', fontWeight: '700', flexShrink: 0 }}>{r.player_initials || r.player_name.substring(0, 2).toUpperCase()}</div>
                                    )}
                                    <div style={{ flex: 1, minWidth: 0 }}>
                                        <div style={{ fontWeight: '600' }}>{r.player_username || r.player_name}</div>
                                        <div style={{ fontSize: '11px', color: '#9B8579' }}>{r.player_name}</div>
                                        <div style={{ fontSize: '12px', color: '#9B8579', marginTop: '2px' }}>
                                            {r.elo_before} → {r.elo_after}
                                            {r.points != null && <span style={{ marginLeft: '8px' }}>• {r.points} Pkt</span>}
                                        </div>
                                    </div>
                                    <div style={{ fontWeight: '700', fontSize: '16px', color: r.elo_change >= 0 ? '#28a745' : '#dc3545', flexShrink: 0 }}>
                                        {r.elo_change >= 0 ? '+' : ''}{r.elo_change}
                                    </div>
                                </div>
                                );
                            })}
                        </div>
                        {match.notes && <div style={{ marginTop: '12px', padding: '12px', background: '#F5F0EB', borderRadius: '8px', fontSize: '14px' }}>📝 {match.notes}</div>}
                        {match.news && match.news.length > 0 && (() => {
                            const topNews = match.news.slice(0, 5);
                            const extraNews = match.news.slice(5);
                            const isExpanded = expandedNews[match.id];
                            const renderItem = (item, i) => (
                                <div key={i} style={{ padding: '3px 0', fontSize: '12px', lineHeight: '1.5', color: '#58595B' }}
                                    dangerouslySetInnerHTML={{ __html: item.replace(/\*(.*?)\*/g, '<strong style="color:#2B2931">$1</strong>') }} />
                            );
                            return (
                                <div style={{ marginTop: '12px', paddingTop: '10px', borderTop: '1px solid #EDE8E3' }}>
                                    <div style={{ fontSize: '11px', fontWeight: '600', color: '#9B8579', marginBottom: '4px', textTransform: 'uppercase', letterSpacing: '0.5px' }}>📰 News</div>
                                    {topNews.map(renderItem)}
                                    {extraNews.length > 0 && !isExpanded && (
                                        <div onClick={() => setExpandedNews(prev => ({ ...prev, [match.id]: true }))}
                                            style={{ marginTop: '4px', fontSize: '11px', color: '#9B8579', cursor: 'pointer', userSelect: 'none' }}>
                                            ▸ {extraNews.length} weitere News anzeigen
                                        </div>
                                    )}
                                    {isExpanded && extraNews.map((item, i) => renderItem(item, i + 5))}
                                    {isExpanded && (
                                        <div onClick={() => setExpandedNews(prev => ({ ...prev, [match.id]: false }))}
                                            style={{ marginTop: '4px', fontSize: '11px', color: '#9B8579', cursor: 'pointer', userSelect: 'none' }}>
                                            ▾ Weniger anzeigen
                                        </div>
                                    )}
                                </div>
                            );
                        })()}
                    </div>
                ))
            )}
            {totalPages > 1 && (
                <div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', gap: '8px', marginTop: '20px', flexWrap: 'wrap' }}>
                    <button onClick={() => setPage(0)} disabled={page === 0} style={{ ...s.btn, ...s.btnSecondary, padding: '8px 12px', fontSize: '14px', opacity: page === 0 ? 0.4 : 1 }}>«</button>
                    <button onClick={() => setPage(p => p - 1)} disabled={page === 0} style={{ ...s.btn, ...s.btnSecondary, padding: '8px 14px', fontSize: '14px', opacity: page === 0 ? 0.4 : 1 }}>‹</button>
                    {Array.from({ length: totalPages }, (_, i) => i)
                        .filter(i => i === 0 || i === totalPages - 1 || Math.abs(i - page) <= 1)
                        .reduce((acc, i, idx, arr) => {
                            if (idx > 0 && i - arr[idx - 1] > 1) acc.push('...');
                            acc.push(i);
                            return acc;
                        }, [])
                        .map((item, idx) =>
                            item === '...' ? (
                                <span key={'dots-' + idx} style={{ color: '#9B8579', padding: '0 4px' }}>...</span>
                            ) : (
                                <button key={item} onClick={() => setPage(item)} style={{ ...s.btn, padding: '8px 14px', fontSize: '14px', fontWeight: item === page ? '700' : '500', background: item === page ? '#2B2931' : '#F5F0EB', color: item === page ? 'white' : '#58595B' }}>{item + 1}</button>
                            )
                        )
                    }
                    <button onClick={() => setPage(p => p + 1)} disabled={page >= totalPages - 1} style={{ ...s.btn, ...s.btnSecondary, padding: '8px 14px', fontSize: '14px', opacity: page >= totalPages - 1 ? 0.4 : 1 }}>›</button>
                    <button onClick={() => setPage(totalPages - 1)} disabled={page >= totalPages - 1} style={{ ...s.btn, ...s.btnSecondary, padding: '8px 12px', fontSize: '14px', opacity: page >= totalPages - 1 ? 0.4 : 1 }}>»</button>
                </div>
            )}
        </div>
    );
}

function PlayersManagement() {
    const [players, setPlayers] = useState([]);
    const [loading, setLoading] = useState(true);
    const [showAddForm, setShowAddForm] = useState(false);
    const [showInactive, setShowInactive] = useState(false);
    const [newPlayer, setNewPlayer] = useState({ username: '', password: '', display_name: '', initials: '', email: '' });
    const [error, setError] = useState('');
    const [deleteConfirm, setDeleteConfirm] = useState(null);
    const [permDeleteConfirm, setPermDeleteConfirm] = useState(null);

    useEffect(() => { loadPlayers(); }, []);

    const loadPlayers = async () => {
        try {
            const data = await api.getPlayers(true);
            setPlayers(data.players);
        } finally {
            setLoading(false);
        }
    };

    const handleAddPlayer = async (e) => {
        e.preventDefault();
        setError('');
        try {
            await api.register(newPlayer.username, newPlayer.password, newPlayer.display_name, newPlayer.initials, newPlayer.email);
            setNewPlayer({ username: '', password: '', display_name: '', initials: '', email: '' });
            setShowAddForm(false);
            loadPlayers();
        } catch (err) {
            setError(err.message);
        }
    };

    const handleToggleActive = async (player) => {
        try {
            await api.updatePlayer(player.id, { is_active: !player.is_active });
            loadPlayers();
        } catch (err) {
            alert('Fehler: ' + err.message);
        }
    };

    const handleDeleteClick = (player) => {
        setDeleteConfirm({ step: 1, player });
    };

    const handleDeleteConfirmStep = async () => {
        if (deleteConfirm.step === 1) {
            setDeleteConfirm({ step: 2, player: deleteConfirm.player });
        } else {
            try {
                await api.deactivatePlayer(deleteConfirm.player.id);
                setDeleteConfirm(null);
                loadPlayers();
            } catch (err) {
                alert('Fehler: ' + err.message);
                setDeleteConfirm(null);
            }
        }
    };

    const handlePermDeleteClick = (player) => {
        setPermDeleteConfirm({ step: 1, player });
    };

    const handlePermDeleteConfirmStep = async () => {
        if (permDeleteConfirm.step === 1) {
            setPermDeleteConfirm({ step: 2, player: permDeleteConfirm.player });
        } else {
            try {
                await api.permanentDeletePlayer(permDeleteConfirm.player.id);
                setPermDeleteConfirm(null);
                loadPlayers();
            } catch (err) {
                alert('Fehler: ' + err.message);
                setPermDeleteConfirm(null);
            }
        }
    };

    if (loading) return <div style={s.card}>Lade Spieler...</div>;

    const activePlayers = players.filter(p => p.is_active);
    const inactivePlayers = players.filter(p => !p.is_active);

    const renderPlayerRow = (p) => (
        <div key={p.id} className="pm-row" style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '16px', background: p.is_active ? '#F5F0EB' : '#fff3cd', borderRadius: '8px', marginBottom: '12px', flexWrap: 'wrap', gap: '12px' }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: '12px', minWidth: 0 }}>
                {p.profile_picture ? (
                    <img src={`${API_BASE}/../${p.profile_picture}`} alt="" style={{ width: '40px', height: '40px', borderRadius: '50%', objectFit: 'cover', flexShrink: 0 }} />
                ) : (
                    <div style={{ width: '40px', height: '40px', borderRadius: '50%', background: '#58595B', display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'white', fontSize: '14px', fontWeight: '700', flexShrink: 0 }}>
                        {p.initials || p.display_name.substring(0, 2).toUpperCase()}
                    </div>
                )}
                <div style={{ minWidth: 0 }}>
                    <div style={{ fontWeight: '600', marginBottom: '2px' }}>
                        {p.username}
                        {p.role === 'admin' && <span style={{ marginLeft: '8px', padding: '2px 8px', borderRadius: '12px', fontSize: '11px', fontWeight: '600', background: '#d4edda', color: '#155724' }}>Admin</span>}
                    </div>
                    <div style={{ fontSize: '13px', color: '#9B8579' }}>{p.display_name} • ELO: {p.elo_rating}</div>
                </div>
            </div>
            <div style={{ display: 'flex', gap: '8px', flexWrap: 'wrap' }}>
                <button onClick={() => navigate('player-edit/' + p.id)} style={{ ...s.btn, ...s.btnSecondary, padding: '8px 12px', fontSize: '13px' }}>
                    Bearbeiten
                </button>
                {p.is_active ? (
                    <button onClick={() => handleDeleteClick(p)} style={{ ...s.btn, ...s.btnDanger, padding: '8px 12px', fontSize: '13px' }}>
                        Deaktivieren
                    </button>
                ) : (
                    <>
                        <button onClick={() => handleToggleActive(p)} style={{ ...s.btn, ...s.btnPrimary, padding: '8px 12px', fontSize: '13px' }}>
                            Aktivieren
                        </button>
                        <button onClick={() => handlePermDeleteClick(p)} style={{ ...s.btn, padding: '8px 12px', fontSize: '13px', background: '#c0392b', color: 'white' }}>
                            Löschen
                        </button>
                    </>
                )}
            </div>
        </div>
    );

    return (
        <div>
            {deleteConfirm && deleteConfirm.step === 1 && (
                <ConfirmDialog
                    title="Spieler deaktivieren"
                    message={`Spieler "${deleteConfirm.player.display_name}" wirklich deaktivieren?`}
                    confirmLabel="Deaktivieren"
                    onConfirm={handleDeleteConfirmStep}
                    onCancel={() => setDeleteConfirm(null)}
                />
            )}
            {deleteConfirm && deleteConfirm.step === 2 && (
                <ConfirmDialog
                    title="Bist du sicher?"
                    message={`${deleteConfirm.player.display_name} kann sich danach nicht mehr einloggen. Diese Aktion kann nur von einem Admin rückgängig gemacht werden.`}
                    confirmLabel="Endgültig deaktivieren"
                    onConfirm={handleDeleteConfirmStep}
                    onCancel={() => setDeleteConfirm(null)}
                />
            )}
            {permDeleteConfirm && permDeleteConfirm.step === 1 && (
                <ConfirmDialog
                    title="Spieler endgültig löschen?"
                    message={`"${permDeleteConfirm.player.display_name}" wird unwiderruflich gelöscht. Gespielte Matches bleiben erhalten, ELO-Werte ändern sich nicht.`}
                    confirmLabel="Endgültig löschen"
                    confirmStyle={{ background: '#c0392b', color: 'white' }}
                    onConfirm={handlePermDeleteConfirmStep}
                    onCancel={() => setPermDeleteConfirm(null)}
                />
            )}
            {permDeleteConfirm && permDeleteConfirm.step === 2 && (
                <ConfirmDialog
                    title="Letzte Warnung"
                    message={`Diese Aktion kann NICHT rückgängig gemacht werden. "${permDeleteConfirm.player.display_name}" wird dauerhaft aus dem System entfernt.`}
                    confirmLabel="Unwiderruflich löschen"
                    confirmStyle={{ background: '#c0392b', color: 'white' }}
                    onConfirm={handlePermDeleteConfirmStep}
                    onCancel={() => setPermDeleteConfirm(null)}
                />
            )}

            <div style={{ ...s.card, display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '20px', flexWrap: 'wrap', gap: '12px' }}>
                <h2 style={{ fontSize: '28px', fontWeight: '700', margin: 0, color: '#2B2931' }}>Spielerverwaltung</h2>
                <button onClick={() => setShowAddForm(!showAddForm)} style={{ ...s.btn, ...s.btnPrimary, fontSize: '14px', padding: '10px 18px' }}>
                    {showAddForm ? 'Abbrechen' : '+ Spieler hinzufügen'}
                </button>
            </div>

            {showAddForm && (
                <div style={s.card}>
                    <h3 style={{ marginBottom: '16px', color: '#2B2931' }}>Neuer Spieler</h3>
                    <form onSubmit={handleAddPlayer}>
                        <input type="text" placeholder="Alias" value={newPlayer.username} onChange={(e) => setNewPlayer({ ...newPlayer, username: e.target.value })} style={s.input} required />
                        <input type="email" placeholder="E-Mail (optional)" value={newPlayer.email} onChange={(e) => setNewPlayer({ ...newPlayer, email: e.target.value })} style={s.input} />
                        <input type="text" placeholder="Vollständiger Name" value={newPlayer.display_name} onChange={(e) => setNewPlayer({ ...newPlayer, display_name: e.target.value })} style={s.input} required />
                        <input type="text" placeholder="Initialen (z.B. MS)" value={newPlayer.initials} onChange={(e) => setNewPlayer({ ...newPlayer, initials: e.target.value.toUpperCase() })} style={s.input} maxLength="3" />
                        <input type="password" placeholder="Passwort (min. 6 Zeichen)" value={newPlayer.password} onChange={(e) => setNewPlayer({ ...newPlayer, password: e.target.value })} style={s.input} required />
                        {error && <div style={{ color: '#c0392b', marginBottom: '12px', fontSize: '14px' }}>{error}</div>}
                        <button type="submit" style={{ ...s.btn, ...s.btnPrimary, width: '100%' }}>Spieler erstellen</button>
                    </form>
                </div>
            )}

            {/* Tabs */}
            <style>{`
                .tab-btn { transition: background 0.15s, color 0.15s; }
                .tab-btn:hover { opacity: 0.85; }
            `}</style>
            <div style={{ display: 'inline-flex', borderRadius: '10px', border: '2px solid white', overflow: 'hidden', marginBottom: '20px' }}>
                <button className="tab-btn" onClick={() => setShowInactive(false)} style={{ ...s.btn, padding: '10px 24px', fontSize: '14px', borderRadius: 0, background: !showInactive ? 'white' : 'transparent', color: !showInactive ? '#2B2931' : 'rgba(255,255,255,0.6)', border: 'none' }}>
                    Aktiv ({activePlayers.length})
                </button>
                <button className="tab-btn" onClick={() => setShowInactive(true)} style={{ ...s.btn, padding: '10px 24px', fontSize: '14px', borderRadius: 0, background: showInactive ? 'white' : 'transparent', color: showInactive ? '#2B2931' : 'rgba(255,255,255,0.6)', border: 'none' }}>
                    Inaktiv ({inactivePlayers.length})
                </button>
            </div>

            <div style={s.card}>
                {!showInactive ? (
                    activePlayers.length === 0
                        ? <div style={{ textAlign: 'center', color: '#9B8579', padding: '24px' }}>Keine aktiven Spieler</div>
                        : activePlayers.map(renderPlayerRow)
                ) : (
                    inactivePlayers.length === 0
                        ? <div style={{ textAlign: 'center', color: '#9B8579', padding: '24px' }}>Keine inaktiven Spieler</div>
                        : inactivePlayers.map(renderPlayerRow)
                )}
            </div>
        </div>
    );
}

function PlayerEdit({ playerId }) {
    const [player, setPlayer] = useState(null);
    const [loading, setLoading] = useState(true);
    const [form, setForm] = useState({});
    const [password, setPassword] = useState('');
    const [saving, setSaving] = useState(false);
    const [error, setError] = useState('');
    const [success, setSuccess] = useState('');
    const [avatarLoading, setAvatarLoading] = useState(false);
    const fileInputRef = React.useRef(null);

    const loadPlayer = async () => {
        try {
            const data = await api.getPlayers(true);
            const p = data.players.find(pl => pl.id === playerId);
            if (!p) { setError('Spieler nicht gefunden'); return; }
            setPlayer(p);
            setForm({ username: p.username, email: p.email || '', display_name: p.display_name, initials: p.initials || '', role: p.role });
        } finally {
            setLoading(false);
        }
    };

    useEffect(() => { loadPlayer(); }, [playerId]);

    const handleSave = async (e) => {
        e.preventDefault();
        setError('');
        setSuccess('');
        setSaving(true);

        const updates = {};
        if (form.username !== player.username) updates.username = form.username;
        if (form.email !== (player.email || '')) updates.email = form.email || null;
        if (form.display_name !== player.display_name) updates.display_name = form.display_name;
        if (form.initials !== (player.initials || '')) updates.initials = form.initials;
        if (form.role !== player.role) updates.role = form.role;
        if (password.length > 0) {
            if (password.length < 6) {
                setError('Passwort muss mindestens 6 Zeichen lang sein');
                setSaving(false);
                return;
            }
            updates.password = password;
        }

        if (Object.keys(updates).length === 0) {
            setError('Keine Änderungen');
            setSaving(false);
            return;
        }

        try {
            await api.updatePlayer(playerId, updates);
            setPassword('');
            setSuccess('Gespeichert');
            await loadPlayer();
            setTimeout(() => setSuccess(''), 3000);
        } catch (err) {
            setError(err.message);
        } finally {
            setSaving(false);
        }
    };

    const handleAvatarChange = async (e) => {
        const file = e.target.files[0];
        if (!file) return;
        setAvatarLoading(true);
        setError('');
        try {
            await api.uploadAvatar(file, playerId);
            await loadPlayer();
        } catch (err) {
            setError(err.message);
        } finally {
            setAvatarLoading(false);
            if (fileInputRef.current) fileInputRef.current.value = '';
        }
    };

    if (loading) return <div style={s.card}>Lade Spieler...</div>;
    if (!player) return <div style={s.card}>{error || 'Spieler nicht gefunden'}</div>;

    const avatarUrl = player.profile_picture ? `${API_BASE}/../${player.profile_picture}` : null;

    return (
        <div>
            <div style={{ marginBottom: '20px' }}>
                <button onClick={() => navigate('players')} style={{ ...s.btn, ...s.btnSecondary, padding: '8px 16px', fontSize: '14px' }}>
                    ← Zurück zur Übersicht
                </button>
            </div>

            <div style={s.card}>
                <h2 style={{ ...s.title, marginBottom: '20px', color: '#2B2931' }}>Spieler bearbeiten</h2>

                {/* Avatar */}
                <div style={{ display: 'flex', alignItems: 'center', gap: '16px', marginBottom: '24px' }}>
                    {avatarUrl ? (
                        <img src={avatarUrl} alt="" style={{ width: '80px', height: '80px', borderRadius: '50%', objectFit: 'cover' }} />
                    ) : (
                        <div style={{ width: '80px', height: '80px', borderRadius: '50%', background: '#58595B', display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'white', fontSize: '28px', fontWeight: '700' }}>
                            {player.initials || player.display_name.substring(0, 2).toUpperCase()}
                        </div>
                    )}
                    <div>
                        <input type="file" accept="image/*" ref={fileInputRef} onChange={handleAvatarChange} style={{ display: 'none' }} />
                        <button onClick={() => fileInputRef.current && fileInputRef.current.click()} style={{ ...s.btn, ...s.btnSecondary, fontSize: '14px' }} disabled={avatarLoading}>
                            {avatarLoading ? 'Hochladen...' : 'Bild ändern'}
                        </button>
                    </div>
                </div>

                <form onSubmit={handleSave}>
                    <label style={{ display: 'block', marginBottom: '4px', fontWeight: '600', fontSize: '14px' }}>Alias</label>
                    <input type="text" value={form.username} onChange={(e) => setForm({ ...form, username: e.target.value })} style={s.input} required minLength="3" maxLength="50" />

                    <label style={{ display: 'block', marginBottom: '4px', fontWeight: '600', fontSize: '14px' }}>E-Mail</label>
                    <input type="email" value={form.email} onChange={(e) => setForm({ ...form, email: e.target.value })} style={s.input} placeholder="Optional" />

                    <label style={{ display: 'block', marginBottom: '4px', fontWeight: '600', fontSize: '14px' }}>Vollständiger Name</label>
                    <input type="text" value={form.display_name} onChange={(e) => setForm({ ...form, display_name: e.target.value })} style={s.input} required />

                    <label style={{ display: 'block', marginBottom: '4px', fontWeight: '600', fontSize: '14px' }}>Initialen</label>
                    <input type="text" value={form.initials} onChange={(e) => setForm({ ...form, initials: e.target.value.toUpperCase() })} style={s.input} maxLength="3" />

                    <label style={{ display: 'block', marginBottom: '4px', fontWeight: '600', fontSize: '14px' }}>Rolle</label>
                    <select value={form.role} onChange={(e) => setForm({ ...form, role: e.target.value })} style={s.input}>
                        <option value="player">Spieler</option>
                        <option value="admin">Admin</option>
                    </select>

                    <label style={{ display: 'block', marginBottom: '4px', fontWeight: '600', fontSize: '14px' }}>Neues Passwort (leer lassen = nicht ändern)</label>
                    <input type="password" value={password} onChange={(e) => setPassword(e.target.value)} style={s.input} placeholder="Min. 6 Zeichen" />

                    {error && <div style={{ color: '#c0392b', marginBottom: '12px', fontSize: '14px' }}>{error}</div>}
                    {success && <div style={{ color: '#28a745', marginBottom: '12px', fontSize: '14px' }}>{success}</div>}

                    <button type="submit" style={{ ...s.btn, ...s.btnPrimary, width: '100%' }} disabled={saving}>
                        {saving ? 'Speichere...' : 'Änderungen speichern'}
                    </button>
                </form>
            </div>
        </div>
    );
}

function AccountSettings({ user, onUserUpdate }) {
    const [form, setForm] = useState({ username: user.username, email: user.email || '', display_name: user.display_name, initials: user.initials || '' });
    const [profileSaving, setProfileSaving] = useState(false);
    const [profileError, setProfileError] = useState('');
    const [profileSuccess, setProfileSuccess] = useState('');
    const [currentPassword, setCurrentPassword] = useState('');
    const [newPassword, setNewPassword] = useState('');
    const [confirmPassword, setConfirmPassword] = useState('');
    const [pwLoading, setPwLoading] = useState(false);
    const [pwError, setPwError] = useState('');
    const [pwSuccess, setPwSuccess] = useState('');
    const [avatarLoading, setAvatarLoading] = useState(false);
    const fileInputRef = React.useRef(null);

    // Sync form wenn user-Objekt sich ändert (z.B. nach Avatar-Upload)
    useEffect(() => {
        setForm({ username: user.username, email: user.email || '', display_name: user.display_name, initials: user.initials || '' });
    }, [user.id, user.username, user.email, user.display_name, user.initials]);

    const handleProfileSave = async (e) => {
        e.preventDefault();
        setProfileError('');
        setProfileSuccess('');

        const updates = {};
        if (form.username !== user.username) updates.username = form.username;
        if (form.email !== (user.email || '')) updates.email = form.email || null;
        if (form.display_name !== user.display_name) updates.display_name = form.display_name;
        if (form.initials !== (user.initials || '')) updates.initials = form.initials;

        if (Object.keys(updates).length === 0) {
            setProfileError('Keine Änderungen');
            return;
        }

        setProfileSaving(true);
        try {
            await api.updatePlayer(user.id, updates);
            const refreshed = await api.getCurrentUser();
            onUserUpdate(refreshed.user);
            setProfileSuccess('Profil gespeichert');
            setTimeout(() => setProfileSuccess(''), 3000);
        } catch (err) {
            setProfileError(err.message);
        } finally {
            setProfileSaving(false);
        }
    };

    const handlePasswordChange = async (e) => {
        e.preventDefault();
        setPwError('');
        setPwSuccess('');

        if (newPassword.length < 6) {
            setPwError('Neues Passwort muss mindestens 6 Zeichen lang sein');
            return;
        }
        if (newPassword !== confirmPassword) {
            setPwError('Passwörter stimmen nicht überein');
            return;
        }

        setPwLoading(true);
        try {
            await api.changePassword(currentPassword, newPassword);
            setPwSuccess('Passwort erfolgreich geändert');
            setCurrentPassword('');
            setNewPassword('');
            setConfirmPassword('');
        } catch (err) {
            setPwError(err.message);
        } finally {
            setPwLoading(false);
        }
    };

    const handleAvatarChange = async (e) => {
        const file = e.target.files[0];
        if (!file) return;
        setAvatarLoading(true);
        try {
            const data = await api.uploadAvatar(file);
            onUserUpdate({ ...user, profile_picture: data.profile_picture });
        } catch (err) {
            setProfileError(err.message);
        } finally {
            setAvatarLoading(false);
            if (fileInputRef.current) fileInputRef.current.value = '';
        }
    };

    const avatarUrl = user.profile_picture ? `${API_BASE}/../${user.profile_picture}` : null;

    return (
        <div>
            <h2 style={s.title}>Konto</h2>

            {/* Profil-Card */}
            <div style={s.card}>
                <h3 style={{ marginBottom: '16px', color: '#2B2931' }}>Profil</h3>

                <div style={{ display: 'flex', alignItems: 'center', gap: '16px', marginBottom: '24px' }}>
                    {avatarUrl ? (
                        <img src={avatarUrl} alt="" style={{ width: '80px', height: '80px', borderRadius: '50%', objectFit: 'cover' }} />
                    ) : (
                        <div style={{ width: '80px', height: '80px', borderRadius: '50%', background: '#58595B', display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'white', fontSize: '28px', fontWeight: '700' }}>
                            {user.initials || user.display_name.substring(0, 2).toUpperCase()}
                        </div>
                    )}
                    <div>
                        <input type="file" accept="image/*" ref={fileInputRef} onChange={handleAvatarChange} style={{ display: 'none' }} />
                        <button onClick={() => fileInputRef.current && fileInputRef.current.click()} style={{ ...s.btn, ...s.btnSecondary, fontSize: '14px' }} disabled={avatarLoading}>
                            {avatarLoading ? 'Hochladen...' : 'Bild ändern'}
                        </button>
                    </div>
                </div>

                <form onSubmit={handleProfileSave}>
                    <label style={{ display: 'block', marginBottom: '4px', fontWeight: '600', fontSize: '14px' }}>Alias</label>
                    <input type="text" value={form.username} onChange={(e) => setForm({ ...form, username: e.target.value })} style={s.input} required minLength="3" maxLength="50" />

                    <label style={{ display: 'block', marginBottom: '4px', fontWeight: '600', fontSize: '14px' }}>E-Mail</label>
                    <input type="email" value={form.email} onChange={(e) => setForm({ ...form, email: e.target.value })} style={s.input} placeholder="Optional" />

                    <label style={{ display: 'block', marginBottom: '4px', fontWeight: '600', fontSize: '14px' }}>Vollständiger Name</label>
                    <input type="text" value={form.display_name} onChange={(e) => setForm({ ...form, display_name: e.target.value })} style={s.input} required />

                    <label style={{ display: 'block', marginBottom: '4px', fontWeight: '600', fontSize: '14px' }}>Initialen</label>
                    <input type="text" value={form.initials} onChange={(e) => setForm({ ...form, initials: e.target.value.toUpperCase() })} style={s.input} maxLength="3" />

                    {profileError && <div style={{ color: '#c0392b', marginBottom: '12px', fontSize: '14px' }}>{profileError}</div>}
                    {profileSuccess && <div style={{ color: '#28a745', marginBottom: '12px', fontSize: '14px' }}>{profileSuccess}</div>}
                    <button type="submit" style={{ ...s.btn, ...s.btnPrimary, width: '100%' }} disabled={profileSaving}>
                        {profileSaving ? 'Speichere...' : 'Profil speichern'}
                    </button>
                </form>
            </div>

            {/* Passwort-Card */}
            <div style={s.card}>
                <h3 style={{ marginBottom: '16px', color: '#2B2931' }}>Passwort ändern</h3>
                <form onSubmit={handlePasswordChange}>
                    <input type="password" placeholder="Aktuelles Passwort" value={currentPassword} onChange={(e) => setCurrentPassword(e.target.value)} style={s.input} required />
                    <input type="password" placeholder="Neues Passwort (min. 6 Zeichen)" value={newPassword} onChange={(e) => setNewPassword(e.target.value)} style={s.input} required />
                    <input type="password" placeholder="Neues Passwort bestätigen" value={confirmPassword} onChange={(e) => setConfirmPassword(e.target.value)} style={s.input} required />
                    {pwError && <div style={{ color: '#c0392b', marginBottom: '12px', fontSize: '14px' }}>{pwError}</div>}
                    {pwSuccess && <div style={{ color: '#28a745', marginBottom: '12px', fontSize: '14px' }}>{pwSuccess}</div>}
                    <button type="submit" style={{ ...s.btn, ...s.btnPrimary, width: '100%' }} disabled={pwLoading}>
                        {pwLoading ? 'Speichere...' : 'Passwort ändern'}
                    </button>
                </form>
            </div>
        </div>
    );
}

function PlayerStats({ playerId }) {
    const [data, setData] = useState(null);
    const [loading, setLoading] = useState(true);
    const [expandedGain, setExpandedGain] = useState(false);
    const [expandedLoss, setExpandedLoss] = useState(false);
    const chartScrollRef = React.useRef(null);
    const [tipIdx, setTipIdx] = useState(null);
    const [showElo, setShowElo] = useState(() => {
        const v = (typeof localStorage !== 'undefined') ? localStorage.getItem('playerStats.showElo') : null;
        return v === null ? true : v === '1';
    });
    const [showPoints, setShowPoints] = useState(() => {
        const v = (typeof localStorage !== 'undefined') ? localStorage.getItem('playerStats.showPoints') : null;
        return v === null ? true : v === '1';
    });
    const [showAvg10, setShowAvg10] = useState(() => {
        const v = (typeof localStorage !== 'undefined') ? localStorage.getItem('playerStats.showAvg10') : null;
        return v === null ? true : v === '1';
    });
    const [showAvg20, setShowAvg20] = useState(() => {
        const v = (typeof localStorage !== 'undefined') ? localStorage.getItem('playerStats.showAvg20') : null;
        return v === null ? false : v === '1';
    });
    const [visibleCount, setVisibleCount] = useState(() => {
        const v = (typeof localStorage !== 'undefined') ? localStorage.getItem('playerStats.visibleCount') : null;
        const parsed = v !== null ? parseInt(v, 10) : NaN;
        return isNaN(parsed) ? 50 : Math.max(10, parsed);
    });
    const pendingScrollCenter = React.useRef(null);
    useEffect(() => { try { localStorage.setItem('playerStats.showElo', showElo ? '1' : '0'); } catch (e) {} }, [showElo]);
    useEffect(() => { try { localStorage.setItem('playerStats.showPoints', showPoints ? '1' : '0'); } catch (e) {} }, [showPoints]);
    useEffect(() => { try { localStorage.setItem('playerStats.showAvg10', showAvg10 ? '1' : '0'); } catch (e) {} }, [showAvg10]);
    useEffect(() => { try { localStorage.setItem('playerStats.showAvg20', showAvg20 ? '1' : '0'); } catch (e) {} }, [showAvg20]);
    useEffect(() => { try { localStorage.setItem('playerStats.visibleCount', String(visibleCount)); } catch (e) {} }, [visibleCount]);

    React.useLayoutEffect(() => {
        if (pendingScrollCenter.current !== null && chartScrollRef.current) {
            const el = chartScrollRef.current;
            el.scrollLeft = pendingScrollCenter.current * el.scrollWidth - el.clientWidth / 2;
            pendingScrollCenter.current = null;
        }
    });

    const handleZoomChange = (newVisibleCount) => {
        if (chartScrollRef.current) {
            const el = chartScrollRef.current;
            if (el.scrollWidth > 0) {
                pendingScrollCenter.current = (el.scrollLeft + el.clientWidth / 2) / el.scrollWidth;
            }
        }
        setVisibleCount(newVisibleCount);
    };

    useEffect(() => {
        (async () => {
            try {
                const result = await api.getPlayerStats(playerId);
                setData(result);
            } finally {
                setLoading(false);
            }
        })();
    }, [playerId]);

    useEffect(() => {
        if (chartScrollRef.current) chartScrollRef.current.scrollLeft = chartScrollRef.current.scrollWidth;
    }, [data]);

    if (loading) return <div style={s.card}>Lade Spielerprofil...</div>;
    if (!data) return <div style={s.card}>Spieler nicht gefunden</div>;

    const { player, head_to_head, lieblingsgegner_absolut, lieblingsgegner_relativ, nemesis_absolut, nemesis_relativ, elo_history, recent_matches } = data;

    const positionEmoji = (pos, size) => {
        if (pos === 1) return '🥇';
        if (pos === 2) return '🥈';
        if (pos === 3) return '🥉';
        return pos === size ? '🚨' : pos + '.';
    };

    const statBox = (label, value, icon, accent) => (
        <div style={{ background: accent ? '#FBB040' : '#F5F0EB', borderRadius: '12px', padding: '10px 12px', display: 'flex', alignItems: 'center', gap: '8px', minWidth: 0 }}>
            <div style={{ fontSize: '20px', flexShrink: 0 }}>{icon}</div>
            <div style={{ minWidth: 0 }}>
                <div style={{ fontSize: '18px', fontWeight: '700', color: '#2B2931', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{value}</div>
                <div style={{ fontSize: '11px', color: '#58595B', marginTop: '2px', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{label}</div>
            </div>
        </div>
    );

    const avatarEl = (pic, initials, size = 80) => pic ? (
        <img src={pic.startsWith('http') ? pic : `${API_BASE}/../${pic}`} alt="" style={{ width: size, height: size, borderRadius: '50%', objectFit: 'cover' }} />
    ) : (
        <div style={{ width: size, height: size, borderRadius: '50%', background: '#58595B', display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'white', fontSize: size * 0.35, fontWeight: '700' }}>
            {initials || '??'}
        </div>
    );

    return (
        <div>
            <button onClick={() => navigate('leaderboard')} style={{ ...s.btn, ...s.btnSecondary, marginBottom: '16px', fontSize: '14px' }}>
                ← Zurück zur Rangliste
            </button>

            {/* Header Card */}
            <div style={{ ...s.card, display: 'flex', gap: '20px', alignItems: 'center', flexWrap: 'wrap' }}>
                {avatarEl(player.profile_picture, player.initials, 80)}
                <div style={{ flex: 1, minWidth: '200px' }}>
                    <h2 style={{ margin: 0, color: '#2B2931', fontSize: '24px' }}>{player.display_name}</h2>
                    <div style={{ color: '#9B8579', fontSize: '14px', marginTop: '4px' }}>@{player.username}</div>
                    <div style={{ marginTop: '8px' }}>
                        <span style={{ fontSize: '32px', fontWeight: '700', color: '#2B2931' }}>{player.elo_rating}</span>
                        <span style={{ fontSize: '14px', color: '#9B8579', marginLeft: '8px' }}>ELO</span>
                    </div>
                    {player.current_streak.count >= 2 && (
                        <div style={{ marginTop: '6px', fontSize: '13px', color: player.current_streak.type === 'win' ? '#28a745' : '#c0392b', fontWeight: '600' }}>
                            {player.current_streak.type === 'win' ? '🔥' : '💀'} {player.current_streak.count}er {player.current_streak.type === 'win' ? 'Siegesserie' : 'Verlierer-Serie'}
                        </div>
                    )}
                </div>
            </div>

            {/* ELO-Verlauf (mit Punkte-Linie als Overlay) */}
            {elo_history.length > 0 && (() => {
                const POINTS_COLOR = '#dc3545';   // Punkte-Verlauf – mittleres Rot
                const AVG10_COLOR = '#ff6b6b';    // Ø 10 Spiele – helles Rot
                const AVG20_COLOR = '#8b0000';    // Ø 20 Spiele – dunkles Rot
                const elos = elo_history.map(e => parseInt(e.elo_rating));
                const pointsVals = elo_history.map(e =>
                    e.points !== null && e.points !== undefined ? parseInt(e.points) : null
                );
                const hasPoints = pointsVals.some(p => p !== null);

                const min = Math.min(...elos) - 20;
                const max = Math.max(...elos) + 20;
                const range = max - min || 1;
                const pointsMin = 20;
                const pointsMax = 60;
                const pointsRange = pointsMax - pointsMin;
                const n = elo_history.length;
                const maxVisible = Math.max(n, 10);
                const minVisible = 10;
                const effectiveVisible = Math.min(Math.max(visibleCount, minVisible), maxVisible);
                const widthPct = Math.max(100, (n / effectiveVisible) * 100);
                const zoomable = n > minVisible;

                const gridStep = range <= 100 ? 25 : range <= 200 ? 50 : 100;
                const firstLine = Math.ceil(min / gridStep) * gridStep;
                const lines = [];
                for (let v = firstLine; v <= max; v += gridStep) lines.push(v);
                const pointsLines = [20, 30, 40, 50, 60];

                const pointsY = (v) => ((Math.min(pointsMax, Math.max(pointsMin, v)) - pointsMin) / pointsRange) * 100;
                const xCenter = (i) => ((i + 0.5) / n) * 100;

                // Werte-Reihe (mit Lücken bei null) in zusammenhängende Linien-Segmente zerlegen
                const buildSegments = (vals) => {
                    const segs = [];
                    let cur = [];
                    vals.forEach((p, i) => {
                        if (p === null) {
                            if (cur.length) { segs.push(cur); cur = []; }
                        } else {
                            cur.push({ i, y: 100 - pointsY(p) });
                        }
                    });
                    if (cur.length) segs.push(cur);
                    return segs;
                };
                const pointsSegments = buildSegments(pointsVals);

                // Gleitender Durchschnitt über die letzten N Spiele (nur Matches mit gesetzten Punkten zählen)
                const rollingAvg = (window) => pointsVals.map((_, i) => {
                    const start = Math.max(0, i - window + 1);
                    const slice = pointsVals.slice(start, i + 1).filter(p => p !== null);
                    if (slice.length < 3) return null;
                    return slice.reduce((a, b) => a + b, 0) / slice.length;
                });
                const rollingAvg10 = rollingAvg(10);
                const rollingAvg20 = rollingAvg(20);
                const avg10Segments = buildSegments(rollingAvg10);
                const avg20Segments = buildSegments(rollingAvg20);

                const eloOn = showElo;
                const pointsOn = hasPoints && showPoints;
                const avg10On = hasPoints && showAvg10;
                const avg20On = hasPoints && showAvg20;
                const pointsAxisOn = pointsOn || avg10On || avg20On;   // rechte Punkte-Achse/Skala aktiv?
                const anyOn = eloOn || pointsAxisOn;
                const leftPad = eloOn ? 40 : 0;
                const rightPad = pointsAxisOn ? 40 : 0;
                const useEloGrid = eloOn;
                const usePointsGrid = !eloOn && pointsAxisOn;

                return (
                    <div style={s.card}>
                        <div style={{ display: 'flex', alignItems: 'center', marginBottom: '16px', gap: '16px', flexWrap: 'wrap' }}>
                            <label style={{ display: 'inline-flex', alignItems: 'center', gap: '8px', cursor: 'pointer', userSelect: 'none', fontSize: '16px', fontWeight: '700', color: '#2B2931' }}>
                                <input type="checkbox" checked={showElo} onChange={(e) => setShowElo(e.target.checked)}
                                    style={{ width: '16px', height: '16px', cursor: 'pointer', accentColor: '#2B2931', margin: 0 }} />
                                ELO-Verlauf
                            </label>
                            {hasPoints && (
                                <label style={{ display: 'inline-flex', alignItems: 'center', gap: '8px', cursor: 'pointer', userSelect: 'none', fontSize: '15px', fontWeight: '700', color: POINTS_COLOR }}>
                                    <input type="checkbox" checked={showPoints} onChange={(e) => setShowPoints(e.target.checked)}
                                        style={{ width: '16px', height: '16px', cursor: 'pointer', accentColor: POINTS_COLOR, margin: 0 }} />
                                    Punkte-Verlauf
                                </label>
                            )}
                            {hasPoints && (
                                <label style={{ display: 'inline-flex', alignItems: 'center', gap: '8px', cursor: 'pointer', userSelect: 'none', fontSize: '15px', fontWeight: '700', color: AVG10_COLOR }}>
                                    <input type="checkbox" checked={showAvg10} onChange={(e) => setShowAvg10(e.target.checked)}
                                        style={{ width: '16px', height: '16px', cursor: 'pointer', accentColor: AVG10_COLOR, margin: 0 }} />
                                    Ø Punkte (10)
                                </label>
                            )}
                            {hasPoints && (
                                <label style={{ display: 'inline-flex', alignItems: 'center', gap: '8px', cursor: 'pointer', userSelect: 'none', fontSize: '15px', fontWeight: '700', color: AVG20_COLOR }}>
                                    <input type="checkbox" checked={showAvg20} onChange={(e) => setShowAvg20(e.target.checked)}
                                        style={{ width: '16px', height: '16px', cursor: 'pointer', accentColor: AVG20_COLOR, margin: 0 }} />
                                    Ø Punkte (20)
                                </label>
                            )}
                        </div>
                        {zoomable && (
                            <div style={{ display: 'flex', alignItems: 'center', gap: '10px', marginBottom: '12px', fontSize: '12px', color: '#9B8579' }}>
                                <span style={{ fontWeight: '600', color: '#58595B' }}>Zoom</span>
                                <span style={{ fontSize: '16px', lineHeight: 1, color: '#9B8579' }}>−</span>
                                <input
                                    type="range"
                                    min={minVisible}
                                    max={maxVisible}
                                    step={1}
                                    value={minVisible + maxVisible - effectiveVisible}
                                    onChange={(e) => handleZoomChange(minVisible + maxVisible - parseInt(e.target.value, 10))}
                                    style={{ flex: 1, accentColor: '#2B2931', cursor: 'pointer', minWidth: '120px' }}
                                    aria-label="Chart-Zoom"
                                />
                                <span style={{ fontSize: '16px', lineHeight: 1, color: '#9B8579' }}>+</span>
                                <span style={{ minWidth: '70px', textAlign: 'right', color: '#58595B' }}>{effectiveVisible} / {n}</span>
                            </div>
                        )}
                        <div style={{ position: 'relative', marginLeft: leftPad + 'px', marginRight: rightPad + 'px' }}>
                            {eloOn && (
                                <div style={{ position: 'absolute', left: '-40px', bottom: 0, height: '140px', width: '40px', pointerEvents: 'none', zIndex: 2 }}>
                                    {lines.map(v => {
                                        const pct = ((v - min) / range) * 100;
                                        return (
                                            <span key={v} style={{ position: 'absolute', bottom: pct + '%', right: '4px', fontSize: '11px', color: '#9B8579', transform: 'translateY(50%)', lineHeight: 1 }}>{v}</span>
                                        );
                                    })}
                                </div>
                            )}
                            {pointsAxisOn && (
                                <div style={{ position: 'absolute', right: '-40px', bottom: 0, height: '140px', width: '40px', pointerEvents: 'none', zIndex: 2 }}>
                                    {pointsLines.map(v => (
                                        <span key={v} style={{ position: 'absolute', bottom: pointsY(v) + '%', left: '4px', fontSize: '11px', color: POINTS_COLOR, fontWeight: '600', transform: 'translateY(50%)', lineHeight: 1 }}>{v}</span>
                                    ))}
                                </div>
                            )}
                            <div ref={chartScrollRef} style={{ overflowX: 'auto', height: '180px' }}>
                                <div style={{ width: widthPct + '%', height: '100%', position: 'relative', minWidth: '100%' }}>
                                    <div style={{ position: 'absolute', left: 0, right: 0, bottom: 0, height: '140px' }}>
                                        {useEloGrid && lines.map(v => {
                                            const pct = ((v - min) / range) * 100;
                                            return (
                                                <div key={`el-${v}`} style={{ position: 'absolute', bottom: pct + '%', left: 0, right: 0, borderBottom: '1px dashed #E8E0D8', pointerEvents: 'none' }} />
                                            );
                                        })}
                                        {pointsAxisOn && pointsLines.filter(v => v > 0).map(v => (
                                            <div key={`pl-${v}`} style={{
                                                position: 'absolute', bottom: pointsY(v) + '%', left: 0, right: 0,
                                                borderBottom: '1px dashed ' + POINTS_COLOR,
                                                opacity: useEloGrid ? 0.28 : 0.5,
                                                pointerEvents: 'none'
                                            }} />
                                        ))}
                                        {eloOn && elos.map((elo, i) => (
                                            <div key={i} style={{
                                                position: 'absolute',
                                                left: `calc(${(i / n) * 100}% + 1px)`,
                                                width: `calc(${100 / n}% - 2px)`,
                                                bottom: 0,
                                                height: ((elo - min) / range * 100) + '%',
                                                minWidth: '2px',
                                                background: i === elos.length - 1 ? '#FBB040' : '#2B2931',
                                                borderRadius: '2px 2px 0 0',
                                                opacity: tipIdx !== null && tipIdx !== i ? 0.35 : (0.7 + (i / elos.length) * 0.3),
                                                zIndex: 1
                                            }}></div>
                                        ))}
                                        {pointsAxisOn && (
                                            <React.Fragment>
                                                <svg width="100%" height="100%" viewBox={`0 0 ${n} 100`} preserveAspectRatio="none" style={{ position: 'absolute', inset: 0, overflow: 'visible', zIndex: 2, pointerEvents: 'none' }}>
                                                    {pointsOn && pointsSegments.map((seg, idx) => (
                                                        seg.length >= 2 ? (
                                                            <polyline key={`pts-${idx}`} fill="none" stroke={POINTS_COLOR} strokeWidth="1.5" strokeLinejoin="round" strokeLinecap="round" vectorEffect="non-scaling-stroke" points={seg.map(pt => `${pt.i + 0.5},${pt.y}`).join(' ')} />
                                                        ) : null
                                                    ))}
                                                    {avg10On && avg10Segments.map((seg, idx) => (
                                                        seg.length >= 2 ? (
                                                            <polyline key={`a10-${idx}`} fill="none" stroke={AVG10_COLOR} strokeWidth="2" strokeLinejoin="round" strokeLinecap="round" vectorEffect="non-scaling-stroke" points={seg.map(pt => `${pt.i + 0.5},${pt.y}`).join(' ')} />
                                                        ) : null
                                                    ))}
                                                    {avg20On && avg20Segments.map((seg, idx) => (
                                                        seg.length >= 2 ? (
                                                            <polyline key={`a20-${idx}`} fill="none" stroke={AVG20_COLOR} strokeWidth="2" strokeLinejoin="round" strokeLinecap="round" vectorEffect="non-scaling-stroke" points={seg.map(pt => `${pt.i + 0.5},${pt.y}`).join(' ')} />
                                                        ) : null
                                                    ))}
                                                </svg>
                                                {pointsOn && pointsVals.map((p, i) => p === null ? null : (
                                                    <div key={`p-${i}`} style={{
                                                        position: 'absolute', left: xCenter(i) + '%', bottom: pointsY(p) + '%',
                                                        transform: 'translate(-50%, 50%)',
                                                        width: tipIdx === i ? '7px' : '4px',
                                                        height: tipIdx === i ? '7px' : '4px',
                                                        borderRadius: '50%',
                                                        background: POINTS_COLOR,
                                                        boxShadow: '0 0 0 1px white',
                                                        zIndex: 3, pointerEvents: 'none',
                                                        transition: 'width 0.1s, height 0.1s'
                                                    }} />
                                                ))}
                                            </React.Fragment>
                                        )}
                                    </div>

                                    {anyOn && elos.map((_, i) => (
                                        <div key={`hb-${i}`}
                                            onPointerEnter={(e) => { if (e.pointerType === 'mouse') setTipIdx(i); }}
                                            onPointerLeave={(e) => { if (e.pointerType === 'mouse') setTipIdx(prev => prev === i ? null : prev); }}
                                            onPointerDown={(e) => { if (e.pointerType !== 'mouse') setTipIdx(prev => prev === i ? null : i); }}
                                            style={{ position: 'absolute', left: ((i / n) * 100) + '%', top: 0, bottom: 0, width: (100 / n) + '%', cursor: 'pointer', zIndex: 4 }} />
                                    ))}

                                    {tipIdx !== null && anyOn && (() => {
                                        const d = elo_history[tipIdx];
                                        const dt = d.match_date ? new Date(d.match_date).toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit', year: '2-digit' }) : '';
                                        const pVal = pointsVals[tipIdx];
                                        const leftPct = xCenter(tipIdx);
                                        const anchorRight = leftPct > 80;
                                        const anchorLeft = leftPct < 20;
                                        const tx = anchorLeft ? '0' : anchorRight ? '-100%' : '-50%';
                                        return (
                                            <div style={{
                                                position: 'absolute',
                                                left: leftPct + '%',
                                                top: '4px',
                                                transform: `translateX(${tx})`,
                                                background: 'white',
                                                border: '1px solid #E8E0D8',
                                                borderRadius: '8px',
                                                padding: '6px 9px',
                                                fontSize: '11px',
                                                lineHeight: '1.4',
                                                boxShadow: '0 2px 8px rgba(0,0,0,0.12)',
                                                whiteSpace: 'nowrap',
                                                zIndex: 5,
                                                pointerEvents: 'none'
                                            }}>
                                                <div style={{ color: '#9B8579', fontSize: '10px', marginBottom: '2px' }}>{dt}</div>
                                                {eloOn && <div style={{ color: '#2B2931' }}>ELO: <strong>{elos[tipIdx]}</strong></div>}
                                                {pointsOn && pVal !== null && (
                                                    <div style={{ color: POINTS_COLOR }}>Punkte: <strong>{pVal}</strong></div>
                                                )}
                                                {avg10On && rollingAvg10[tipIdx] !== null && (
                                                    <div style={{ color: AVG10_COLOR }}>Ø 10 Spiele: <strong>{rollingAvg10[tipIdx].toFixed(1)}</strong></div>
                                                )}
                                                {avg20On && rollingAvg20[tipIdx] !== null && (
                                                    <div style={{ color: AVG20_COLOR }}>Ø 20 Spiele: <strong>{rollingAvg20[tipIdx].toFixed(1)}</strong></div>
                                                )}
                                            </div>
                                        );
                                    })()}

                                    {tipIdx !== null && anyOn && (
                                        <div style={{
                                            position: 'absolute',
                                            left: xCenter(tipIdx) + '%',
                                            bottom: 0,
                                            height: '140px',
                                            width: '1px',
                                            background: '#9B8579',
                                            opacity: 0.4,
                                            transform: 'translateX(-50%)',
                                            zIndex: 1,
                                            pointerEvents: 'none'
                                        }} />
                                    )}
                                </div>
                            </div>
                        </div>
                        <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: '11px', color: '#9B8579', marginTop: '6px', marginLeft: leftPad + 'px', marginRight: rightPad + 'px' }}>
                            <span>{elo_history[0].match_date}</span>
                            <span>{elo_history[n - 1].match_date}</span>
                        </div>
                    </div>
                );
            })()}

            {/* Statistik-Grid */}
            <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(140px, 1fr))', gap: '10px', marginBottom: '20px' }}>
                <div style={{ background: '#F5F0EB', borderRadius: '12px', padding: '10px 12px', display: 'flex', alignItems: 'center', gap: '8px', minWidth: 0 }}>
                    <div style={{ fontSize: '20px', flexShrink: 0 }}>🎮</div>
                    <div style={{ minWidth: 0 }}>
                        <div style={{ fontSize: '18px', fontWeight: '700', color: '#2B2931' }}>{player.total_matches}</div>
                        <div style={{ fontSize: '11px', color: '#58595B', marginTop: '2px' }}>Matches</div>
                    </div>
                    <div style={{ marginLeft: 'auto', display: 'flex', gap: '8px', flexShrink: 0 }}>
                        <div style={{ textAlign: 'center' }}><div style={{ fontSize: '13px', fontWeight: '700', color: '#2B2931' }}>{player.matches_4p}</div><div style={{ fontSize: '9px', color: '#58595B' }}>4er</div></div>
                        <div style={{ textAlign: 'center' }}><div style={{ fontSize: '13px', fontWeight: '700', color: '#2B2931' }}>{player.matches_3p}</div><div style={{ fontSize: '9px', color: '#58595B' }}>3er</div></div>
                        <div style={{ textAlign: 'center' }}><div style={{ fontSize: '13px', fontWeight: '700', color: '#2B2931' }}>{player.matches_2p}</div><div style={{ fontSize: '9px', color: '#58595B' }}>2er</div></div>
                    </div>
                </div>
                <div style={{ background: '#FBB040', borderRadius: '12px', padding: '10px 12px', display: 'flex', alignItems: 'center', gap: '8px', minWidth: 0 }}>
                    <div style={{ fontSize: '20px', flexShrink: 0 }}>🥇</div>
                    <div style={{ minWidth: 0 }}>
                        <div style={{ fontSize: '18px', fontWeight: '700', color: '#2B2931' }}>{player.wins}</div>
                        <div style={{ fontSize: '11px', color: '#58595B', marginTop: '2px' }}>Siege</div>
                    </div>
                    <div style={{ marginLeft: 'auto', display: 'flex', gap: '8px', flexShrink: 0 }}>
                        <div style={{ textAlign: 'center' }}><div style={{ fontSize: '13px', fontWeight: '700', color: '#2B2931' }}>{player.wins_4p}</div><div style={{ fontSize: '9px', color: '#58595B' }}>4er</div></div>
                        <div style={{ textAlign: 'center' }}><div style={{ fontSize: '13px', fontWeight: '700', color: '#2B2931' }}>{player.wins_3p}</div><div style={{ fontSize: '9px', color: '#58595B' }}>3er</div></div>
                        <div style={{ textAlign: 'center' }}><div style={{ fontSize: '13px', fontWeight: '700', color: '#2B2931' }}>{player.wins_2p}</div><div style={{ fontSize: '9px', color: '#58595B' }}>2er</div></div>
                    </div>
                </div>
                {statBox('Siegrate', player.win_rate + '%', '📊')}
                {statBox('Ø Platz', player.avg_position || '—', '📈')}
                {statBox('Bestes ELO', player.highest_elo, '⭐')}
                <div style={{ background: '#F5F0EB', borderRadius: '12px', padding: '10px 12px', display: 'flex', alignItems: 'center', gap: '8px', minWidth: 0 }}>
                    <div style={{ fontSize: '20px', flexShrink: 0 }}>🚨</div>
                    <div style={{ minWidth: 0 }}>
                        <div style={{ fontSize: '18px', fontWeight: '700', color: '#2B2931' }}>{player.last_places}</div>
                        <div style={{ fontSize: '11px', color: '#58595B', marginTop: '2px' }}>Letzte Plätze</div>
                    </div>
                    <div style={{ marginLeft: 'auto', display: 'flex', gap: '8px', flexShrink: 0 }}>
                        <div style={{ textAlign: 'center' }}><div style={{ fontSize: '13px', fontWeight: '700', color: '#2B2931' }}>{player.last_places_4p}</div><div style={{ fontSize: '9px', color: '#58595B' }}>4er</div></div>
                        <div style={{ textAlign: 'center' }}><div style={{ fontSize: '13px', fontWeight: '700', color: '#2B2931' }}>{player.last_places_3p}</div><div style={{ fontSize: '9px', color: '#58595B' }}>3er</div></div>
                        <div style={{ textAlign: 'center' }}><div style={{ fontSize: '13px', fontWeight: '700', color: '#2B2931' }}>{player.last_places_2p}</div><div style={{ fontSize: '9px', color: '#58595B' }}>2er</div></div>
                    </div>
                </div>
            </div>

            {/* Stärkster Sieg & Niederlage */}
            {(player.biggest_elo_gain || player.biggest_elo_loss) && (
                <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(220px, 1fr))', gap: '12px', marginBottom: '20px' }}>
                    {player.biggest_elo_gain && (
                        <div onClick={() => setExpandedGain(!expandedGain)} style={{ ...s.card, marginBottom: 0, borderLeft: '4px solid #28a745', cursor: 'pointer' }}>
                            <div style={{ fontSize: '12px', color: '#28a745', fontWeight: '700', marginBottom: '8px', textTransform: 'uppercase' }}>Stärkster Sieg</div>
                            <div style={{ display: 'flex', alignItems: 'center', gap: '10px' }}>
                                <div style={{ fontSize: '24px' }}>📈</div>
                                <div>
                                    <div style={{ fontWeight: '700', color: '#28a745', fontSize: '20px' }}>+{player.biggest_elo_gain.elo_change} ELO</div>
                                    <div style={{ fontSize: '12px', color: '#9B8579' }}>{new Date(player.biggest_elo_gain.match_date).toLocaleDateString('de-DE')}</div>
                                </div>
                            </div>
                            {expandedGain && player.biggest_elo_gain.participants && player.biggest_elo_gain.participants.length > 0 && (
                                <div style={{ marginTop: '12px', borderTop: '1px solid #EDE8E3', paddingTop: '10px' }}>
                                    {player.biggest_elo_gain.participants.map((p, i) => (
                                        <div key={i} style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '4px 0', fontSize: '13px' }}>
                                            <span style={{ color: '#2B2931' }}>{p.position}. {p.display_name} <span style={{ color: '#9B8579', fontSize: '11px' }}>({p.elo_before})</span></span>
                                            <span style={{ fontWeight: '600', color: p.elo_change >= 0 ? '#28a745' : '#c0392b' }}>{p.elo_change >= 0 ? '+' : ''}{p.elo_change}</span>
                                        </div>
                                    ))}
                                </div>
                            )}
                        </div>
                    )}
                    {player.biggest_elo_loss && (
                        <div onClick={() => setExpandedLoss(!expandedLoss)} style={{ ...s.card, marginBottom: 0, borderLeft: '4px solid #c0392b', cursor: 'pointer' }}>
                            <div style={{ fontSize: '12px', color: '#c0392b', fontWeight: '700', marginBottom: '8px', textTransform: 'uppercase' }}>Überraschendste Niederlage</div>
                            <div style={{ display: 'flex', alignItems: 'center', gap: '10px' }}>
                                <div style={{ fontSize: '24px' }}>📉</div>
                                <div>
                                    <div style={{ fontWeight: '700', color: '#c0392b', fontSize: '20px' }}>{player.biggest_elo_loss.elo_change} ELO</div>
                                    <div style={{ fontSize: '12px', color: '#9B8579' }}>{new Date(player.biggest_elo_loss.match_date).toLocaleDateString('de-DE')}</div>
                                </div>
                            </div>
                            {expandedLoss && player.biggest_elo_loss.participants && player.biggest_elo_loss.participants.length > 0 && (
                                <div style={{ marginTop: '12px', borderTop: '1px solid #EDE8E3', paddingTop: '10px' }}>
                                    {player.biggest_elo_loss.participants.map((p, i) => (
                                        <div key={i} style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '4px 0', fontSize: '13px' }}>
                                            <span style={{ color: '#2B2931' }}>{p.position}. {p.display_name} <span style={{ color: '#9B8579', fontSize: '11px' }}>({p.elo_before})</span></span>
                                            <span style={{ fontWeight: '600', color: p.elo_change >= 0 ? '#28a745' : '#c0392b' }}>{p.elo_change >= 0 ? '+' : ''}{p.elo_change}</span>
                                        </div>
                                    ))}
                                </div>
                            )}
                        </div>
                    )}
                </div>
            )}

            {/* Lieblingsgegner & Nemesis */}
            {(lieblingsgegner_absolut || lieblingsgegner_relativ || nemesis_absolut || nemesis_relativ) && (
                <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(220px, 1fr))', gap: '12px', marginBottom: '20px' }}>
                    {lieblingsgegner_absolut && (
                        <div onClick={() => navigate('player-stats/' + lieblingsgegner_absolut.opponent_id)} style={{ ...s.card, marginBottom: 0, borderLeft: '4px solid #28a745', cursor: 'pointer' }}>
                            <div style={{ fontSize: '12px', color: '#28a745', fontWeight: '700', marginBottom: '8px', textTransform: 'uppercase' }}>Lieblingsgegner (absolut)</div>
                            <div style={{ display: 'flex', alignItems: 'center', gap: '10px' }}>
                                {avatarEl(lieblingsgegner_absolut.opponent_picture, lieblingsgegner_absolut.opponent_initials, 40)}
                                <div>
                                    <div style={{ fontWeight: '700', color: '#2B2931' }}>{lieblingsgegner_absolut.opponent_name}</div>
                                    <div style={{ fontSize: '13px', color: '#58595B' }}>{lieblingsgegner_absolut.my_wins} von {lieblingsgegner_absolut.matches_together} gewonnen</div>
                                </div>
                            </div>
                        </div>
                    )}
                    {lieblingsgegner_relativ && (
                        <div onClick={() => navigate('player-stats/' + lieblingsgegner_relativ.opponent_id)} style={{ ...s.card, marginBottom: 0, borderLeft: '4px solid #28a745', cursor: 'pointer' }}>
                            <div style={{ fontSize: '12px', color: '#28a745', fontWeight: '700', marginBottom: '8px', textTransform: 'uppercase' }}>Lieblingsgegner (relativ)</div>
                            <div style={{ display: 'flex', alignItems: 'center', gap: '10px' }}>
                                {avatarEl(lieblingsgegner_relativ.opponent_picture, lieblingsgegner_relativ.opponent_initials, 40)}
                                <div>
                                    <div style={{ fontWeight: '700', color: '#2B2931' }}>{lieblingsgegner_relativ.opponent_name}</div>
                                    <div style={{ fontSize: '13px', color: '#58595B' }}>{Math.round(lieblingsgegner_relativ.my_wins / lieblingsgegner_relativ.matches_together * 100)}% Siegrate ({lieblingsgegner_relativ.my_wins}/{lieblingsgegner_relativ.matches_together})</div>
                                </div>
                            </div>
                        </div>
                    )}
                    {nemesis_absolut && (
                        <div onClick={() => navigate('player-stats/' + nemesis_absolut.opponent_id)} style={{ ...s.card, marginBottom: 0, borderLeft: '4px solid #c0392b', cursor: 'pointer' }}>
                            <div style={{ fontSize: '12px', color: '#c0392b', fontWeight: '700', marginBottom: '8px', textTransform: 'uppercase' }}>Nemesis (absolut)</div>
                            <div style={{ display: 'flex', alignItems: 'center', gap: '10px' }}>
                                {avatarEl(nemesis_absolut.opponent_picture, nemesis_absolut.opponent_initials, 40)}
                                <div>
                                    <div style={{ fontWeight: '700', color: '#2B2931' }}>{nemesis_absolut.opponent_name}</div>
                                    <div style={{ fontSize: '13px', color: '#58595B' }}>{nemesis_absolut.opp_wins} von {nemesis_absolut.matches_together} verloren</div>
                                </div>
                            </div>
                        </div>
                    )}
                    {nemesis_relativ && (
                        <div onClick={() => navigate('player-stats/' + nemesis_relativ.opponent_id)} style={{ ...s.card, marginBottom: 0, borderLeft: '4px solid #c0392b', cursor: 'pointer' }}>
                            <div style={{ fontSize: '12px', color: '#c0392b', fontWeight: '700', marginBottom: '8px', textTransform: 'uppercase' }}>Nemesis (relativ)</div>
                            <div style={{ display: 'flex', alignItems: 'center', gap: '10px' }}>
                                {avatarEl(nemesis_relativ.opponent_picture, nemesis_relativ.opponent_initials, 40)}
                                <div>
                                    <div style={{ fontWeight: '700', color: '#2B2931' }}>{nemesis_relativ.opponent_name}</div>
                                    <div style={{ fontSize: '13px', color: '#58595B' }}>{Math.round(nemesis_relativ.opp_wins / nemesis_relativ.matches_together * 100)}% Niederlagenrate ({nemesis_relativ.opp_wins}/{nemesis_relativ.matches_together})</div>
                                </div>
                            </div>
                        </div>
                    )}
                </div>
            )}

            {/* Head-to-Head Tabelle */}
            {head_to_head.length > 0 && (
                <div style={s.card}>
                    <style>{`
                        .h2h-row { display: grid; grid-template-columns: 180px 1fr 70px; align-items: center; gap: 12px; padding: 10px 0; border-bottom: 1px solid #EDE8E3; }
                        .h2h-bar-section { display: flex; align-items: center; gap: 8px; }
                        .h2h-games { font-size: 12px; color: #9B8579; text-align: right; }
                        @media (max-width: 600px) {
                            .h2h-row { grid-template-columns: 1fr; }
                            .h2h-bar-section { width: 100%; }
                        }
                    `}</style>
                    <h3 style={{ marginBottom: '16px', color: '#2B2931' }}>Head-to-Head</h3>
                    {head_to_head.map(h => {
                        const total = h.matches_together;
                        const myPct = total > 0 ? (h.my_wins / total * 100) : 0;
                        const drawPct = total > 0 ? (h.draws / total * 100) : 0;
                        const oppPct = total > 0 ? (h.opp_wins / total * 100) : 0;
                        const streakIsMe = h.current_streak_holder === 'me';
                        const streakName = streakIsMe ? player.display_name : h.opponent_name;
                        const bestStreak = Math.max(h.best_streak_me || 0, h.best_streak_opp || 0);
                        const bestStreakName = (h.best_streak_me || 0) >= (h.best_streak_opp || 0) ? player.display_name : h.opponent_name;
                        return (
                            <div key={h.opponent_id} style={{ padding: '10px 0', borderBottom: '1px solid #EDE8E3' }}>
                                <div className="h2h-row" style={{ padding: 0, borderBottom: 'none' }}>
                                    <div onClick={() => navigate('player-stats/' + h.opponent_id)} style={{ display: 'flex', alignItems: 'center', gap: '10px', cursor: 'pointer', overflow: 'hidden' }}>
                                        {avatarEl(h.opponent_picture, h.opponent_initials, 32)}
                                        <div style={{ fontWeight: '600', fontSize: '14px', textDecoration: 'underline', textDecorationColor: '#E8E0D8', textUnderlineOffset: '2px', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{h.opponent_name}</div>
                                    </div>
                                    <div className="h2h-bar-section">
                                        <span style={{ fontSize: '13px', fontWeight: '700', color: '#28a745', minWidth: '28px', textAlign: 'right', flexShrink: 0 }}>{h.my_wins}</span>
                                        <div style={{ flex: 1, height: '8px', borderRadius: '4px', background: '#c0392b', overflow: 'hidden', display: 'flex' }}>
                                            <div style={{ width: myPct + '%', background: '#28a745', transition: 'width 0.3s' }}></div>
                                            <div style={{ width: drawPct + '%', background: '#f0c040', transition: 'width 0.3s' }}></div>
                                        </div>
                                        <span style={{ fontSize: '13px', fontWeight: '700', color: '#c0392b', minWidth: '28px', flexShrink: 0 }}>{h.opp_wins}</span>
                                    </div>
                                    <div className="h2h-games">{h.matches_together} Spiele</div>
                                </div>
                                {h.current_streak > 1 && (
                                    <div style={{ display: 'flex', gap: '12px', flexWrap: 'wrap', marginTop: '4px', paddingLeft: '42px', fontSize: '11px', color: '#9B8579' }}>
                                        <span>🔥 Streak: <strong style={{ color: streakIsMe ? '#28a745' : '#c0392b' }}>{streakName}</strong> ({h.current_streak}x)</span>
                                        {bestStreak > 1 && <span>📊 Rekord: <strong style={{ color: '#2B2931' }}>{bestStreakName}</strong> ({bestStreak}x)</span>}
                                    </div>
                                )}
                                {h.current_streak <= 1 && bestStreak > 1 && (
                                    <div style={{ marginTop: '4px', paddingLeft: '42px', fontSize: '11px', color: '#9B8579' }}>
                                        📊 Längster Streak: <strong style={{ color: '#2B2931' }}>{bestStreakName}</strong> ({bestStreak}x)
                                    </div>
                                )}
                            </div>
                        );
                    })}
                </div>
            )}

            {/* Letzte Matches */}
            {recent_matches.length > 0 && (
                <div style={s.card}>
                    <h3 style={{ marginBottom: '16px', color: '#2B2931' }}>Letzte Matches</h3>
                    {recent_matches.map(m => (
                        <div key={m.match_id} style={{ display: 'flex', alignItems: 'center', gap: '12px', padding: '10px 0', borderBottom: '1px solid #EDE8E3', fontSize: '14px' }}>
                            <div style={{ fontSize: '20px', minWidth: '32px', textAlign: 'center' }}>{positionEmoji(m.position, m.match_size)}</div>
                            <div style={{ flex: 1 }}>
                                <div style={{ color: '#2B2931', fontWeight: '600' }}>{m.match_date}</div>
                                <div style={{ fontSize: '12px', color: '#9B8579' }}>
                                    {m.participants.map((p, i) => (
                                        <span key={i}>{i > 0 ? ', ' : ''}{p.display_name} ({p.position}.)</span>
                                    ))}
                                </div>
                            </div>
                            <div style={{ fontWeight: '700', color: m.elo_change >= 0 ? '#28a745' : '#c0392b', minWidth: '50px', textAlign: 'right' }}>
                                {m.elo_change >= 0 ? '+' : ''}{m.elo_change}
                            </div>
                        </div>
                    ))}
                </div>
            )}
        </div>
    );
}

function SystemSettings() {
    const [settings, setSettings] = useState(null);
    const [loading, setLoading] = useState(true);
    const [saving, setSaving] = useState(false);

    useEffect(() => {
        (async () => {
            try {
                const data = await api.getSettings();
                setSettings(data.settings);
            } finally {
                setLoading(false);
            }
        })();
    }, []);

    const toggle = async (key) => {
        const newVal = settings[key] === '1' ? false : true;
        setSaving(true);
        try {
            const data = await api.updateSettings({ [key]: newVal });
            setSettings(data.settings);
        } finally {
            setSaving(false);
        }
    };

    const saveSetting = async (key, value) => {
        setSaving(true);
        try {
            const data = await api.updateSettings({ [key]: value });
            setSettings(data.settings);
        } finally {
            setSaving(false);
        }
    };

    if (loading) return <div style={s.card}>Lade Einstellungen...</div>;
    if (!settings) return <div style={s.card}>Einstellungen konnten nicht geladen werden.</div>;

    const ToggleSwitch = ({ label, description, settingKey }) => {
        const enabled = settings[settingKey] === '1';
        return (
            <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '16px 0', borderBottom: '1px solid #EDE8E3' }}>
                <div>
                    <div style={{ fontWeight: '600', color: '#2B2931', fontSize: '15px' }}>{label}</div>
                    <div style={{ fontSize: '13px', color: '#9B8579', marginTop: '2px' }}>{description}</div>
                </div>
                <button onClick={() => toggle(settingKey)} disabled={saving} style={{
                    width: '52px', height: '28px', borderRadius: '14px', border: 'none', cursor: saving ? 'wait' : 'pointer',
                    background: enabled ? '#28a745' : '#E8E0D8', position: 'relative', transition: 'background 0.2s', flexShrink: 0, marginLeft: '16px'
                }}>
                    <div style={{
                        width: '22px', height: '22px', borderRadius: '50%', background: 'white', position: 'absolute', top: '3px',
                        left: enabled ? '27px' : '3px', transition: 'left 0.2s', boxShadow: '0 1px 3px rgba(0,0,0,0.2)'
                    }}></div>
                </button>
            </div>
        );
    };

    return (
        <div>
            <h2 style={s.title}>Systemeinstellungen</h2>
            <div style={s.card}>
                <h3 style={{ marginBottom: '8px', color: '#2B2931' }}>Benachrichtigungen</h3>
                <p style={{ fontSize: '13px', color: '#9B8579', marginBottom: '16px' }}>Steuere, wohin Match-Ergebnisse automatisch gesendet werden.</p>
                <ToggleSwitch label="Slack" description="Match-Ergebnisse und Rekorde an den Slack-Channel senden" settingKey="slack_enabled" />
                <ToggleSwitch label="Vestaboard" description="Match-Updates auf dem Vestaboard anzeigen" settingKey="vestaboard_enabled" />
            </div>

            <div style={s.card}>
                <h3 style={{ marginBottom: '8px', color: '#2B2931' }}>ELO-System</h3>
                <p style={{ fontSize: '13px', color: '#9B8579', marginBottom: '16px' }}>Einstellungen für das ELO-Rating-System.</p>
                <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '16px 0' }}>
                    <div>
                        <div style={{ fontWeight: '600', color: '#2B2931', fontSize: '15px' }}>Start-ELO für neue Spieler</div>
                        <div style={{ fontSize: '13px', color: '#9B8579', marginTop: '2px' }}>ELO-Punktzahl, mit der neue Spieler starten</div>
                    </div>
                    <input type="number" value={settings.default_elo || '1200'} onChange={(e) => setSettings({ ...settings, default_elo: e.target.value })}
                        onBlur={(e) => { const v = parseInt(e.target.value); if (v > 0) saveSetting('default_elo', v); }}
                        style={{ ...s.input, width: '80px', marginBottom: 0, textAlign: 'center', flexShrink: 0, marginLeft: '16px' }} min="0" />
                </div>
            </div>
        </div>
    );
}

const VALID_VIEWS = ['leaderboard', 'add-match', 'history', 'players', 'player-edit', 'player-stats', 'settings', 'account', 'login'];
const PUBLIC_VIEWS = ['leaderboard', 'history', 'player-stats', 'login'];

function getViewFromHash() {
    const hash = window.location.hash.replace('#/', '').replace('#', '');
    if (hash.startsWith('player-edit/')) return 'player-edit';
    if (hash.startsWith('player-stats/')) return 'player-stats';
    return VALID_VIEWS.includes(hash) ? hash : 'leaderboard';
}

function getPlayerIdFromHash() {
    const hash = window.location.hash.replace('#/', '').replace('#', '');
    const match = hash.match(/^player-edit\/(\d+)$/);
    return match ? parseInt(match[1]) : null;
}

function getPlayerStatsIdFromHash() {
    const hash = window.location.hash.replace('#/', '').replace('#', '');
    const match = hash.match(/^player-stats\/(\d+)$/);
    return match ? parseInt(match[1]) : null;
}

function navigate(view) {
    window.location.hash = '#/' + view;
}

function App() {
    const [user, setUser] = useState(null);
    const [loading, setLoading] = useState(true);
    const [currentView, setCurrentView] = useState(getViewFromHash);
    const [menuOpen, setMenuOpen] = useState(false);
    const [fontSize, setFontSize] = useState(() => parseInt(localStorage.getItem('mk-fontsize') || '14'));

    // Hash-Änderungen lauschen (Browser vor/zurück)
    const [hashKey, setHashKey] = useState(0);
    useEffect(() => {
        const onHashChange = () => {
            setCurrentView(getViewFromHash());
            setHashKey(k => k + 1);
        };
        window.addEventListener('hashchange', onHashChange);
        return () => window.removeEventListener('hashchange', onHashChange);
    }, []);

    useEffect(() => {
        (async () => {
            if (!api.token) {
                setLoading(false);
                return;
            }
            try {
                const [userData] = await Promise.all([
                    api.getCurrentUser(),
                    api.getPlayers() // Prefetch Spielerliste
                ]);
                setUser(userData.user);
            } catch (err) {
                api.setToken(null);
            } finally {
                setLoading(false);
            }
        })();
    }, []);

    const editPlayerId = getPlayerIdFromHash();
    const statsPlayerId = getPlayerStatsIdFromHash();

    // Nicht-öffentliche Views ohne Login → zurück zu Leaderboard
    useEffect(() => {
        if (!loading && !user && !PUBLIC_VIEWS.includes(currentView)) {
            navigate('leaderboard');
        }
    }, [currentView, user, loading]);

    const handleLoginSuccess = (userData) => {
        setUser(userData);
        navigate('leaderboard');
    };

    const handleLogout = async () => {
        try { await api.logout(); } catch (err) { }
        setUser(null);
        api.setToken(null);
        navigate('leaderboard');
    };

    const changeFontSize = (delta) => {
        setFontSize(prev => {
            const next = Math.max(10, Math.min(20, prev + delta));
            localStorage.setItem('mk-fontsize', next);
            return next;
        });
    };

    if (loading) return null;

    const navBtn = (view, icon, label) => (
        <button onClick={() => { navigate(view); setMenuOpen(false); }} style={{
            ...s.btn,
            padding: '10px 20px',
            fontSize: '14px',
            width: menuOpen ? '100%' : undefined,
            textAlign: menuOpen ? 'left' : undefined,
            background: (currentView === view || (view === 'players' && currentView === 'player-edit')) ? '#2B2931' : 'transparent',
            color: (currentView === view || (view === 'players' && currentView === 'player-edit')) ? 'white' : '#58595B'
        }}>
            {icon} {label}
        </button>
    );

    const burgerBar = (
        <div className="burger-bar" style={{ display: 'none', width: '100%', alignItems: 'center', justifyContent: 'space-between' }}>
            <button onClick={() => setMenuOpen(!menuOpen)} style={{
                ...s.btn, background: 'transparent', padding: '8px', fontSize: '24px', lineHeight: '1', color: '#58595B'
            }} aria-label="Menü">
                {menuOpen ? '✕' : '☰'}
            </button>
            <span style={{ fontSize: '15px', fontWeight: '700', color: '#2B2931', fontFamily: 'Montserrat,sans-serif' }}>🏎️ MK-Rangliste</span>
            {user ? (
                <div onClick={() => { navigate('account'); setMenuOpen(false); }} style={{ cursor: 'pointer' }}>
                    {user.profile_picture ? (
                        <img src={`${API_BASE}/../${user.profile_picture}`} alt="" style={{ width: '32px', height: '32px', borderRadius: '50%', objectFit: 'cover' }} />
                    ) : (
                        <div style={{ width: '32px', height: '32px', borderRadius: '50%', background: '#58595B', display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'white', fontSize: '12px', fontWeight: '700' }}>
                            {user.initials || user.display_name.substring(0, 2).toUpperCase()}
                        </div>
                    )}
                </div>
            ) : (
                <button onClick={() => { navigate('login'); setMenuOpen(false); }} style={{ ...s.btn, ...s.btnPrimary, padding: '6px 14px', fontSize: '13px' }}>Anmelden</button>
            )}
        </div>
    );

    return (
        <div style={{ minHeight: '100vh', padding: '20px', maxWidth: '1200px', margin: '0 auto' }}>
            <style>{`
                .nav-links { display: flex; gap: 12px; flex-wrap: wrap; }
                .nav-right { display: flex; align-items: center; gap: 12px; }
                .burger-bar { display: none !important; }
                .font-controls { display: none !important; }
                @media (max-width: 768px) {
                    .burger-bar { display: flex !important; }
                    .nav-links { display: ${menuOpen ? 'flex' : 'none'}; flex-direction: column; width: 100%; order: 3; }
                    .nav-right { display: ${menuOpen ? 'flex' : 'none'}; width: 100%; justify-content: center; padding-top: 8px; border-top: 1px solid #E8E0D8; margin-top: 4px; order: 4; }
                    .font-controls { display: ${menuOpen ? 'flex' : 'none'} !important; width: 100%; order: 5; padding-top: 8px; border-top: 1px solid #E8E0D8; }
                }
            `}</style>
            <div style={{ ...s.card, display: 'flex', justifyContent: 'space-between', alignItems: 'center', flexWrap: 'wrap', gap: '12px' }}>
                {burgerBar}
                <div className="nav-links">
                    {navBtn('leaderboard', '🏆', 'MK-Rangliste')}
                    {navBtn('history', '📊', 'Historie')}
                    {user && navBtn('add-match', '➕', 'Match eintragen')}
                    {user && user.role === 'admin' && navBtn('players', '👥', 'Spieler')}
                    {user && user.role === 'admin' && navBtn('settings', '🔧', 'System')}
                    {user && navBtn('account', '⚙️', 'Konto')}
                </div>
                <div className="nav-right">
                    {user ? (
                        <>
                            {user.profile_picture ? (
                                <img src={`${API_BASE}/../${user.profile_picture}`} alt="" style={{ width: '32px', height: '32px', borderRadius: '50%', objectFit: 'cover' }} />
                            ) : (
                                <div style={{ width: '32px', height: '32px', borderRadius: '50%', background: '#58595B', display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'white', fontSize: '12px', fontWeight: '700' }}>
                                    {user.initials || user.display_name.substring(0, 2).toUpperCase()}
                                </div>
                            )}
                            <span style={{ fontSize: '14px', color: '#58595B' }}>{user.display_name}</span>
                            <button onClick={() => { handleLogout(); setMenuOpen(false); }} style={{ ...s.btn, ...s.btnSecondary, padding: '8px 16px', fontSize: '14px' }}>Abmelden</button>
                        </>
                    ) : (
                        <button onClick={() => { navigate('login'); setMenuOpen(false); }} style={{ ...s.btn, ...s.btnPrimary, padding: '8px 16px', fontSize: '14px' }}>Anmelden</button>
                    )}
                </div>
                <div className="font-controls">
                    <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', gap: '12px', padding: '8px 0' }}>
                        <span style={{ fontSize: '13px', color: '#58595B' }}>Schriftgr.</span>
                        <button onClick={() => changeFontSize(-1)} style={{ ...s.btn, ...s.btnSecondary, padding: '6px 14px', fontSize: '14px', lineHeight: '1' }}>A-</button>
                        <span style={{ fontSize: '13px', color: '#58595B', minWidth: '24px', textAlign: 'center' }}>{fontSize}</span>
                        <button onClick={() => changeFontSize(1)} style={{ ...s.btn, ...s.btnSecondary, padding: '6px 14px', fontSize: '14px', lineHeight: '1' }}>A+</button>
                    </div>
                </div>
            </div>

            <div style={{ zoom: fontSize / 14 }}>
            {currentView === 'leaderboard' && <><Leaderboard /><Records /></>}
            {currentView === 'login' && !user && <Login onLoginSuccess={handleLoginSuccess} />}
            {currentView === 'add-match' && user && <AddMatch onMatchAdded={() => navigate('history')} />}
            {currentView === 'history' && <MatchHistory user={user} />}
            {currentView === 'players' && user && user.role === 'admin' && <PlayersManagement />}
            {currentView === 'player-edit' && user && user.role === 'admin' && editPlayerId && <PlayerEdit playerId={editPlayerId} />}
            {currentView === 'settings' && user && user.role === 'admin' && <SystemSettings />}
            {currentView === 'player-stats' && statsPlayerId && <PlayerStats key={statsPlayerId} playerId={statsPlayerId} />}
            {currentView === 'account' && user && <AccountSettings user={user} onUserUpdate={setUser} />}
            </div>
        </div>
    );
}

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