import React, { useState, useEffect, useRef } from 'react';
import { 
  BarChart2, 
  Users, 
  MessageSquare, 
  ShieldAlert, 
  Mic, 
  LogOut, 
  LogIn, 
  Activity, 
  Search, 
  Settings, 
  Lock,
  Volume2,
  RefreshCw,
  Clock,
  Trash2,
  UserCheck
} from 'lucide-react';
import {
  Chart as ChartJS,
  CategoryScale,
  LinearScale,
  RadialLinearScale,
  PointElement,
  LineElement,
  Title,
  Tooltip,
  Legend,
  Filler
} from 'chart.js';
import { Line, Radar } from 'react-chartjs-2';

// Register Chart.js components
ChartJS.register(
  CategoryScale,
  LinearScale,
  RadialLinearScale,
  PointElement,
  LineElement,
  Title,
  Tooltip,
  Legend,
  Filler
);

// 3D Galaxy Chatter Orbit Visualization
function ChatterOrbit({ chatters }) {
  const canvasRef = useRef(null);
  const containerRef = useRef(null);
  const particlesRef = useRef(new Map());
  const avatarRef = useRef(null);

  useEffect(() => {
    // Load Avatar via backend proxy (avoids CORS issues with decapi.me)
    if (!avatarRef.current) {
      const img = new Image();
      img.src = '/api/avatar/winx_prinx';
      img.onload = () => { avatarRef.current = img; };
      img.onerror = () => console.warn('[ChatterOrbit] Avatar load failed');
    }
  }, []);

  useEffect(() => {
    const safeChatters = Array.isArray(chatters) ? chatters : [];
    
    safeChatters.forEach(c => {
      const username = c.username || c.display_name || 'unknown';
      if (!particlesRef.current.has(username)) {
        const isLurker = !c.has_chatted && !(c.message_count > 0);
        // All particles go on the ring — tight band around ring radius ±8%
        const ringNoise = (Math.random() - 0.5) * 0.16;
        const radiusNorm = 1.0 + ringNoise;
          
        particlesRef.current.set(username, {
          username,
          displayName: c.display_name || username,
          angle: Math.random() * Math.PI * 2,
          radiusNorm,
          speed: (0.0003 + Math.random() * 0.0004) * (Math.random() > 0.5 ? 1 : -1),
          isMod: c.is_mod,
          isSub: c.is_sub,
          isLurker,
          messageCount: c.message_count || 0,
          isStreamer: username.toLowerCase() === 'winx_prinx',
        });
      } else {
        const p = particlesRef.current.get(username);
        const isLurker = !c.has_chatted && !(c.message_count > 0);
        p.isLurker = isLurker;
        p.messageCount = c.message_count || p.messageCount;
        p.isMod = c.is_mod || p.isMod;
        p.isSub = c.is_sub || p.isSub;
      }
    });
  }, [chatters]);

  useEffect(() => {
    const canvas = canvasRef.current;
    const container = containerRef.current;
    if (!canvas || !container) return;
    const ctx = canvas.getContext('2d');
    let animationId;

    const HEIGHT = 320;

    const resize = () => {
      const dpr = window.devicePixelRatio || 1;
      const rect = container.getBoundingClientRect();
      canvas.width = rect.width * dpr;
      canvas.height = HEIGHT * dpr;
      canvas.style.width = `${rect.width}px`;
      canvas.style.height = `${HEIGHT}px`;
      ctx.scale(dpr, dpr);
    };
    resize();
    window.addEventListener('resize', resize);

    let hoverName = null;
    let hoverX = 0;
    let hoverY = 0;
    let mouseX = -9999;
    let mouseY = -9999;

    const handleMouseMove = (e) => {
      const rect = canvas.getBoundingClientRect();
      mouseX = e.clientX - rect.left;
      mouseY = e.clientY - rect.top;
    };
    const handleMouseLeave = () => { mouseX = -9999; mouseY = -9999; };
    canvas.addEventListener('mousemove', handleMouseMove);
    canvas.addEventListener('mouseleave', handleMouseLeave);

    const animate = () => {
      const width = canvas.width / (window.devicePixelRatio || 1);
      const height = HEIGHT;
      const cx = width / 2;
      const cy = height / 2;

      // Ring fills most of the canvas
      const RX = width * 0.44;
      const RY = height * 0.36;
      const TILT = RY / RX;

      // Solid near-black background
      ctx.fillStyle = '#08080f';
      ctx.fillRect(0, 0, width, height);

      const particles = Array.from(particlesRef.current.values());

      hoverName = null;

      // Update positions
      particles.forEach(p => {
        p.angle += p.speed;
        const r = p.radiusNorm * RX;
        p.x = cx + Math.cos(p.angle) * r;
        p.y = cy + Math.sin(p.angle) * r * TILT;
        p.depth = (Math.sin(p.angle) * TILT + TILT) / (2 * TILT); // 0=back, 1=front

        if (p.isStreamer) {
          p.baseSize = 5;
          p.color = '#A370F7';
        } else if (p.isLurker) {
          p.baseSize = 1;
          p.color = null;
        } else {
          p.baseSize = Math.min(4, 1.5 + Math.log10((p.messageCount || 0) + 1) * 1.2);
          p.color = p.isMod ? '#00F5D4' : p.isSub ? '#FF007F' : '#c8c8d8';
        }
        p.drawSize = p.baseSize;
      });

      // Sort back-to-front
      particles.sort((a, b) => a.depth - b.depth);

      // Draw particles
      particles.forEach(p => {
        const alpha = p.isLurker
          ? 0.15 + p.depth * 0.45
          : 0.5 + p.depth * 0.5;

        let color;
        if (p.isLurker) {
          const brightness = Math.round(160 + p.depth * 60);
          color = `rgba(${brightness},${brightness},${brightness + 20},${alpha})`;
        } else {
          color = p.color;
        }

        const dist = Math.hypot(mouseX - p.x, mouseY - p.y);
        if (dist < p.drawSize + 6) {
          hoverName = p.displayName;
          hoverX = p.x;
          hoverY = p.y;
          p.drawSize = Math.max(p.drawSize * 2.5, 5);
        }

        ctx.globalAlpha = p.isLurker ? 1 : alpha;
        ctx.shadowBlur = 0;

        if (!p.isLurker && (p.isMod || p.isSub || p.isStreamer)) {
          ctx.shadowBlur = 6;
          ctx.shadowColor = color;
        }

        ctx.beginPath();
        ctx.arc(p.x, p.y, p.drawSize, 0, Math.PI * 2);
        ctx.fillStyle = color;
        ctx.fill();
      });
      ctx.globalAlpha = 1;
      ctx.shadowBlur = 0;

      // Draw Avatar on top
      ctx.save();
      ctx.beginPath();
      ctx.arc(cx, cy, 26, 0, Math.PI * 2);
      ctx.closePath();
      ctx.shadowColor = '#9147ff';
      ctx.shadowBlur = 24;
      ctx.strokeStyle = 'rgba(145, 71, 255, 0.9)';
      ctx.lineWidth = 2.5;
      ctx.stroke();
      ctx.shadowBlur = 0;
      ctx.clip();
      if (avatarRef.current) {
        ctx.drawImage(avatarRef.current, cx - 26, cy - 26, 52, 52);
      } else {
        ctx.fillStyle = '#6441A5';
        ctx.fill();
      }
      ctx.restore();

      // Hover tooltip
      if (hoverName) {
        ctx.shadowBlur = 0;
        ctx.globalAlpha = 1;
        ctx.font = 'bold 11px Inter, sans-serif';
        const tw = ctx.measureText(hoverName).width;
        const tx = Math.min(hoverX + 12, width - tw - 20);
        const ty = hoverY - 30 < 5 ? hoverY + 20 : hoverY - 30;
        ctx.fillStyle = 'rgba(18,18,24,0.92)';
        ctx.beginPath();
        if (ctx.roundRect) ctx.roundRect(tx - 4, ty, tw + 16, 22, 5);
        else ctx.rect(tx - 4, ty, tw + 16, 22);
        ctx.fill();
        ctx.strokeStyle = 'rgba(145,71,255,0.5)';
        ctx.lineWidth = 1;
        ctx.stroke();
        ctx.fillStyle = '#efeff1';
        ctx.fillText(hoverName, tx + 4, ty + 15);
      }

      animationId = requestAnimationFrame(animate);
    };

    animate();

    return () => {
      cancelAnimationFrame(animationId);
      canvas.removeEventListener('mousemove', handleMouseMove);
      canvas.removeEventListener('mouseleave', handleMouseLeave);
      window.removeEventListener('resize', resize);
    };
  }, []);

  return (
    <div ref={containerRef} style={{ display: 'flex', flexDirection: 'column', width: '100%', position: 'relative' }}>
      <canvas ref={canvasRef} style={{ borderRadius: '8px', display: 'block', width: '100%' }} />
      <div style={{ position: 'absolute', bottom: '10px', right: '12px', fontSize: '11px', color: 'rgba(180,180,200,0.7)', display: 'flex', gap: '14px' }}>
        <span><span style={{ display: 'inline-block', width: '6px', height: '6px', background: 'rgba(200,200,220,0.5)', borderRadius: '50%', marginRight: '4px'}}></span>Зрители</span>
        <span><span style={{ display: 'inline-block', width: '6px', height: '6px', background: '#c8c8d8', borderRadius: '50%', marginRight: '4px'}}></span>Чатеры</span>
        <span><span style={{ display: 'inline-block', width: '6px', height: '6px', background: '#FF007F', borderRadius: '50%', marginRight: '4px'}}></span>Сабы</span>
        <span><span style={{ display: 'inline-block', width: '6px', height: '6px', background: '#00F5D4', borderRadius: '50%', marginRight: '4px'}}></span>Модеры</span>
      </div>
    </div>
  );
}

// Fallback to local port 3000 in development, or use VITE_API_URL if configured, otherwise same origin
const API_BASE = import.meta.env.VITE_API_URL || (import.meta.env.DEV ? 'http://localhost:3000' : '');
const TWITCH_CHANNEL = 'winx_prinx';

export default function App() {
  const [activeTab, setActiveTab] = useState('overview');
  const [streams, setStreams] = useState([]);
  const [selectedStreamId, setSelectedStreamId] = useState('all');
  const [auth, setAuth] = useState({ loggedIn: false, user: null });
  const [twitchConfigured, setTwitchConfigured] = useState(true);
  const [loading, setLoading] = useState(true);
  const [serverStatus, setServerStatus] = useState('connecting'); // 'connecting' | 'online' | 'offline'

  // Statistics State
  const [chatters, setChatters] = useState([]);
  const [chattersSearch, setChattersSearch] = useState('');
  const [voiceWords, setVoiceWords] = useState([]);
  const [chatWords, setChatWords] = useState([]);
  const [wordType, setWordType] = useState('voice'); // 'voice' or 'chat'
  const [activityData, setActivityData] = useState([]);
  const [modActions, setModActions] = useState([]);
  const [modSummary, setModSummary] = useState([]);
  
  // RPG Mod Profiles
  const [modProfiles, setModProfiles] = useState([]);
  const [selectedMod, setSelectedMod] = useState(null);
  const [syncingVods, setSyncingVods] = useState(false);
  const [isRacing, setIsRacing] = useState(false);

  // Admin State
  const [adminStats, setAdminStats] = useState(null);
  const [loadingAdminStats, setLoadingAdminStats] = useState(false);
  const [cleaningStreams, setCleaningStreams] = useState(false);
  const [adminSelectedStreamId, setAdminSelectedStreamId] = useState('');
  const [editTitle, setEditTitle] = useState('');
  const [editCategory, setEditCategory] = useState('');
  const [savingMetadata, setSavingMetadata] = useState(false);
  const [deletingStream, setDeletingStream] = useState(false);

  // Auto-refresh timer for live stream
  const pollIntervalRef = useRef(null);
  const raceIntervalRef = useRef(null);

  const fetchAdminStats = async () => {
    setLoadingAdminStats(true);
    try {
      const res = await fetch(`${API_BASE}/api/admin/stats`, { credentials: 'include' });
      if (res.status === 200) {
        const data = await res.json();
        if (data.success) {
          setAdminStats(data.stats);
        }
      }
    } catch (e) {
      console.error('Error fetching admin stats:', e);
    } finally {
      setLoadingAdminStats(false);
    }
  };

  // Fetch admin stats when switching to admin tab
  useEffect(() => {
    if (activeTab === 'admin') {
      fetchAdminStats();
      if (streams && streams.length > 0 && !adminSelectedStreamId) {
        setAdminSelectedStreamId(streams[0].id.toString());
      }
    }
  }, [activeTab, streams]);

  // Sync edit fields when admin selection changes
  useEffect(() => {
    if (adminSelectedStreamId) {
      const stream = streams.find(s => s.id === parseInt(adminSelectedStreamId));
      if (stream) {
        setEditTitle(stream.title || '');
        setEditCategory(stream.category || '');
      } else {
        setEditTitle('');
        setEditCategory('');
      }
    } else {
      setEditTitle('');
      setEditCategory('');
    }
  }, [adminSelectedStreamId, streams]);

  const checkServerHealth = async () => {
    try {
      const controller = new AbortController();
      const timeoutId = setTimeout(() => controller.abort(), 6000);
      
      const res = await fetch(`${API_BASE}/api/health`, { signal: controller.signal });
      clearTimeout(timeoutId);
      
      if (res.ok) {
        setServerStatus('online');
        return true;
      }
    } catch (e) {
      console.warn('Backend connection healthcheck failed:', e);
    }
    return false;
  };

  const pingServer = async () => {
    const ok = await checkServerHealth();
    if (ok) {
      fetchAuthStatus();
      fetchStreams();
    } else {
      setServerStatus('offline');
    }
  };

  // Check Auth on Mount & Server connection status loop
  useEffect(() => {
    let active = true;
    let timer = null;

    const runPingLoop = async () => {
      if (!active) return;
      const ok = await checkServerHealth();
      if (active) {
        if (ok) {
          fetchAuthStatus();
          fetchStreams();
          timer = setTimeout(runPingLoop, 30000);
        } else {
          setServerStatus('offline');
          timer = setTimeout(runPingLoop, 6000);
        }
      }
    };

    runPingLoop();

    return () => {
      active = false;
      if (timer) clearTimeout(timer);
    };
  }, []);

  // Fetch stats when selected stream changes
  useEffect(() => {
    if (selectedStreamId && serverStatus === 'online') {
      fetchAllStats();
      
      // Setup polling if the selected stream is live (end_time is null)
      const selectedStream = streams.find(s => s.id === parseInt(selectedStreamId));
      const isLive = selectedStream && !selectedStream.end_time;

      if (isLive || selectedStreamId === 'all') {
        startPolling();
      } else {
        stopPolling();
      }
    }
    return () => stopPolling();
  }, [selectedStreamId, streams, serverStatus]);

  const startPolling = () => {
    stopPolling();
    pollIntervalRef.current = setInterval(() => {
      fetchAllStats(false); // poll silently without loading spinner
    }, 15000); // refresh every 15s
  };

  const stopPolling = () => {
    if (pollIntervalRef.current) {
      clearInterval(pollIntervalRef.current);
      pollIntervalRef.current = null;
    }
  };

  // Optimize polling based on page visibility (pause if tab is backgrounded)
  useEffect(() => {
    const handleVisibilityChange = () => {
      if (document.visibilityState === 'hidden') {
        stopPolling();
      } else if (document.visibilityState === 'visible' && selectedStreamId && serverStatus === 'online') {
        fetchAllStats(false);
        const selectedStream = streams.find(s => s.id === parseInt(selectedStreamId));
        const isLive = selectedStream && !selectedStream.end_time;
        if (isLive || selectedStreamId === 'all') {
          startPolling();
        }
      }
    };

    document.addEventListener('visibilitychange', handleVisibilityChange);
    return () => {
      document.removeEventListener('visibilitychange', handleVisibilityChange);
    };
  }, [selectedStreamId, streams, serverStatus]);

  const fetchAuthStatus = async () => {
    try {
      const res = await fetch(`${API_BASE}/api/auth/status`, { credentials: 'include' });
      const data = await res.json();
      setTwitchConfigured(data.twitchConfigured !== false);
      if (data.loggedIn) {
        setAuth({ loggedIn: true, user: data.user });
      } else {
        setAuth({ loggedIn: false, user: null });
      }
    } catch (e) {
      console.error('Auth check failed:', e);
    }
  };

  const fetchStreams = async () => {
    try {
      const res = await fetch(`${API_BASE}/api/streams`);
      const data = await res.json();
      setStreams(data);
    } catch (e) {
      console.error('Failed to fetch streams:', e);
    }
  };

  const getUrl = (endpoint, params = {}) => {
    if (selectedStreamId !== 'all') {
      params.stream_id = selectedStreamId;
    }
    const query = new URLSearchParams(params).toString();
    return `${API_BASE}${endpoint}${query ? '?' + query : ''}`;
  };

  const fetchAllStats = async (showSpinner = true) => {
    if (showSpinner) setLoading(true);

    try {
      // 1. Top Chatters
      const chattersRes = await fetch(getUrl('/api/stats/chatters'));
      const chattersData = await chattersRes.json();
      setChatters(Array.isArray(chattersData) ? chattersData : []);

      // 2. Spoken voice words
      const voiceRes = await fetch(getUrl('/api/stats/words', { type: 'voice', limit: 60 }));
      const voiceData = await voiceRes.json();
      setVoiceWords(Array.isArray(voiceData) ? voiceData : []);

      // 3. Written chat words by streamer
      const chatWordsRes = await fetch(getUrl('/api/stats/words', { type: 'chat', limit: 60 }));
      const chatWordsData = await chatWordsRes.json();
      setChatWords(Array.isArray(chatWordsData) ? chatWordsData : []);

      // 4. Activity chart (only if stream is selected)
      if (selectedStreamId !== 'all') {
        const activityRes = await fetch(getUrl('/api/stats/activity'));
        const activityData = await activityRes.json();
        setActivityData(Array.isArray(activityData) ? activityData : []);
      } else {
        setActivityData([]);
      }

      // 5. Fetch moderator actions if authorized
      if (!twitchConfigured || (auth.loggedIn && (auth.user?.role === 'streamer' || auth.user?.role === 'moderator' || auth.user?.role === 'admin'))) {
        const modRes = await fetch(getUrl('/api/stats/moderators', { limit: 100 }), { credentials: 'include' });
        const modData = await modRes.json();
        setModActions(Array.isArray(modData) ? modData : []);

        const summaryRes = await fetch(getUrl('/api/stats/moderators/summary'), { credentials: 'include' });
        const summaryData = await summaryRes.json();
        setModSummary(Array.isArray(summaryData) ? summaryData : []);

        const profilesRes = await fetch(getUrl('/api/stats/moderators/profiles'), { credentials: 'include' });
        const profilesData = await profilesRes.json();
        setModProfiles(Array.isArray(profilesData) ? profilesData : []);
        if (profilesData && profilesData.length > 0) {
          setSelectedMod(prev => prev ? profilesData.find(p => p.moderator === prev.moderator) || profilesData[0] : profilesData[0]);
        }
      }
    } catch (e) {
      console.error('Error fetching statistics:', e);
    } finally {
      if (showSpinner) setLoading(false);
    }
  };

  const startGraphRace = () => {
    if (activityData.length === 0) return;
    if (raceIntervalRef.current) clearInterval(raceIntervalRef.current);
    
    const originalData = [...activityData];
    setActivityData([]);
    setIsRacing(true);
    
    let currentIndex = 0;
    raceIntervalRef.current = setInterval(() => {
      if (currentIndex >= originalData.length) {
        clearInterval(raceIntervalRef.current);
        setIsRacing(false);
        return;
      }
      setActivityData(prev => [...prev, originalData[currentIndex]]);
      currentIndex++;
    }, 150);
  };

  const handleLogin = () => {
    window.location.href = `${API_BASE}/api/auth/twitch`;
  };

  const handleLogout = async () => {
    try {
      await fetch(`${API_BASE}/api/auth/logout`, { credentials: 'include' });
      setAuth({ loggedIn: false, user: null });
      setModActions([]);
      setModSummary([]);
      setActiveTab('overview');
    } catch (e) {
      console.error('Logout failed:', e);
    }
  };

  const activeStream = streams.find(s => !s.end_time);

  // Helper to format dates
  const formatDate = (isoString) => {
    if (!isoString) return '';
    const date = new Date(isoString);
    return date.toLocaleString('ru-RU', { 
      day: 'numeric', 
      month: 'short', 
      hour: '2-digit', 
      minute: '2-digit' 
    });
  };

  // KPI Metrics Calculation
  const totalMessages = chatters.reduce((acc, curr) => acc + curr.message_count, 0);
  const totalUniqueChatters = chatters.length;
  const topChatter = chatters[0]?.display_name || '—';
  const totalVoiceWords = voiceWords.reduce((acc, curr) => acc + curr.word_count, 0);
  const totalModActionsCount = modActions.length;

  const statsSummary = {
    messages: totalMessages,
    uniqueChatters: totalUniqueChatters,
    mostActiveChatter: topChatter,
    voiceWordsCount: totalVoiceWords,
    modActionsCount: totalModActionsCount
  };

  // Chart Setup
  const chartLabels = activityData.map(d => {
    const date = new Date(d.timestamp);
    return date.toLocaleTimeString('ru-RU', { hour: '2-digit', minute: '2-digit' });
  });

  const chartDataConfig = {
    labels: chartLabels.length > 0 ? chartLabels : ['Нет данных'],
    datasets: [
      {
        fill: true,
        label: 'Сообщений в 5 мин',
        data: activityData.map(d => d.message_count),
        borderColor: '#9146FF',
        backgroundColor: 'rgba(145, 70, 255, 0.1)',
        tension: 0.4,
        pointBackgroundColor: '#9146FF',
        pointBorderColor: '#fff',
        pointHoverBackgroundColor: '#fff',
        pointHoverBorderColor: '#9146FF',
      },
    ],
  };

  const chartOptions = {
    responsive: true,
    maintainAspectRatio: false,
    plugins: {
      legend: {
        display: false,
      },
      tooltip: {
        backgroundColor: '#18181B',
        borderColor: '#2F2F35',
        borderWidth: 1,
        titleColor: '#EFeff1',
        bodyColor: '#ADADB8',
        padding: 10,
        displayColors: false,
      }
    },
    scales: {
      x: {
        grid: {
          color: '#2F2F35',
        },
        ticks: {
          color: '#ADADB8',
          font: { size: 10 }
        }
      },
      y: {
        grid: {
          color: '#2F2F35',
        },
        ticks: {
          color: '#ADADB8',
          font: { size: 10 }
        }
      }
    }
  };

  return (
    <div className="app-container">
      {/* Header */}
      <header className="app-header">
        <div className="brand-section">
          <BarChart2 size={28} className="brand-logo" />
          <h1 className="brand-name">winx_prinx</h1>
          <span className="channel-tag">Analytics</span>

          {/* Live stream badge */}
          {activeStream ? (
            <div className="status-indicator" style={{ marginLeft: '1rem' }}>
              <span className="status-dot live"></span>
              <span style={{ color: '#ff0000', fontSize: '0.75rem' }}>В ЭФИРЕ</span>
            </div>
          ) : (
            <div className="status-indicator" style={{ marginLeft: '1rem' }}>
              <span className="status-dot offline"></span>
              <span style={{ color: 'var(--color-text-muted)', fontSize: '0.75rem' }}>ОФФЛАЙН</span>
            </div>
          )}

          {/* Stream Selector — compact, in header */}
          <div className="header-stream-selector">
            <select
              className="select-input select-input--compact"
              value={selectedStreamId}
              onChange={(e) => setSelectedStreamId(e.target.value)}
            >
              <option value="all">За всё время</option>
              {streams.map(s => (
                <option key={s.id} value={s.id}>
                  {s.title} ({formatDate(s.start_time)}{!s.end_time ? ' · Live' : ''})
                </option>
              ))}
            </select>
          </div>
        </div>

        <div className="header-controls">
          {/* Navigation Tabs */}
          <nav className="nav-tabs">
            <button 
              className={`tab-btn ${activeTab === 'overview' ? 'active' : ''}`}
              onClick={() => setActiveTab('overview')}
            >
              <Activity size={16} /> Обзор
            </button>
            <button 
              className={`tab-btn ${activeTab === 'chatters' ? 'active' : ''}`}
              onClick={() => setActiveTab('chatters')}
            >
              <Users size={16} /> Зрители
            </button>
            <button 
              className={`tab-btn ${activeTab === 'words' ? 'active' : ''}`}
              onClick={() => setActiveTab('words')}
            >
              <Mic size={16} /> Словарь частот
            </button>
            <button 
              className={`tab-btn ${activeTab === 'moderator' ? 'active' : ''}`}
              onClick={() => setActiveTab('moderator')}
            >
              <ShieldAlert size={16} /> Модерация
            </button>
            {(auth.user?.role === 'streamer' || auth.user?.role === 'admin' || !twitchConfigured) && (
              <button 
                className={`tab-btn ${activeTab === 'admin' ? 'active' : ''}`}
                onClick={() => setActiveTab('admin')}
              >
                <Settings size={16} /> Админка
              </button>
            )}
          </nav>

          {/* Refresh + User Profile */}
          <div className="user-profile">
            <button
              className="btn btn-refresh"
              onClick={() => { fetchStreams(); fetchAllStats(); }}
              disabled={loading}
              title="Обновить данные"
            >
              <RefreshCw size={14} className={loading ? 'spin' : ''} />
              Обновить
            </button>
            {!twitchConfigured ? (
              <span className="badge badge-mod" style={{ padding: '0.5rem 1rem', fontSize: '0.85rem', background: '#232329', border: '1px solid #2F2F35', color: '#00F5D4' }}>
                Локальный режим
              </span>
            ) : auth.loggedIn ? (
              <>
                <div className="user-info">
                  <div className="user-name">{auth.user.displayName}</div>
                  <div className="user-role">
                    {auth.user?.role === 'streamer' ? 'Стример' : auth.user?.role === 'admin' ? 'Админ' : auth.user?.role === 'moderator' ? 'Модератор' : 'Зритель'}
                  </div>
                </div>
                <button className="btn btn-secondary" onClick={handleLogout}>
                  <LogOut size={16} /> Выйти
                </button>
              </>
            ) : (
              <button className="btn" onClick={handleLogin}>
                <LogIn size={16} /> Войти через Twitch
              </button>
            )}
          </div>
        </div>
      </header>

      {/* Main Dashboard Panel */}
      <main className="dashboard-content">

        {serverStatus !== 'online' ? (
          <div className="connection-overlay-container" style={{
            display: 'flex',
            flexDirection: 'column',
            alignItems: 'center',
            justifyContent: 'center',
            minHeight: '60vh',
            padding: '2rem',
            textAlign: 'center',
            background: 'rgba(20, 20, 27, 0.4)',
            backdropFilter: 'blur(8px)',
            WebkitBackdropFilter: 'blur(8px)',
            borderRadius: 'var(--radius-lg)',
            border: '1px solid var(--color-border)',
            margin: '2rem auto',
            maxWidth: '600px',
            boxShadow: '0 8px 32px 0 rgba(0, 0, 0, 0.37)',
            animation: 'fadeIn 0.4s ease-out'
          }}>
            {serverStatus === 'connecting' ? (
              <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '1.5rem' }}>
                <div className="spinner" style={{
                  width: '50px',
                  height: '50px',
                  borderRadius: '50%',
                  border: '3px solid rgba(145, 70, 255, 0.1)',
                  borderTopColor: 'var(--color-brand)',
                  animation: 'spin 1s linear infinite'
                }}></div>
                <h2 style={{ fontSize: '1.4rem', fontWeight: 600, color: 'var(--color-text-main)', margin: 0 }}>
                  Подключение к серверу аналитики...
                </h2>
                <p style={{ color: 'var(--color-text-muted)', fontSize: '0.88rem', margin: 0, lineHeight: 1.6 }}>
                  Сервер бэкенда на Render автоматически засыпает после 15 минут неактивности. Пробуждение сервера занимает около 30–50 секунд. Пожалуйста, подождите.
                </p>
              </div>
            ) : (
              <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '1.5rem' }}>
                <div style={{
                  width: '60px',
                  height: '60px',
                  borderRadius: '50%',
                  backgroundColor: 'rgba(255, 73, 73, 0.1)',
                  border: '1px solid rgba(255, 73, 73, 0.2)',
                  display: 'flex',
                  alignItems: 'center',
                  justifyContent: 'center',
                  color: '#FF4949',
                  fontSize: '1.8rem'
                }}>⚠️</div>
                <h2 style={{ fontSize: '1.4rem', fontWeight: 600, color: 'var(--color-text-main)', margin: 0 }}>
                  Бэкенд недоступен
                </h2>
                <p style={{ color: 'var(--color-text-muted)', fontSize: '0.88rem', margin: 0, lineHeight: 1.6 }}>
                  Не удалось установить соединение с сервером. Возможно, сервер временно отключен, обновляется или ваш провайдер блокирует подключение.
                </p>
                <button 
                  className="btn btn-refresh" 
                  onClick={() => {
                    setServerStatus('connecting');
                    pingServer();
                  }}
                  style={{
                    padding: '0.6rem 1.5rem',
                    fontSize: '0.85rem',
                    backgroundColor: 'var(--color-brand)',
                    color: '#fff',
                    border: 'none',
                    borderRadius: 'var(--radius-md)',
                    cursor: 'pointer',
                    fontWeight: 600,
                    transition: 'background-color 0.2s',
                    marginTop: '0.5rem'
                  }}
                >
                  <RefreshCw size={14} style={{ marginRight: '8px' }} />
                  Повторить попытку
                </button>
              </div>
            )}
          </div>
        ) : loading ? (
          <div className="status-msg">
            <RefreshCw size={48} className="status-msg-icon spin" />
            <p>Загрузка аналитики...</p>
          </div>
        ) : (
          <>
            {/* OVERVIEW TAB */}
            {activeTab === 'overview' && (
              <div className="tab-content">
                {/* Stats row */}
                <div className="grid-4col" style={{ marginBottom: '2rem' }}>
                  <div className="stat-card" style={{ '--accent-color': 'var(--color-brand)' }}>
                    <div className="stat-card-inner">
                      <div style={{ minWidth: 0, flex: 1, marginRight: '0.5rem' }}>
                        <div className="stat-label">Сообщений в чате</div>
                        <div className="stat-value">{statsSummary.messages.toLocaleString()}</div>
                      </div>
                      <div className="stat-icon-wrapper"><MessageSquare size={22} style={{ color: 'var(--color-brand)' }} /></div>
                    </div>
                  </div>
                  <div className="stat-card" style={{ '--accent-color': 'var(--color-text-accent)' }}>
                    <div className="stat-card-inner">
                      <div style={{ minWidth: 0, flex: 1, marginRight: '0.5rem' }}>
                        <div className="stat-label">Уникальных зрителей</div>
                        <div className="stat-value">{statsSummary.uniqueChatters.toLocaleString()}</div>
                      </div>
                      <div className="stat-icon-wrapper"><Users size={22} style={{ color: 'var(--color-text-accent)' }} /></div>
                    </div>
                  </div>
                  <div className="stat-card" style={{ '--accent-color': '#ff007f' }}>
                    <div className="stat-card-inner">
                      <div style={{ minWidth: 0, flex: 1, marginRight: '0.5rem' }}>
                        <div className="stat-label">Самый активный чатер</div>
                        <div 
                          className="stat-value" 
                          title={statsSummary.mostActiveChatter || ''}
                          style={{ 
                            fontSize: (statsSummary.mostActiveChatter || '').length > 15 ? '1.05rem' : '1.25rem', 
                            letterSpacing: '-0.02em', 
                            overflow: 'hidden', 
                            textOverflow: 'ellipsis', 
                            whiteSpace: 'nowrap' 
                          }}
                        >
                          {statsSummary.mostActiveChatter || '—'}
                        </div>
                      </div>
                      <div className="stat-icon-wrapper"><Users size={22} style={{ color: '#ff007f' }} /></div>
                    </div>
                  </div>
                  <div className="stat-card" style={{ '--accent-color': '#00f5d4' }}>
                    <div className="stat-card-inner">
                      <div style={{ minWidth: 0, flex: 1, marginRight: '0.5rem' }}>
                        <div className="stat-label">Распознано слов (голос)</div>
                        <div className="stat-value">{statsSummary.voiceWordsCount.toLocaleString()}</div>
                      </div>
                      <div className="stat-icon-wrapper"><Mic size={22} style={{ color: '#00f5d4' }} /></div>
                    </div>
                  </div>
                </div>

                <div className="grid-2col" style={{ gridTemplateColumns: '2fr 1fr' }}>
                  {/* Activity graph */}
                  <div className="panel">
                    <div className="panel-header">
                      <h3 className="panel-title"><Activity size={20} /> Активность чата</h3>
                      <div style={{ display: 'flex', gap: '0.75rem', alignItems: 'center' }}>
                        <span style={{ fontSize: '0.8rem', color: 'var(--color-text-muted)' }}>выберите конкретный стрим для графика</span>
                        {activityData.length > 0 && (
                          <button 
                            className="btn btn-secondary" 
                            style={{ fontSize: '0.75rem', padding: '0.3rem 0.6rem' }} 
                            onClick={startGraphRace}
                            disabled={isRacing}
                          >
                            <Activity size={12} className={isRacing ? "pulse" : ""} /> {isRacing ? 'Гонка идет...' : 'Запустить гонку'}
                          </button>
                        )}
                      </div>
                    </div>
                    {selectedStreamId === 'all' ? (
                      <div className="status-msg" style={{ height: '300px' }}>
                        <BarChart2 size={36} className="status-msg-icon" />
                        <p>Для просмотра временного графика выберите конкретный стрим в верхнем меню</p>
                      </div>
                    ) : activityData.length === 0 ? (
                      <div className="status-msg" style={{ height: '300px' }}>
                        <MessageSquare size={36} className="status-msg-icon" />
                        <p>В этом стриме пока не было сообщений</p>
                      </div>
                    ) : (
                      <div className="chart-container">
                        <Line data={chartDataConfig} options={chartOptions} />
                      </div>
                    )}
                  </div>

                  {/* Quick Words list */}
                  <div className="panel">
                    <div className="panel-header">
                      <h3 className="panel-title">
                        <Mic size={18} style={{ color: 'var(--color-text-accent)' }} /> Голос стримера (Топ)
                      </h3>
                    </div>
                    {voiceWords.length === 0 ? (
                      <div className="status-msg" style={{ height: '300px', padding: '1rem' }}>
                        <Mic size={28} className="status-msg-icon" />
                        <p>Слова пока не распознаны. Запустите local_worker на ПК.</p>
                      </div>
                    ) : (
                      <div style={{ display: 'flex', flexDirection: 'column', gap: '0.75rem', maxHeight: '320px', overflowY: 'auto', paddingRight: '4px' }}>
                        {voiceWords.slice(0, 7).map((w, idx) => (
                          <div key={idx} style={{ display: 'flex', justifyContent: 'space-between', padding: '0.5rem 0.75rem', backgroundColor: 'var(--color-bg-base)', border: '1px solid var(--color-border)', borderRadius: '6px', alignItems: 'center' }}>
                            <span style={{ fontWeight: 600, color: 'var(--color-text-main)' }}>#{idx+1} {w.word}</span>
                            <span className="badge badge-streamer">{w.word_count} раз</span>
                          </div>
                        ))}
                      </div>
                    )}
                  </div>
                </div>
              </div>
            )}

            {/* CHATTERS TAB */}
            {activeTab === 'chatters' && (
              <div className="grid-2col tab-content" style={{ gridTemplateColumns: 'repeat(auto-fit, minmax(340px, 1fr))', gap: '1.5rem', alignItems: 'start' }}>
                <div className="panel">
                  <div className="panel-header">
                    <h3 className="panel-title"><Users size={20} /> Орбита зрителей</h3>
                  </div>
                  <div style={{ display: 'flex', justifyContent: 'center', padding: '1rem 0' }}>
                    <ChatterOrbit chatters={chatters} />
                  </div>
                </div>

                <div className="panel">
                  <div className="panel-header">
                    <h3 className="panel-title"><Users size={20} /> Лидеры чата по активности</h3>
                    <div className="search-container">
                      <Search size={16} className="search-icon" />
                      <input 
                        type="text" 
                        className="search-input" 
                        placeholder="Поиск зрителя..."
                        value={chattersSearch}
                        onChange={(e) => setChattersSearch(e.target.value)}
                      />
                    </div>
                  </div>

                  {chatters.length === 0 ? (
                    <div className="status-msg">
                      <Users size={40} className="status-msg-icon" />
                      <p>Нет данных о зрителях для этого периода</p>
                    </div>
                  ) : (
                    <div className="table-wrapper">
                      <table className="data-table">
                        <thead>
                          <tr>
                            <th>Место</th>
                            <th>Никнейм</th>
                            <th>Роли</th>
                            <th>Сообщений</th>
                          </tr>
                        </thead>
                        <tbody>
                          {chatters
                            .filter(c => {
                              const disp = c.display_name || c.username || '';
                              const user = c.username || '';
                              return disp.toLowerCase().includes(chattersSearch.toLowerCase()) || 
                                     user.toLowerCase().includes(chattersSearch.toLowerCase());
                            })
                            .map((c, idx) => (
                              <tr key={idx} className="chatter-row">
                                <td style={{ fontWeight: 700, width: '80px', color: idx < 3 ? 'var(--color-brand)' : 'var(--color-text-muted)' }}>
                                  #{idx + 1}
                                </td>
                                <td style={{ fontWeight: 600 }}>{c.display_name || c.username || '—'}</td>
                                <td>
                                  <div style={{ display: 'flex', gap: '0.4rem' }}>
                                    {(c.username || '').toLowerCase() === TWITCH_CHANNEL && (
                                      <span className="badge badge-streamer">Стример</span>
                                    )}
                                    {c.is_mod ? <span className="badge badge-mod">Мод</span> : null}
                                    {c.is_sub ? <span className="badge badge-sub">Саб</span> : null}
                                  </div>
                                </td>
                                <td style={{ fontWeight: 700, color: 'var(--color-text-accent)' }}>
                                  {c.message_count.toLocaleString()}
                                </td>
                              </tr>
                            ))}
                        </tbody>
                      </table>
                    </div>
                  )}
                </div>
              </div>
            )}

            {/* WORDS TAB */}
            {activeTab === 'words' && (
              <div className="panel tab-content">
                <div className="panel-header">
                  <h3 className="panel-title"><Mic size={20} /> Частотный словарь</h3>
                  
                  <div className="nav-tabs" style={{ background: 'var(--color-bg-base)', padding: '0.2rem', borderRadius: '8px', border: '1px solid var(--color-border)' }}>
                    <button 
                      className={`tab-btn ${wordType === 'voice' ? 'active' : ''}`}
                      onClick={() => setWordType('voice')}
                      style={{ fontSize: '0.8rem', padding: '0.4rem 0.8rem' }}
                    >
                      <Volume2 size={14} /> Из Голоса (Whisper)
                    </button>
                    <button 
                      className={`tab-btn ${wordType === 'chat' ? 'active' : ''}`}
                      onClick={() => setWordType('chat')}
                      style={{ fontSize: '0.8rem', padding: '0.4rem 0.8rem' }}
                    >
                      <MessageSquare size={14} /> Из Чата (Текстом)
                    </button>
                  </div>
                </div>

                <p style={{ color: 'var(--color-text-muted)', fontSize: '0.85rem', marginBottom: '1.5rem', marginTop: '-0.75rem' }}>
                  {wordType === 'voice' 
                    ? 'Слова, которые стример произнес в микрофон (распознанные через Whisper на локальном ПК).' 
                    : 'Слова, которые зрители написали в текстовый чат Twitch.'}
                </p>

                {(() => {
                  const currentWordsList = wordType === 'voice' 
                    ? (Array.isArray(voiceWords) ? voiceWords : []) 
                    : (Array.isArray(chatWords) ? chatWords : []);
                  if (currentWordsList.length === 0) {
                    return (
                      <div className="status-msg">
                        <Mic size={40} className="status-msg-icon" />
                        <p>Нет собранных слов для выбранного стрима</p>
                      </div>
                    );
                  }
                                    const counts = currentWordsList.map(x => x.word_count);
                  const maxCount = Math.max(...counts, 1);
                  const minCount = Math.min(...counts, 1);

                  // Helper for Russian pluralization
                  const getRussianPlural = (count) => {
                    const lastDigit = count % 10;
                    const lastTwoDigits = count % 100;
                    if (lastTwoDigits >= 11 && lastTwoDigits <= 19) {
                      return 'раз';
                    }
                    if (lastDigit === 1) {
                      return 'раз';
                    }
                    if (lastDigit >= 2 && lastDigit <= 4) {
                      return 'раза';
                    }
                    return 'раз';
                  };

                  // Color assignment based on word frequency: purple gradient
                  const getWordColor = (count) => {
                    const scale = maxCount === minCount ? 1 : (count - minCount) / (maxCount - minCount);
                    // Scale saturation from 35% (desaturated/white-lavender) to 100% (saturated purple)
                    const sat = Math.round(35 + scale * 65);
                    // Scale lightness from 92% (light/white-ish) to 60% (vivid deep purple)
                    const light = Math.round(92 - scale * 32);
                    return `hsl(265, ${sat}%, ${light}%)`;
                  };

                  // Layout calculations with collision avoidance on stretched elliptical spiral
                  const placedBoxes = [];
                  const laidOutWords = [];
                  
                  const stretchX = 2.8; 
                  const stretchY = 1.0;
                  const paddingX = 12; 
                  const paddingY = 8; 
                  const remToPx = 16;

                  // Identify center group: words with count within 500 of the max count,
                  // but ONLY if the top count is >= 500. Also cap center group size to at most 3 words.
                  const centerGroupWords = currentWordsList.filter((w, idx) => 
                    idx === 0 || (maxCount >= 500 && (maxCount - w.word_count) < 500 && idx < 3)
                  );
                  const otherWordsList = currentWordsList.filter((w, idx) => 
                    !(idx === 0 || (maxCount >= 500 && (maxCount - w.word_count) < 500 && idx < 3))
                  );
                  
                  const maxOtherCount = otherWordsList.length > 0 ? Math.max(...otherWordsList.map(x => x.word_count)) : 1;
                  const minOtherCount = otherWordsList.length > 0 ? Math.min(...otherWordsList.map(x => x.word_count)) : 1;
                  const minCenterCount = Math.min(...centerGroupWords.map(x => x.word_count));

                  // Function to estimate word width factor based on wide/narrow letters
                  const getWordWidthFactor = (word) => {
                    let factor = 0;
                    const wideChars = /[мжшщыюяwm]/i;
                    const narrowChars = /[ilj1!|т]/i;
                    for (const char of word) {
                      if (wideChars.test(char)) {
                        factor += 0.75;
                      } else if (narrowChars.test(char)) {
                        factor += 0.35;
                      } else {
                        factor += 0.55;
                      }
                    }
                    return factor;
                  };

                  for (let i = 0; i < currentWordsList.length; i++) {
                    const w = currentWordsList[i];
                    const isCenterGroup = i === 0 || (maxCount >= 500 && (maxCount - w.word_count) < 500 && i < 3);
                    
                    let fontSize;
                    let fontWeight;
                    let scaleValue = 0;

                    if (isCenterGroup) {
                      // Scale font size within center group: ranges from 4.5rem to 6.2rem
                      const centerScale = maxCount === minCenterCount ? 1 : (w.word_count - minCenterCount) / (maxCount - minCenterCount);
                      fontSize = 4.5 + centerScale * 1.7;
                      fontWeight = '900';
                      scaleValue = centerScale;
                    } else {
                      // Scale font size within other words: ranges from 1.1rem to 3.2rem
                      const scale = maxOtherCount === minOtherCount ? 1 : (w.word_count - minOtherCount) / (maxOtherCount - minOtherCount);
                      scaleValue = Math.pow(scale, 1.4);
                      fontSize = 1.1 + scaleValue * 2.1;
                      fontWeight = fontSize > 2.0 ? '700' : (fontSize > 1.4 ? '600' : '500');
                    }
                    
                    // Precise width calculation based on custom width factors
                    const wordWidth = fontSize * getWordWidthFactor(w.word) * remToPx;
                    const wordHeight = fontSize * 1.1 * remToPx;
                    
                    let x = 0;
                    let y = 0;
                    
                    // Generate a stable hash for the word to randomize angle and jitter
                    let hash = 0;
                    for (let j = 0; j < w.word.length; j++) {
                      hash = w.word.charCodeAt(j) + ((hash << 5) - hash);
                    }
                    hash = Math.abs(hash);

                    // Search for position starting from r = 0.
                    // Since center group words are processed first, they cluster tightly around (0,0).
                    let found = false;
                    const rStep = 1.1; 
                    
                    for (let attempt = 0; attempt < 1200; attempt++) {
                      const startAngle = (hash % 100) * 0.06283; // 0 to 2*PI
                      const angle = startAngle + attempt * 0.15;
                      const r = (i === 0 && attempt === 0) ? 0 : (45 + rStep * attempt);
                      
                      x = r * Math.cos(angle) * stretchX;
                      y = r * Math.sin(angle) * stretchY;
                      
                      // Add coordinate noise/jitter (except for the absolute top word at the center)
                      if (r > 0) {
                        x += Math.sin(hash * 0.5 + attempt) * 6;
                        y += Math.cos(hash * 0.8 + attempt) * 4;
                      }
                      
                      let collision = false;
                      for (const box of placedBoxes) {
                        const halfW1 = wordWidth / 2;
                        const halfH1 = wordHeight / 2;
                        const halfW2 = box.w / 2;
                        const halfH2 = box.h / 2;
                        
                        if (Math.abs(x - box.x) < (halfW1 + halfW2 + paddingX) &&
                            Math.abs(y - box.y) < (halfH1 + halfH2 + paddingY)) {
                          collision = true;
                          break;
                        }
                      }
                      
                      if (!collision) {
                        found = true;
                        break;
                      }
                    }
                    
                    placedBoxes.push({ x: x, y: y, w: wordWidth, h: wordHeight });
                    
                    const color = getWordColor(w.word_count);
                    
                    // Floating parameters
                    const duration = 4.5 + (i % 3) + (i % 4) * 0.4; // 4.5s to 8.5s
                    const delay = -((i * 1.3) % 7); // negative delay to start asynchronously
                    const amount = 3 + (i % 4); // 3px to 6px float amount
                    
                    laidOutWords.push({
                      word: w.word,
                      count: w.word_count,
                      x: Math.round(x),
                      y: Math.round(y),
                      fontSize: `${fontSize}rem`,
                      fontWeight: fontWeight,
                      color: color,
                      scale: scaleValue,
                      isCenterGroup: isCenterGroup,
                      duration: `${duration}s`,
                      delay: `${delay}s`,
                      amount: `${amount}px`
                    });
                  }

                  return (
                    <div className="word-galaxy-container">
                      {laidOutWords.map((w, idx) => (
                        <div
                          key={idx}
                          className="word-galaxy-tag"
                          style={{
                            '--x': `${w.x}px`,
                            '--y': `${w.y}px`,
                            '--float-duration': w.duration,
                            '--float-delay': w.delay,
                            '--float-amount': w.amount,
                            fontSize: w.fontSize,
                            fontWeight: w.fontWeight,
                            color: w.color,
                            opacity: 0.95, // High opacity so purple colors are bright and vivid
                            zIndex: w.isCenterGroup ? 25 : Math.round(10 + w.scale * 15)
                          }}
                        >
                          {w.word}
                          <div className="word-tooltip">
                            {w.count} {getRussianPlural(w.count)}
                          </div>
                        </div>
                      ))}
                    </div>
                  );
                })()}
              </div>
            )}

            {/* ADMIN TAB */}
            {activeTab === 'admin' && (
              <div className="tab-content">
                        <h2 style={{ fontSize: '1.5rem', fontWeight: 700, marginBottom: '1.5rem', display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
                          <Settings size={24} style={{ color: 'var(--color-brand)' }} /> Панель администратора
                        </h2>

                        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(320px, 1fr))', gap: '1.5rem', marginBottom: '2rem' }}>
                          
                          {/* Left: Stream management */}
                          <div className="panel" style={{ display: 'flex', flexDirection: 'column', gap: '1.25rem' }}>
                            <div className="panel-header">
                              <h3 className="panel-title">Управление стримами</h3>
                            </div>

                            <div style={{ display: 'flex', flexDirection: 'column', gap: '0.75rem' }}>
                              <label style={{ fontSize: '0.85rem', fontWeight: 600, color: 'var(--color-text-muted)' }}>Выбрать стрим для редактирования или удаления:</label>
                              <select 
                                className="dark-input"
                                value={adminSelectedStreamId}
                                onChange={(e) => setAdminSelectedStreamId(e.target.value)}
                              >
                                <option value="">-- Выберите стрим --</option>
                                {streams.map((stream) => (
                                  <option key={stream.id} value={stream.id}>
                                    {stream.title || 'Без названия'} ({new Date(stream.start_time).toLocaleDateString('ru-RU')} {new Date(stream.start_time).toLocaleTimeString('ru-RU', { hour: '2-digit', minute: '2-digit' })})
                                  </option>
                                ))}
                              </select>
                            </div>

                            {(() => {
                              const activeStream = streams.find(s => s.id === parseInt(adminSelectedStreamId));
                              if (!activeStream) return (
                                <div style={{ padding: '1.5rem', textAlign: 'center', color: 'var(--color-text-muted)', fontSize: '0.85rem' }}>
                                  Выберите стрим в выпадающем списке выше для выполнения действий.
                                </div>
                              );

                              const isLive = !activeStream.end_time;
                              const statusLabel = 
                                activeStream.backfill_status === 'completed' ? 'Импортирован полностью' :
                                activeStream.backfill_status === 'pending' ? 'В очереди воркера (ожидание)' :
                                activeStream.backfill_status === 'live' ? 'В эфире (live)' : activeStream.backfill_status;

                              const statusColor = 
                                activeStream.backfill_status === 'completed' ? 'var(--color-success, #00f2fe)' :
                                activeStream.backfill_status === 'pending' ? 'var(--color-warning, #f1c40f)' : 'var(--color-primary)';

                              return (
                                <div style={{ display: 'flex', flexDirection: 'column', gap: '1.25rem' }}>
                                  <div style={{ fontSize: '0.8rem', padding: '0.75rem', background: 'rgba(255,255,255,0.02)', borderRadius: '6px', border: '1px solid var(--color-border)' }}>
                                    <p style={{ margin: '0 0 0.4rem 0' }}><strong>ID сессии:</strong> {activeStream.id}</p>
                                    <p style={{ margin: '0 0 0.4rem 0' }}><strong>Статус импорта VOD:</strong> <span style={{ color: statusColor, fontWeight: 'bold' }}>{statusLabel}</span></p>
                                    <p style={{ margin: '0 0 0.4rem 0' }}><strong>Twitch VOD ID:</strong> {activeStream.twitch_vod_id || 'Отсутствует'}</p>
                                    <p style={{ margin: 0 }}><strong>Начало:</strong> {new Date(activeStream.start_time).toLocaleString('ru-RU')}</p>
                                  </div>

                                  {/* Edit Metadata */}
                                  <div style={{ display: 'flex', flexDirection: 'column', gap: '0.75rem', padding: '1rem', background: 'rgba(255,255,255,0.01)', borderRadius: '6px', border: '1px solid rgba(255,255,255,0.03)' }}>
                                    <h4 style={{ margin: 0, fontSize: '0.9rem', fontWeight: 600 }}>Редактирование названия / категории</h4>
                                    
                                    <div style={{ display: 'flex', flexDirection: 'column', gap: '0.4rem' }}>
                                      <label style={{ fontSize: '0.75rem', color: 'var(--color-text-muted)' }}>Название стрима:</label>
                                      <input 
                                        type="text"
                                        className="dark-input"
                                        value={editTitle}
                                        onChange={(e) => setEditTitle(e.target.value)}
                                      />
                                    </div>

                                    <div style={{ display: 'flex', flexDirection: 'column', gap: '0.4rem' }}>
                                      <label style={{ fontSize: '0.75rem', color: 'var(--color-text-muted)' }}>Категория (игра):</label>
                                      <input 
                                        type="text"
                                        className="dark-input"
                                        value={editCategory}
                                        onChange={(e) => setEditCategory(e.target.value)}
                                      />
                                    </div>

                                    <button 
                                      className="btn btn-secondary" 
                                      style={{ width: '100%', padding: '0.5rem', marginTop: '0.25rem' }}
                                      disabled={savingMetadata || !editTitle.trim()}
                                      onClick={async () => {
                                        setSavingMetadata(true);
                                        try {
                                          const res = await fetch(`${API_BASE}/api/streams/${activeStream.id}`, {
                                            method: 'PUT',
                                            headers: { 'Content-Type': 'application/json' },
                                            body: JSON.stringify({ title: editTitle, category: editCategory }),
                                            credentials: 'include'
                                          });
                                          const data = await res.json();
                                          if (data.success) {
                                            alert('Метаданные стрима успешно обновлены!');
                                            fetchStreams();
                                          } else {
                                            alert(`Ошибка: ${data.error}`);
                                          }
                                        } catch (e) {
                                          alert('Ошибка при обновлении метаданных.');
                                        } finally {
                                          setSavingMetadata(false);
                                        }
                                      }}
                                    >
                                      {savingMetadata ? 'Сохранение...' : 'Сохранить изменения'}
                                    </button>
                                  </div>

                                  {/* VOD Actions (Only if VOD is present) */}
                                  {activeStream.twitch_vod_id && (
                                    <div style={{ display: 'flex', flexDirection: 'column', gap: '0.5rem' }}>
                                      <h4 style={{ margin: 0, fontSize: '0.9rem', fontWeight: 600 }}>Действия импорта VOD:</h4>
                                      <div style={{ display: 'flex', gap: '0.5rem' }}>
                                        <button
                                          className="btn btn-secondary"
                                          style={{ flex: 1, fontSize: '0.75rem', padding: '0.5rem' }}
                                          onClick={async () => {
                                            if (!confirm(`Запустить заполнение пропусков для стрима "${activeStream.title}"? Воркер докачает пропущенный чат и Whisper-речь.`)) return;
                                            try {
                                              const res = await fetch(`${API_BASE}/api/streams/reset-backfill`, {
                                                method: 'POST',
                                                headers: { 'Content-Type': 'application/json' },
                                                body: JSON.stringify({ streamId: activeStream.id, mode: 'gap_fill' }),
                                                credentials: 'include'
                                              });
                                              const data = await res.json();
                                              if (data.success) {
                                                alert('Статус сброшен на "ожидание". Воркер скоро начнет дозаполнение!');
                                                fetchStreams();
                                              } else {
                                                alert(`Ошибка: ${data.error}`);
                                              }
                                            } catch (e) {
                                              alert('Ошибка при запуске дозаполнения VOD.');
                                            }
                                          }}
                                        >
                                          Заполнить пропуски VOD
                                        </button>
                                        <button
                                          className="btn btn-secondary"
                                          style={{ flex: 1, fontSize: '0.75rem', padding: '0.5rem' }}
                                          onClick={async () => {
                                            if (!confirm(`Внимание: это полностью удалит сохраненные сообщения чата и слова Whisper для стрима "${activeStream.title}" и заново запустит весь импорт VOD с 0-й секунды. Вы уверены?`)) return;
                                            try {
                                              const res = await fetch(`${API_BASE}/api/streams/reset-backfill`, {
                                                method: 'POST',
                                                headers: { 'Content-Type': 'application/json' },
                                                body: JSON.stringify({ streamId: activeStream.id, mode: 'full_rebuild' }),
                                                credentials: 'include'
                                              });
                                              const data = await res.json();
                                              if (data.success) {
                                                alert('Данные очищены. Стрим поставлен на полный переимпорт воркером!');
                                                fetchStreams();
                                              } else {
                                                alert(`Ошибка: ${data.error}`);
                                              }
                                            } catch (e) {
                                              alert('Ошибка при запуске переимпорта.');
                                            }
                                          }}
                                        >
                                          Полный переимпорт VOD
                                        </button>
                                      </div>
                                    </div>
                                  )}

                                  {/* Delete Button */}
                                  <div style={{ borderTop: '1px solid var(--color-border)', paddingTop: '1rem', marginTop: '0.5rem' }}>
                                    <button
                                      className="btn btn-danger"
                                      style={{ 
                                        width: '100%', 
                                        display: 'flex', 
                                        alignItems: 'center', 
                                        justifyContent: 'center', 
                                        gap: '0.4rem',
                                        backgroundColor: 'rgba(231, 76, 60, 0.15)',
                                        color: '#e74c3c',
                                        border: '1px solid rgba(231, 76, 60, 0.3)',
                                        borderRadius: '4px',
                                        cursor: 'pointer',
                                        padding: '0.6rem'
                                      }}
                                      disabled={deletingStream}
                                      onClick={async () => {
                                        if (!confirm(`ВНИМАНИЕ: Вы уверены, что хотите полностью УДАЛИТЬ стрим "${activeStream.title}"? Это действие сотрет всю связанную статистику (чат, слова Whisper, модерацию) из базы данных навсегда и безвозвратно!`)) return;
                                        if (!confirm(`ПОСЛЕДНЕЕ ПРЕДУПРЕЖДЕНИЕ: Вы действительно хотите стереть стрим ID ${activeStream.id} из базы? Восстановление невозможно.`)) return;
                                        
                                        setDeletingStream(true);
                                        try {
                                          const res = await fetch(`${API_BASE}/api/streams/${activeStream.id}`, {
                                            method: 'DELETE',
                                            credentials: 'include'
                                          });
                                          const data = await res.json();
                                          if (data.success) {
                                            alert('Стрим успешно удален из базы данных!');
                                            setAdminSelectedStreamId('');
                                            fetchStreams();
                                          } else {
                                            alert(`Ошибка: ${data.error}`);
                                          }
                                        } catch (e) {
                                          alert('Ошибка при удалении стрима.');
                                        } finally {
                                          setDeletingStream(false);
                                        }
                                      }}
                                    >
                                      <Trash2 size={16} /> Удалить стрим полностью
                                    </button>
                                  </div>
                                </div>
                              );
                            })()}
                          </div>

                          {/* Right: Global actions and Stats */}
                          <div style={{ display: 'flex', flexDirection: 'column', gap: '1.5rem' }}>
                            
                            {/* Global Actions Panel */}
                            <div className="panel">
                              <div className="panel-header">
                                <h3 className="panel-title">Глобальные действия</h3>
                              </div>
                              <div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>
                                
                                {/* Twitch VOD Sync */}
                                <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', paddingBottom: '0.75rem', borderBottom: '1px solid var(--color-border)' }}>
                                  <div>
                                    <h4 style={{ margin: 0, fontSize: '0.85rem', fontWeight: 600 }}>Синхронизация Twitch VOD</h4>
                                    <p style={{ margin: 0, fontSize: '0.7rem', color: 'var(--color-text-muted)' }}>Запросить последние 20 архивов из Twitch API.</p>
                                  </div>
                                  <button 
                                    className="btn btn-secondary"
                                    style={{ fontSize: '0.75rem', padding: '0.4rem 0.8rem' }}
                                    disabled={syncingVods}
                                    onClick={async () => {
                                      setSyncingVods(true);
                                      try {
                                        const res = await fetch(`${API_BASE}/api/streams/sync-vods`, { method: 'POST', credentials: 'include' });
                                        const data = await res.json();
                                        if (data.success) {
                                          alert(`Успешно импортировано ${data.count} стримов!`);
                                          fetchStreams();
                                        } else {
                                          alert(`Ошибка: ${data.error}`);
                                        }
                                      } catch (e) {
                                        alert('Ошибка при синхронизации VOD.');
                                      } finally {
                                        setSyncingVods(false);
                                      }
                                    }}
                                  >
                                    <RefreshCw size={12} className={syncingVods ? "spin" : ""} /> {syncingVods ? 'Синхронизация...' : 'Синхронизировать VOD'}
                                  </button>
                                </div>

                                {/* Database Cleanup */}
                                <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
                                  <div>
                                    <h4 style={{ margin: 0, fontSize: '0.85rem', fontWeight: 600 }}>Очистить пустые стримы</h4>
                                    <p style={{ margin: 0, fontSize: '0.7rem', color: 'var(--color-text-muted)' }}>Удалить сессии с 0 сообщениями и 0 слов.</p>
                                  </div>
                                  <button 
                                    className="btn btn-secondary"
                                    style={{ fontSize: '0.75rem', padding: '0.4rem 0.8rem' }}
                                    disabled={cleaningStreams}
                                    onClick={async () => {
                                      if (!confirm('Вы действительно хотите удалить все пустые стримы (в которых нет ни сообщений в чате, ни распознанных слов)? Это очистит тестовый мусор из списка.')) return;
                                      setCleaningStreams(true);
                                      try {
                                        const res = await fetch(`${API_BASE}/api/admin/cleanup`, { method: 'POST', credentials: 'include' });
                                        const data = await res.json();
                                        if (data.success) {
                                          alert(`Успешно очищено. Удалено пустых стримов: ${data.count}`);
                                          fetchStreams();
                                          fetchAdminStats();
                                        } else {
                                          alert(`Ошибка: ${data.error}`);
                                        }
                                      } catch (e) {
                                        alert('Ошибка при очистке стримов.');
                                      } finally {
                                        setCleaningStreams(false);
                                      }
                                    }}
                                  >
                                    Очистить пустые стримы
                                  </button>
                                </div>

                              </div>
                            </div>

                            {/* System Statistics Panel */}
                            <div className="panel">
                              <div className="panel-header">
                                <h3 className="panel-title">Системная статистика</h3>
                              </div>
                              
                              {loadingAdminStats || !adminStats ? (
                                <div style={{ padding: '1rem', textAlign: 'center', color: 'var(--color-text-muted)', fontSize: '0.85rem' }}>
                                  Загрузка статистики...
                                </div>
                              ) : (
                                <div style={{ display: 'flex', flexDirection: 'column', gap: '0.75rem', fontSize: '0.8rem' }}>
                                  <div style={{ display: 'flex', justifyContent: 'space-between', paddingBottom: '0.4rem', borderBottom: '1px solid rgba(255,255,255,0.03)' }}>
                                    <span style={{ color: 'var(--color-text-muted)' }}>Режим базы данных:</span>
                                    <strong style={{ color: 'var(--color-brand)' }}>{adminStats.dbMode.toUpperCase()}</strong>
                                  </div>
                                  {adminStats.dbMode === 'sqlite' && (
                                    <div style={{ display: 'flex', justifyContent: 'space-between', paddingBottom: '0.4rem', borderBottom: '1px solid rgba(255,255,255,0.03)' }}>
                                      <span style={{ color: 'var(--color-text-muted)' }}>Размер файла SQLite:</span>
                                      <strong>{adminStats.dbSizeMb} МБ</strong>
                                    </div>
                                  )}
                                  <div style={{ display: 'flex', justifyContent: 'space-between', paddingBottom: '0.4rem', borderBottom: '1px solid rgba(255,255,255,0.03)' }}>
                                    <span style={{ color: 'var(--color-text-muted)' }}>Всего стримов в базе:</span>
                                    <strong>{adminStats.totalStreams}</strong>
                                  </div>
                                  <div style={{ display: 'flex', justifyContent: 'space-between', paddingBottom: '0.4rem', borderBottom: '1px solid rgba(255,255,255,0.03)' }}>
                                    <span style={{ color: 'var(--color-text-muted)' }}>Всего сообщений чата:</span>
                                    <strong>{adminStats.totalMessages.toLocaleString()}</strong>
                                  </div>
                                  <div style={{ display: 'flex', justifyContent: 'space-between' }}>
                                    <span style={{ color: 'var(--color-text-muted)' }}>Всего голосовых слов:</span>
                                    <strong>{adminStats.totalVoiceWords.toLocaleString()}</strong>
                                  </div>
                                  
                                  <button 
                                    className="btn btn-secondary"
                                    style={{ width: '100%', fontSize: '0.75rem', padding: '0.4rem', marginTop: '0.5rem' }}
                                    onClick={fetchAdminStats}
                                  >
                                    Обновить статистику
                                  </button>
                                </div>
                              )}
                            </div>

                          </div>

                </div>
              </div>
            )}

            {/* MODERATOR TAB */}
            {activeTab === 'moderator' && (
              <div className="tab-content">
                {twitchConfigured && !auth.loggedIn ? (
                  <div className="login-overlay">
                    <div className="login-card">
                      <Lock size={48} style={{ color: 'var(--color-brand)', marginBottom: '1.5rem' }} />
                      <h2 className="login-title">Доступ Ограничен</h2>
                      <p className="login-description">
                        Лог действий модераторов и статистика банов/удалений доступны только стримеру и официальным модераторам канала **winx_prinx**. 
                        Пожалуйста, авторизуйтесь через Twitch для проверки прав.
                      </p>
                      <button className="btn" onClick={handleLogin}>
                        <LogIn size={16} /> Войти через Twitch
                      </button>
                    </div>
                  </div>
                ) : twitchConfigured && (auth.user?.role !== 'streamer' && auth.user?.role !== 'moderator' && auth.user?.role !== 'admin') ? (
                  <div className="status-msg">
                    <ShieldAlert size={48} className="status-msg-icon" />
                    <h2>Недостаточно прав</h2>
                    <p>Вы успешно вошли как <strong>{auth.user?.displayName}</strong>, но вы не являетесь модератором канала {TWITCH_CHANNEL}.</p>
                  </div>
                ) : (
                  <div>
                    {modProfiles.length <= 2 && (
                      <div style={{ background: 'rgba(145, 70, 255, 0.1)', border: '1px solid rgba(145, 70, 255, 0.3)', borderRadius: '8px', padding: '1rem', marginBottom: '1.5rem', display: 'flex', gap: '1rem', alignItems: 'center' }}>
                        <ShieldAlert size={24} style={{ color: 'var(--color-brand)' }} />
                        <div>
                          <h4 style={{ margin: '0 0 0.25rem 0', color: 'var(--color-text-main)', fontSize: '0.95rem' }}>Данные накапливаются</h4>
                          <p style={{ margin: 0, fontSize: '0.85rem', color: 'var(--color-text-muted)' }}>Информация о модераторах появляется по мере их активности в выбранном стриме.</p>
                        </div>
                      </div>
                    )}
                    {/* TOP 3 PODIUM */}
                    <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(240px, 1fr))', gap: '1.5rem', marginBottom: '2rem' }}>
                      {modProfiles.slice(0, 3).map((mod, idx) => {
                        const trophyColor = idx === 0 ? '#FFD700' : idx === 1 ? '#C0C0C0' : '#CD7F32';
                        const glowStyle = {
                          border: `1px solid ${trophyColor}40`,
                          boxShadow: `0 0 15px ${trophyColor}12`,
                          position: 'relative',
                          overflow: 'hidden'
                        };
                        return (
                          <div key={idx} className="panel" style={glowStyle}>
                            <div style={{ position: 'absolute', top: '-10px', right: '-10px', fontSize: '5rem', opacity: 0.08, color: trophyColor, fontWeight: 900 }}>
                              #{idx + 1}
                            </div>
                            <div style={{ display: 'flex', alignItems: 'center', gap: '1rem' }}>
                              <div style={{ 
                                width: '44px', 
                                height: '44px', 
                                borderRadius: '50%', 
                                background: 'var(--color-bg-base)', 
                                border: `2px solid ${trophyColor}`,
                                display: 'flex',
                                alignItems: 'center',
                                justifyContent: 'center',
                                fontWeight: 700,
                                fontSize: '1.1rem',
                                color: trophyColor
                              }}>
                                {idx === 0 ? '👑' : idx === 1 ? '🥈' : '🥉'}
                              </div>
                              <div>
                                <h4 style={{ margin: 0, fontSize: '1rem', fontWeight: 700 }}>{mod.moderator}</h4>
                                <span style={{ fontSize: '0.7rem', color: 'var(--color-text-muted)', textTransform: 'uppercase', letterSpacing: '0.05em' }}>
                                  {idx === 0 ? 'Глава патруля' : idx === 1 ? 'Старший мод' : 'Защитник чата'}
                                </span>
                              </div>
                            </div>
                            <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: '1.25rem', fontSize: '0.8rem' }}>
                              <div>
                                <div style={{ color: 'var(--color-text-muted)' }}>Действий</div>
                                <div style={{ fontSize: '1.1rem', fontWeight: 700, color: 'var(--color-text-accent)' }}>{mod.total_actions}</div>
                              </div>
                              <div>
                                <div style={{ color: 'var(--color-text-muted)' }}>Ср. Реакция</div>
                                <div style={{ fontSize: '1.1rem', fontWeight: 700, color: '#00F5D4' }}>
                                  {mod.reaction_time_avg ? `${mod.reaction_time_avg}с` : '—'}
                                </div>
                              </div>
                              <div>
                                <div style={{ color: 'var(--color-text-muted)' }}>КПД Активности</div>
                                <div style={{ fontSize: '1.1rem', fontWeight: 700, color: '#A370F7' }}>{mod.scores.activity}%</div>
                              </div>
                            </div>
                          </div>
                        );
                      })}
                    </div>

                    <div className="grid-2col" style={{ gridTemplateColumns: 'repeat(auto-fit, minmax(320px, 1fr))', gap: '1.5rem', alignItems: 'start' }}>
                      {/* Left: Mod List */}
                      <div className="panel">
                        <div className="panel-header">
                          <h3 className="panel-title"><ShieldAlert size={20} /> Рейтинг модераторов</h3>
                        </div>
                        {modProfiles.length === 0 ? (
                          <div className="status-msg">
                            <ShieldAlert size={40} className="status-msg-icon" />
                            <p>Модераторы еще не совершали действий в этом периоде</p>
                          </div>
                        ) : (
                          <div className="table-wrapper">
                            <table className="data-table">
                              <thead>
                                <tr>
                                  <th>Ранг</th>
                                  <th>Никнейм</th>
                                  <th>Действий</th>
                                  <th>Ср. Реакция</th>
                                </tr>
                              </thead>
                              <tbody>
                                {modProfiles.map((mod, idx) => (
                                  <tr 
                                    key={idx} 
                                    onClick={() => setSelectedMod(mod)}
                                    style={{ 
                                      cursor: 'pointer',
                                      background: selectedMod && selectedMod.moderator === mod.moderator ? 'rgba(163, 112, 247, 0.08)' : 'transparent',
                                      borderLeft: selectedMod && selectedMod.moderator === mod.moderator ? '3px solid var(--color-brand)' : 'none'
                                    }}
                                  >
                                    <td>#{idx + 1}</td>
                                    <td style={{ fontWeight: 600 }}>{mod.moderator}</td>
                                    <td>{mod.total_actions}</td>
                                    <td style={{ color: '#00F5D4', fontWeight: 600 }}>{mod.reaction_time_avg ? `${mod.reaction_time_avg}с` : '—'}</td>
                                  </tr>
                                ))}
                              </tbody>
                            </table>
                          </div>
                        )}
                      </div>

                      {/* Right: Mod Dossier */}
                      <div className="panel">
                        <div className="panel-header">
                          <h3 className="panel-title"><UserCheck size={20} /> Личное досье модератора</h3>
                        </div>
                        
                        {!selectedMod ? (
                          <div className="status-msg">
                            <UserCheck size={40} className="status-msg-icon" />
                            <p>Выберите модератора слева для просмотра досье</p>
                          </div>
                        ) : (
                          <div>
                            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '1.25rem' }}>
                              <div>
                                <h3 style={{ margin: 0, fontSize: '1.25rem', fontWeight: 700, color: 'var(--color-brand)' }}>{selectedMod.moderator}</h3>
                                <p style={{ margin: 0, fontSize: '0.75rem', color: 'var(--color-text-muted)' }}>Анализ стиля модерирования и характеристик</p>
                              </div>
                            </div>

                            {/* Radar chart */}
                            <div style={{ height: '280px', display: 'flex', justifyContent: 'center', marginBottom: '1.25rem' }}>
                              <Radar 
                                data={{
                                  labels: ['Скорость', 'Активность', 'Жесткость', 'Внимательность'],
                                  datasets: [{
                                    data: [
                                      selectedMod.scores.speed,
                                      selectedMod.scores.activity,
                                      selectedMod.scores.harshness,
                                      selectedMod.scores.watchfulness
                                    ],
                                    backgroundColor: 'rgba(163, 112, 247, 0.2)',
                                    borderColor: '#A370F7',
                                    borderWidth: 2,
                                    pointBackgroundColor: '#A370F7',
                                    pointBorderColor: '#FFF',
                                    pointHoverBackgroundColor: '#FFF',
                                    pointHoverBorderColor: '#A370F7'
                                  }]
                                }}
                                options={{
                                  plugins: { legend: { display: false } },
                                  scales: {
                                    r: {
                                      angleLines: { color: '#2F2F35' },
                                      grid: { color: '#2F2F35' },
                                      pointLabels: { color: '#ADADB8', font: { size: 10, weight: 'bold' } },
                                      ticks: { display: false },
                                      min: 0,
                                      max: 100
                                    }
                                  }
                                }}
                              />
                            </div>

                            {/* Actions distribution */}
                            <div style={{ marginBottom: '1rem' }}>
                              <h4 style={{ margin: '0 0 0.5rem 0', fontSize: '0.85rem', fontWeight: 600 }}>Распределение наказаний:</h4>
                              <div style={{ height: '16px', display: 'flex', borderRadius: '4px', overflow: 'hidden', background: 'var(--color-bg-base)' }}>
                                {selectedMod.bans_count > 0 && (
                                  <div 
                                    style={{ width: `${(selectedMod.bans_count / selectedMod.total_actions) * 100}%`, background: '#FF0055', height: '100%' }} 
                                    title={`Баны: ${selectedMod.bans_count}`} 
                                  />
                                )}
                                {selectedMod.timeouts_count > 0 && (
                                  <div 
                                    style={{ width: `${(selectedMod.timeouts_count / selectedMod.total_actions) * 100}%`, background: '#FFAA00', height: '100%' }} 
                                    title={`Муты/Таймауты: ${selectedMod.timeouts_count}`} 
                                  />
                                )}
                                {selectedMod.deletions_count > 0 && (
                                  <div 
                                    style={{ width: `${(selectedMod.deletions_count / selectedMod.total_actions) * 100}%`, background: '#00AAFF', height: '100%' }} 
                                    title={`Удаления сообщений: ${selectedMod.deletions_count}`} 
                                  />
                                )}
                                {selectedMod.unbans_count > 0 && (
                                  <div 
                                    style={{ width: `${(selectedMod.unbans_count / selectedMod.total_actions) * 100}%`, background: '#00FF88', height: '100%' }} 
                                    title={`Разбаны: ${selectedMod.unbans_count}`} 
                                  />
                                )}
                              </div>
                              {/* Legend */}
                              <div style={{ display: 'flex', flexWrap: 'wrap', gap: '0.75rem 1.25rem', marginTop: '0.5rem', fontSize: '0.7rem', color: 'var(--color-text-muted)' }}>
                                <div style={{ display: 'flex', alignItems: 'center', gap: '0.25rem' }}>
                                  <span style={{ display: 'inline-block', width: '6px', height: '6px', borderRadius: '50%', background: '#FF0055' }}></span>
                                  Баны ({selectedMod.bans_count})
                                </div>
                                <div style={{ display: 'flex', alignItems: 'center', gap: '0.25rem' }}>
                                  <span style={{ display: 'inline-block', width: '6px', height: '6px', borderRadius: '50%', background: '#FFAA00' }}></span>
                                  Муты ({selectedMod.timeouts_count})
                                </div>
                                <div style={{ display: 'flex', alignItems: 'center', gap: '0.25rem' }}>
                                  <span style={{ display: 'inline-block', width: '6px', height: '6px', borderRadius: '50%', background: '#00AAFF' }}></span>
                                  Удаления ({selectedMod.deletions_count})
                                </div>
                                <div style={{ display: 'flex', alignItems: 'center', gap: '0.25rem' }}>
                                  <span style={{ display: 'inline-block', width: '6px', height: '6px', borderRadius: '50%', background: '#00FF88' }}></span>
                                  Разбаны ({selectedMod.unbans_count})
                                </div>
                              </div>
                            </div>
                          </div>
                        )}
                      </div>
                    </div>
                  </div>
                )}
              </div>
            )}
          </>
        )}
      </main>

      {/* Footer */}
      <footer style={{ backgroundColor: 'var(--color-bg-card)', borderTop: '1px solid var(--color-border)', padding: '1.5rem', textAlign: 'center', color: 'var(--color-text-muted)', fontSize: '0.8rem' }}>
        <p>Дашборд Аналитики Twitch для канала winx_prinx © {new Date().getFullYear()}</p>
      </footer>
    </div>
  );
}
