import { useState, useEffect, useRef } from 'react';
import RadioTab from './plugins/radio/RadioTab';
import SoundboardTab from './plugins/soundboard/SoundboardTab';
import LolstatsTab from './plugins/lolstats/LolstatsTab';
import StreamingTab from './plugins/streaming/StreamingTab';
import WatchTogetherTab from './plugins/watch-together/WatchTogetherTab';
import GameLibraryTab from './plugins/game-library/GameLibraryTab';
import AdminPanel from './AdminPanel';
import LoginModal from './LoginModal';
import UserSettings from './UserSettings';

interface PluginInfo {
  name: string;
  version: string;
  description: string;
}

interface AuthUser {
  authenticated: boolean;
  provider?: 'discord' | 'steam' | 'admin';
  discordId?: string;
  steamId?: string;
  username?: string;
  avatar?: string | null;
  globalName?: string | null;
  isAdmin?: boolean;
}

interface AuthProviders {
  discord: boolean;
  steam: boolean;
  admin: boolean;
}

// Plugin tab components
const tabComponents: Record<string, React.FC<{ data: any; isAdmin?: boolean }>> = {
  radio: RadioTab,
  soundboard: SoundboardTab,
  lolstats: LolstatsTab,
  streaming: StreamingTab,
  'watch-together': WatchTogetherTab,
  'game-library': GameLibraryTab,
};

export function registerTab(pluginName: string, component: React.FC<{ data: any; isAdmin?: boolean }>) {
  tabComponents[pluginName] = component;
}

type UpdateStatus = 'idle' | 'checking' | 'available' | 'downloading' | 'ready' | 'upToDate' | 'error';

export default function App() {
  const [connected, setConnected] = useState(false);
  const [plugins, setPlugins] = useState<PluginInfo[]>([]);
  const [activeTab, setActiveTabRaw] = useState<string>(() => localStorage.getItem('hub_activeTab') ?? '');

  const setActiveTab = (tab: string) => {
    setActiveTabRaw(tab);
    localStorage.setItem('hub_activeTab', tab);
  };
  const [showVersionModal, setShowVersionModal] = useState(false);
  const [pluginData, setPluginData] = useState<Record<string, any>>({});

  // ── Unified Auth State ──
  const [user, setUser] = useState<AuthUser>({ authenticated: false });
  const [providers, setProviders] = useState<AuthProviders>({ discord: false, steam: false, admin: false });
  const [showLoginModal, setShowLoginModal] = useState(false);
  const [showUserSettings, setShowUserSettings] = useState(false);
  const [showAdminPanel, setShowAdminPanel] = useState(false);

  // Derived state
  const isAdmin = user.authenticated && (user.provider === 'admin' || user.isAdmin === true);
  const isDiscordUser = user.authenticated && user.provider === 'discord';
  const isSteamUser = user.authenticated && user.provider === 'steam';
  const isRegularUser = isDiscordUser || isSteamUser;

  // Electron auto-update state
  const isElectron = !!(window as any).electronAPI?.isElectron;
  const electronVersion = isElectron ? (window as any).electronAPI.version : null;
  const [updateStatus, setUpdateStatus] = useState<UpdateStatus>('idle');
  const [updateError, setUpdateError] = useState<string>('');
  const eventSourceRef = useRef<EventSource | null>(null);

  // Request notification permission
  useEffect(() => {
    if ('Notification' in window && Notification.permission === 'default') {
      Notification.requestPermission();
    }
  }, []);

  // Check auth status + providers on mount
  useEffect(() => {
    fetch('/api/auth/me', { credentials: 'include' })
      .then(r => r.json())
      .then((data: AuthUser) => setUser(data))
      .catch(() => {});

    fetch('/api/auth/providers')
      .then(r => r.json())
      .then((data: AuthProviders) => setProviders(data))
      .catch(() => {});

    // Also check legacy admin cookie (backward compat)
    fetch('/api/soundboard/admin/status', { credentials: 'include' })
      .then(r => r.json())
      .then(d => {
        if (d.authenticated) {
          setUser(prev => prev.authenticated ? prev : { authenticated: true, provider: 'admin', username: 'Admin', isAdmin: true });
        }
      })
      .catch(() => {});
  }, []);

  // Admin login handler (for LoginModal)
  async function handleAdminLogin(password: string): Promise<boolean> {
    try {
      const resp = await fetch('/api/auth/admin', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ password }),
        credentials: 'include',
      });
      if (resp.ok) {
        setUser({ authenticated: true, provider: 'admin', username: 'Admin', isAdmin: true });
        return true;
      }
      return false;
    } catch {
      return false;
    }
  }

  // Unified logout
  async function handleLogout() {
    await fetch('/api/auth/logout', { method: 'POST', credentials: 'include' });
    setUser({ authenticated: false });
    setShowUserSettings(false);
    setShowAdminPanel(false);
  }

  // Electron auto-update listeners
  useEffect(() => {
    if (!isElectron) return;
    const api = (window as any).electronAPI;
    api.onUpdateAvailable(() => setUpdateStatus('downloading'));
    api.onUpdateReady(() => setUpdateStatus('ready'));
    api.onUpdateNotAvailable(() => setUpdateStatus('upToDate'));
    api.onUpdateError((msg: string) => {
      setUpdateStatus('error');
      setUpdateError(msg || 'Unbekannter Fehler');
    });
    // Sync initial status (Hintergrund-Download könnte bereits laufen)
    const currentState = api.getUpdateStatus?.();
    if (currentState === 'downloading') setUpdateStatus('downloading');
    else if (currentState === 'ready') setUpdateStatus('ready');
    else if (currentState === 'checking') setUpdateStatus('checking');
  }, [isElectron]);

  // Fetch plugin list
  useEffect(() => {
    fetch('/api/plugins')
      .then(r => r.json())
      .then((list: PluginInfo[]) => {
        setPlugins(list);
        // If ?viewStream= is in URL, force switch to streaming tab
        const urlParams = new URLSearchParams(location.search);
        if (urlParams.has('viewStream') && list.some(p => p.name === 'streaming')) {
          setActiveTab('streaming');
          return;
        }
        const saved = localStorage.getItem('hub_activeTab');
        const valid = list.some(p => p.name === saved);
        if (list.length > 0 && !valid) setActiveTab(list[0].name);
      })
      .catch(() => {});
  }, []);

  // SSE connection
  useEffect(() => {
    let es: EventSource | null = null;
    let retryTimer: ReturnType<typeof setTimeout>;

    function connect() {
      es = new EventSource('/api/events');
      eventSourceRef.current = es;

      es.onopen = () => setConnected(true);

      es.onmessage = (ev) => {
        try {
          const msg = JSON.parse(ev.data);
          if (msg.type === 'snapshot') {
            setPluginData(prev => ({ ...prev, ...msg }));
          } else if (msg.plugin) {
            setPluginData(prev => ({
              ...prev,
              [msg.plugin]: { ...(prev[msg.plugin] || {}), ...msg },
            }));
          }
        } catch {}
      };

      es.onerror = () => {
        setConnected(false);
        es?.close();
        retryTimer = setTimeout(connect, 3000);
      };
    }

    connect();
    return () => { es?.close(); clearTimeout(retryTimer); };
  }, []);

  const version = (import.meta as any).env?.VITE_APP_VERSION ?? 'dev';


  // Close version modal on Escape
  useEffect(() => {
    if (!showVersionModal) return;
    const handler = (e: KeyboardEvent) => { if (e.key === 'Escape') setShowVersionModal(false); };
    window.addEventListener('keydown', handler);
    return () => window.removeEventListener('keydown', handler);
  }, [showVersionModal]);


  // Tab icon mapping
  const tabIcons: Record<string, string> = {
    radio: '\u{1F30D}',
    soundboard: '\u{1F3B5}',
    lolstats: '\u{2694}\uFE0F',
    stats: '\u{1F4CA}',
    events: '\u{1F4C5}',
    games: '\u{1F3B2}',
    gamevote: '\u{1F3AE}',
    streaming: '\u{1F4FA}',
    'watch-together': '\u{1F3AC}',
    'game-library': '\u{1F3AE}',
  };

  // What happens when the user button is clicked
  function handleUserButtonClick() {
    if (!user.authenticated) {
      setShowLoginModal(true);
    } else if (isAdmin) {
      setShowAdminPanel(true);
    } else if (isRegularUser) {
      setShowUserSettings(true);
    }
  }

  return (
    <div className="hub-app">
      <header className="hub-header">
        <div className="hub-header-left">
          <span className="hub-logo">{'\u{1F3AE}'}</span>
          <span className="hub-title">Gaming Hub</span>
          <span className={`hub-conn-dot ${connected ? 'online' : ''}`} />
        </div>

        <nav className="hub-tabs">
          {plugins.filter(p => p.name in tabComponents).map(p => (
            <button
              key={p.name}
              className={`hub-tab ${activeTab === p.name ? 'active' : ''}`}
              onClick={() => setActiveTab(p.name)}
              title={p.description}
            >
              <span className="hub-tab-icon">{tabIcons[p.name] ?? '\u{1F4E6}'}</span>
              <span className="hub-tab-label">{p.name}</span>
            </button>
          ))}
        </nav>

        <div className="hub-header-right">
          {!(window as any).electronAPI && (
            <a
              className="hub-download-btn"
              href="/downloads/GamingHub-Setup.exe"
              download
              title="Desktop App herunterladen"
            >
              <span className="hub-download-icon">{'\u2B07\uFE0F'}</span>
              <span className="hub-download-label">Desktop App</span>
            </a>
          )}

          {/* Unified Login / User button */}
          <button
            className={`hub-user-btn ${user.authenticated ? 'logged-in' : ''} ${isAdmin ? 'admin' : ''}`}
            onClick={handleUserButtonClick}
            onContextMenu={e => {
              if (user.authenticated) { e.preventDefault(); handleLogout(); }
            }}
            title={
              user.authenticated
                ? `${user.globalName || user.username || 'Admin'} (Rechtsklick = Abmelden)`
                : 'Anmelden'
            }
          >
            {user.authenticated ? (
              isRegularUser && user.avatar ? (
                <img src={user.avatar} alt="" className="hub-user-avatar" />
              ) : (
                <span className="hub-user-icon">{isAdmin ? '\uD83D\uDD27' : '\uD83D\uDC64'}</span>
              )
            ) : (
              <>
                <span className="hub-user-icon">{'\uD83D\uDD12'}</span>
                <span className="hub-user-label">Login</span>
              </>
            )}
          </button>

          <button
            className="hub-refresh-btn"
            onClick={() => window.location.reload()}
            title="Seite neu laden"
          >
            {'\u{1F504}'}
          </button>
          <span
            className="hub-version hub-version-clickable"
            onClick={() => {
              // Status vom Main-Prozess synchronisieren bevor Modal öffnet
              if (isElectron) {
                const api = (window as any).electronAPI;
                const s = api.getUpdateStatus?.();
                if (s === 'downloading') setUpdateStatus('downloading');
                else if (s === 'ready') setUpdateStatus('ready');
                else if (s === 'checking') setUpdateStatus('checking');
              }
              setShowVersionModal(true);
            }}
            title="Versionsinformationen"
          >
            v{version}
          </span>
        </div>
      </header>


      {showVersionModal && (
        <div className="hub-version-overlay" onClick={() => setShowVersionModal(false)}>
          <div className="hub-version-modal" onClick={e => e.stopPropagation()}>
            <div className="hub-version-modal-header">
              <span>Versionsinformationen</span>
              <button className="hub-version-modal-close" onClick={() => setShowVersionModal(false)}>
                {'\u2715'}
              </button>
            </div>
            <div className="hub-version-modal-body">
              <div className="hub-version-modal-row">
                <span className="hub-version-modal-label">Hub-Version</span>
                <span className="hub-version-modal-value">v{version}</span>
              </div>
              {isElectron && (
                <div className="hub-version-modal-row">
                  <span className="hub-version-modal-label">Desktop-App</span>
                  <span className="hub-version-modal-value">v{electronVersion}</span>
                </div>
              )}
              <div className="hub-version-modal-row">
                <span className="hub-version-modal-label">Server</span>
                <span className="hub-version-modal-value">
                  <span className={`hub-version-modal-dot ${connected ? 'online' : ''}`} />
                  {connected ? 'Verbunden' : 'Getrennt'}
                </span>
              </div>

              {isElectron && (
                <div className="hub-version-modal-update">
                  {updateStatus === 'idle' && (
                    <button
                      className="hub-version-modal-update-btn"
                      onClick={() => {
                        setUpdateStatus('checking');
                        setUpdateError('');
                        (window as any).electronAPI.checkForUpdates();
                      }}
                    >
                      {'\u{1F504}'} Nach Updates suchen
                    </button>
                  )}
                  {updateStatus === 'checking' && (
                    <div className="hub-version-modal-update-status">
                      <span className="hub-update-spinner" />
                      Suche nach Updates…
                    </div>
                  )}
                  {updateStatus === 'downloading' && (
                    <div className="hub-version-modal-update-status">
                      <span className="hub-update-spinner" />
                      Update wird heruntergeladen…
                    </div>
                  )}
                  {updateStatus === 'ready' && (
                    <button
                      className="hub-version-modal-update-btn ready"
                      onClick={() => (window as any).electronAPI.installUpdate()}
                    >
                      {'\u2705'} Jetzt installieren & neu starten
                    </button>
                  )}
                  {updateStatus === 'upToDate' && (
                    <div className="hub-version-modal-update-status success">
                      {'\u2705'} App ist aktuell
                      <button
                        className="hub-version-modal-update-retry"
                        onClick={() => setUpdateStatus('idle')}
                      >
                        Erneut prüfen
                      </button>
                    </div>
                  )}
                  {updateStatus === 'error' && (
                    <div className="hub-version-modal-update-status error">
                      {'\u274C'} {updateError}
                      <button
                        className="hub-version-modal-update-retry"
                        onClick={() => setUpdateStatus('idle')}
                      >
                        Erneut versuchen
                      </button>
                    </div>
                  )}
                </div>
              )}
            </div>
          </div>
        </div>
      )}

      {/* Login Modal */}
      {showLoginModal && (
        <LoginModal
          onClose={() => setShowLoginModal(false)}
          onAdminLogin={handleAdminLogin}
          providers={providers}
        />
      )}

      {/* User Settings (Discord + Steam users) */}
      {showUserSettings && isRegularUser && (
        <UserSettings
          user={{
            id: user.discordId || user.steamId || '',
            provider: user.provider as 'discord' | 'steam',
            username: user.username ?? '',
            avatar: user.avatar ?? null,
            globalName: user.globalName ?? null,
          }}
          onClose={() => setShowUserSettings(false)}
          onLogout={handleLogout}
        />
      )}

      {/* Admin Panel */}
      {showAdminPanel && isAdmin && (
        <AdminPanel onClose={() => setShowAdminPanel(false)} onLogout={() => { handleLogout(); setShowAdminPanel(false); }} />
      )}

      <main className="hub-content">
        {plugins.length === 0 ? (
          <div className="hub-empty">
            <span className="hub-empty-icon">{'\u{1F4E6}'}</span>
            <h2>Keine Plugins geladen</h2>
            <p>Plugins werden im Server konfiguriert.</p>
          </div>
        ) : (
          /* Render ALL tabs, hide inactive ones to preserve state.
             Active tab gets full dimensions; hidden tabs stay in DOM but invisible. */
          plugins.map(p => {
            const Comp = tabComponents[p.name];
            if (!Comp) return null;
            const isActive = activeTab === p.name;
            return (
              <div
                key={p.name}
                className={`hub-tab-panel ${isActive ? 'active' : ''}`}
                style={isActive
                  ? { display: 'flex', flexDirection: 'column', width: '100%', height: '100%' }
                  : { display: 'none' }
                }
              >
                <Comp data={pluginData[p.name] || {}} isAdmin={isAdmin} />
              </div>
            );
          })
        )}
      </main>
    </div>
  );
}
