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 OverviewTab from './components/OverviewTab';
import ChattersTab from './components/ChattersTab';
import WordsTab from './components/WordsTab';
import AdminTab from './components/AdminTab';
import ModeratorTab from './components/ModeratorTab';

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

// 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';

// ChatterOrbit component has been extracted to components/ChatterOrbit.jsx

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([]);
  const [statsSummary, setStatsSummary] = useState({ messages: 0, uniqueChatters: 0, mostActiveChatter: '—', voiceWordsCount: 0, modActionsCount: 0 });
  
  // 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);
  const [rateLimitInfo, setRateLimitInfo] = useState(null);

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

  const safeFetch = async (url, options = {}) => {
    const res = await fetch(url, options);
    if (res.status === 429) {
      try {
        const data = await res.json();
        setRateLimitInfo({ 
          message: data.message || 'Превышен лимит запросов к серверу.', 
          retryAfter: data.retryAfter || 60 
        });
      } catch (e) {
        setRateLimitInfo({ message: 'Слишком много запросов к серверу.', retryAfter: 60 });
      }
      return res;
    } else if (res.ok) {
      setRateLimitInfo(null);
    }
    return res;
  };

  useEffect(() => {
    if (rateLimitInfo && rateLimitInfo.retryAfter > 0) {
      if (rateLimitTimerRef.current) clearInterval(rateLimitTimerRef.current);
      rateLimitTimerRef.current = setInterval(() => {
        setRateLimitInfo(prev => {
          if (!prev || prev.retryAfter <= 1) {
            clearInterval(rateLimitTimerRef.current);
            return null;
          }
          return { ...prev, retryAfter: prev.retryAfter - 1 };
        });
      }, 1000);
    } else if (!rateLimitInfo && rateLimitTimerRef.current) {
      clearInterval(rateLimitTimerRef.current);
    }
    return () => clearInterval(rateLimitTimerRef.current);
  }, [rateLimitInfo]);

  const fetchAdminStats = async () => {
    setLoadingAdminStats(true);
    try {
      const res = await safeFetch(`${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 safeFetch(`${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 (with loading spinner)
  useEffect(() => {
    if (selectedStreamId && serverStatus === 'online') {
      fetchAllStats(true);
    }
  }, [selectedStreamId, serverStatus, auth.loggedIn, twitchConfigured]);

  // Manage polling intervals when selected stream changes or streams update
  useEffect(() => {
    if (selectedStreamId && serverStatus === 'online') {
      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 safeFetch(`${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 safeFetch(`${API_BASE}/api/streams`);
      const data = await res.json();
      setStreams(Array.isArray(data) ? 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 safeFetch(getUrl('/api/stats/chatters'));
      const chattersData = await chattersRes.json();
      setChatters(Array.isArray(chattersData) ? chattersData : []);

      // 1.5. Overall stream stats summary (true totals)
      try {
        const statsSummaryRes = await safeFetch(getUrl('/api/stats/summary'));
        const statsSummaryData = await statsSummaryRes.json();
        if (statsSummaryData && !statsSummaryData.error) {
          setStatsSummary(statsSummaryData);
        }
      } catch (err) {
        console.error('Error fetching stream stats summary:', err);
      }

      // 2. Spoken voice words
      const voiceRes = await safeFetch(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 safeFetch(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 safeFetch(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 safeFetch(getUrl('/api/stats/moderators', { limit: 100 }), { credentials: 'include' });
        const modData = await modRes.json();
        setModActions(Array.isArray(modData) ? modData : []);

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

        const profilesRes = await safeFetch(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 safeFetch(`${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' 
    });
  };



  // 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">

        {rateLimitInfo && (
          <div className="rate-limit-banner" style={{
            background: 'linear-gradient(90deg, rgba(255, 153, 0, 0.15) 0%, rgba(255, 102, 0, 0.15) 100%)',
            backdropFilter: 'blur(8px)',
            WebkitBackdropFilter: 'blur(8px)',
            border: '1px solid rgba(255, 153, 0, 0.3)',
            borderRadius: 'var(--radius-md)',
            padding: '1rem',
            margin: '0 0 1rem 0',
            display: 'flex',
            alignItems: 'center',
            gap: '1rem',
            color: '#FF9900',
            animation: 'fadeIn 0.3s ease-out'
          }}>
            <ShieldAlert size={24} style={{ animation: 'pulse 2s infinite' }} />
            <div style={{ flex: 1 }}>
              <h3 style={{ margin: 0, fontSize: '1rem', fontWeight: 600 }}>Внимание: Лимит запросов</h3>
              <p style={{ margin: '0.2rem 0 0', fontSize: '0.85rem', color: 'rgba(255, 255, 255, 0.8)' }}>
                {rateLimitInfo.message}
              </p>
            </div>
            <div style={{
              background: 'rgba(255, 153, 0, 0.2)',
              padding: '0.5rem 1rem',
              borderRadius: 'var(--radius-sm)',
              fontWeight: 600,
              fontVariantNumeric: 'tabular-nums'
            }}>
              Разблокировка через: {rateLimitInfo.retryAfter} сек.
            </div>
          </div>
        )}

        {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 }}>
                  Сервер бэкенда в облаке может находиться в спящем режиме. Пробуждение сервера занимает около 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>
        ) : (
          <>
            {activeTab === 'overview' && (
              <OverviewTab
                statsSummary={statsSummary}
                selectedStreamId={selectedStreamId}
                activityData={activityData}
                isRacing={isRacing}
                startGraphRace={startGraphRace}
                chartDataConfig={chartDataConfig}
                chartOptions={chartOptions}
                voiceWords={voiceWords}
              />
            )}

            {activeTab === 'chatters' && (
              <ChattersTab
                chatters={chatters}
                chattersSearch={chattersSearch}
                setChattersSearch={setChattersSearch}
                TWITCH_CHANNEL={TWITCH_CHANNEL}
              />
            )}

            {activeTab === 'words' && (
              <WordsTab
                wordType={wordType}
                setWordType={setWordType}
                voiceWords={voiceWords}
                chatWords={chatWords}
              />
            )}

            {activeTab === 'admin' && (
              <AdminTab
                adminSelectedStreamId={adminSelectedStreamId}
                setAdminSelectedStreamId={setAdminSelectedStreamId}
                streams={streams}
                editTitle={editTitle}
                setEditTitle={setEditTitle}
                editCategory={editCategory}
                setEditCategory={setEditCategory}
                savingMetadata={savingMetadata}
                setSavingMetadata={setSavingMetadata}
                deletingStream={deletingStream}
                setDeletingStream={setDeletingStream}
                syncingVods={syncingVods}
                setSyncingVods={setSyncingVods}
                cleaningStreams={cleaningStreams}
                setCleaningStreams={setCleaningStreams}
                loadingAdminStats={loadingAdminStats}
                adminStats={adminStats}
                fetchAdminStats={fetchAdminStats}
                fetchStreams={fetchStreams}
                API_BASE={API_BASE}
              />
            )}

            {activeTab === 'moderator' && (
              <ModeratorTab
                twitchConfigured={twitchConfigured}
                auth={auth}
                handleLogin={handleLogin}
                TWITCH_CHANNEL={TWITCH_CHANNEL}
                modProfiles={modProfiles}
                selectedMod={selectedMod}
                setSelectedMod={setSelectedMod}
                API_BASE={API_BASE}
              />
            )}
          </>
        )}
      </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>
  );
}
