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

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

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

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

export default function App() {
  const [connected, setConnected] = useState(false);
  const [plugins, setPlugins] = useState<PluginInfo[]>([]);
  const [updateState, setUpdateState] = useState<'idle' | 'checking' | 'downloading' | 'ready' | 'uptodate' | 'error'>('idle');
  const [updateError, setUpdateError] = useState<string>('');
  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>>({});
  const eventSourceRef = useRef<EventSource | null>(null);

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

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

  // Listen for Electron auto-update events
  useEffect(() => {
    const api = (window as any).electronAPI;
    if (!api?.onUpdateAvailable) return;
    api.onUpdateAvailable(() => {
      setUpdateState('downloading');
      if (Notification.permission === 'granted') {
        new Notification('Gaming Hub Update', { body: 'Ein Update wird heruntergeladen...' });
      }
    });
    api.onUpdateReady(() => {
      setUpdateState('ready');
      if (Notification.permission === 'granted') {
        new Notification('Gaming Hub Update bereit', { body: 'Klicke OK um das Update zu installieren.' });
      }
    });
    api.onUpdateNotAvailable?.(() => setUpdateState('uptodate'));
    api.onUpdateError?.((msg: string) => {
      setUpdateError(msg || 'Unbekannter Fehler');
      setUpdateState('error');
    });
  }, []);

  const electronVersion = (window as any).electronAPI?.version ?? null;

  // 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]);

  const handleCheckForUpdates = () => {
    setUpdateState('checking');
    setUpdateError('');
    (window as any).electronAPI?.checkForUpdates?.();
    // Timeout: falls Electron nicht antwortet, nach 15s zurücksetzen
    setTimeout(() => {
      setUpdateState(prev => prev === 'checking' ? 'error' : prev);
      setUpdateError(prev => prev || 'Zeitüberschreitung — Server nicht erreichbar.');
    }, 15000);
  };

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

  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.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>
          )}
          {(window as any).electronAPI && (
            <button
              className="hub-check-update-btn"
              onClick={handleCheckForUpdates}
              disabled={updateState !== 'idle'}
              title="Nach Updates suchen"
            >
              {'\u{1F504}'}
            </button>
          )}
          <span
            className="hub-version hub-version-clickable"
            onClick={() => setShowVersionModal(true)}
            title="Versionsinformationen"
          >
            v{version}
          </span>
        </div>
      </header>

      {updateState !== 'idle' && (
        <div className="hub-update-overlay">
          <div className="hub-update-modal">
            {updateState === 'checking' && (
              <>
                <div className="hub-update-icon">{'\u{1F50D}'}</div>
                <h2>Suche nach Updates...</h2>
                <div className="hub-update-versions">
                  {electronVersion && <span>Desktop App: v{electronVersion}</span>}
                  <span>Server: v{version}</span>
                </div>
                <div className="hub-update-progress">
                  <div className="hub-update-progress-bar" />
                </div>
                <button className="hub-update-btn" onClick={() => setUpdateState('idle')}>
                  Abbrechen
                </button>
              </>
            )}
            {updateState === 'downloading' && (
              <>
                <div className="hub-update-icon">{'\u2B07\uFE0F'}</div>
                <h2>Update wird heruntergeladen...</h2>
                <div className="hub-update-versions">
                  {electronVersion && <span>Aktuell: v{electronVersion}</span>}
                </div>
                <div className="hub-update-progress">
                  <div className="hub-update-progress-bar" />
                </div>
              </>
            )}
            {updateState === 'ready' && (
              <>
                <div className="hub-update-icon">{'\u2705'}</div>
                <h2>Update bereit!</h2>
                <p>Die App wird neu gestartet, um das Update zu installieren.</p>
                <button className="hub-update-btn" onClick={() => (window as any).electronAPI?.installUpdate()}>
                  Jetzt installieren
                </button>
                <button className="hub-update-btn hub-update-btn-secondary" onClick={() => setUpdateState('idle')}>
                  Später
                </button>
              </>
            )}
            {updateState === 'uptodate' && (
              <>
                <div className="hub-update-icon">{'\u2705'}</div>
                <h2>Alles aktuell!</h2>
                <div className="hub-update-versions">
                  {electronVersion && <span>Desktop App: v{electronVersion}</span>}
                  <span>Server: v{version}</span>
                </div>
                <p>Du verwendest bereits die neueste Version.</p>
                <button className="hub-update-btn" onClick={() => setUpdateState('idle')}>
                  OK
                </button>
              </>
            )}
            {updateState === 'error' && (
              <>
                <div className="hub-update-icon">{'\u274C'}</div>
                <h2>Update fehlgeschlagen</h2>
                <div className="hub-update-versions">
                  {electronVersion && <span>Desktop App: v{electronVersion}</span>}
                  <span>Server: v{version}</span>
                </div>
                {updateError && <p className="hub-update-error-detail">{updateError}</p>}
                <button className="hub-update-btn" onClick={() => setUpdateState('idle')}>
                  Schließen
                </button>
              </>
            )}
          </div>
        </div>
      )}

      {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>
              <div className="hub-version-modal-row">
                <span className="hub-version-modal-label">Desktop App</span>
                <span className="hub-version-modal-value">
                  {electronVersion
                    ? `v${electronVersion}`
                    : <a href="/downloads/GamingHub-Setup.exe" download className="hub-version-modal-link">Herunterladen</a>
                  }
                </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>
              {electronVersion && electronVersion !== version && (
                <div className="hub-version-modal-hint">
                  Desktop App und Hub Version unterschiedlich — Update verfügbar.
                </div>
              )}
            </div>
          </div>
        </div>
      )}

      <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] || {}} />
              </div>
            );
          })
        )}
      </main>
    </div>
  );
}
