import { useState, useEffect, useRef, useCallback } from 'react';
import './watch-together.css';

// ── Types ──

interface RoomInfo {
  id: string;
  name: string;
  hostName: string;
  memberCount: number;
  hasPassword: boolean;
  playing: boolean;
}

interface RoomState {
  id: string;
  name: string;
  hostId: string;
  members: Array<{ id: string; name: string }>;
  currentVideo: { url: string; title: string } | null;
  playing: boolean;
  currentTime: number;
  queue: Array<{ url: string; title: string; addedBy: string; watched: boolean }>;
}

interface JoinModal {
  roomId: string;
  roomName: string;
  password: string;
  error: string | null;
}

// ── Helpers ──

function formatTime(s: number): string {
  const sec = Math.floor(s);
  const h = Math.floor(sec / 3600);
  const m = Math.floor((sec % 3600) / 60);
  const ss = sec % 60;
  if (h > 0) return `${h}:${String(m).padStart(2, '0')}:${String(ss).padStart(2, '0')}`;
  return `${m}:${String(ss).padStart(2, '0')}`;
}

function parseVideoUrl(url: string): { type: 'youtube'; videoId: string } | { type: 'direct'; url: string } | null {
  const ytMatch = url.match(/(?:youtube\.com\/(?:watch\?v=|embed\/|shorts\/)|youtu\.be\/)([a-zA-Z0-9_-]{11})/);
  if (ytMatch) return { type: 'youtube', videoId: ytMatch[1] };
  if (/\.(mp4|webm|ogg)(\?|$)/i.test(url) || url.startsWith('http')) return { type: 'direct', url };
  return null;
}

declare global {
  interface Window {
    YT: any;
    onYouTubeIframeAPIReady: (() => void) | undefined;
  }
}

// ── Component ──

export default function WatchTogetherTab({ data }: { data: any }) {
  // ── State ──
  const [rooms, setRooms] = useState<RoomInfo[]>([]);
  const [userName, setUserName] = useState(() => localStorage.getItem('wt_name') || '');
  const [roomName, setRoomName] = useState('');
  const [roomPassword, setRoomPassword] = useState('');
  const [currentRoom, setCurrentRoom] = useState<RoomState | null>(null);
  const [joinModal, setJoinModal] = useState<JoinModal | null>(null);
  const [error, setError] = useState<string | null>(null);
  const [queueUrl, setQueueUrl] = useState('');
  const [volume, setVolume] = useState(() => {
    const v = localStorage.getItem('wt_volume');
    return v ? parseFloat(v) : 1;
  });
  const [isFullscreen, setIsFullscreen] = useState(false);
  const [duration, setDuration] = useState(0);
  const [currentTime, setCurrentTime] = useState(0);
  const [playerError, setPlayerError] = useState<string | null>(null);
  const [addingToQueue, setAddingToQueue] = useState(false);

  // ── Refs ──
  const wsRef = useRef<WebSocket | null>(null);
  const clientIdRef = useRef<string>('');
  const reconnectTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
  const reconnectDelayRef = useRef(1000);
  const currentRoomRef = useRef<RoomState | null>(null);
  const roomContainerRef = useRef<HTMLDivElement | null>(null);

  // Player refs
  const ytPlayerRef = useRef<any>(null);
  const videoRef = useRef<HTMLVideoElement | null>(null);
  const playerContainerRef = useRef<HTMLDivElement | null>(null);
  const currentVideoTypeRef = useRef<'youtube' | 'direct' | null>(null);
  const ytReadyRef = useRef(false);
  const seekingRef = useRef(false);
  const timeUpdateRef = useRef<ReturnType<typeof setInterval> | null>(null);

  // Mirror state to refs
  useEffect(() => { currentRoomRef.current = currentRoom; }, [currentRoom]);

  const isHost = currentRoom != null && clientIdRef.current === currentRoom.hostId;

  // ── SSE data ──
  useEffect(() => {
    if (data?.rooms) {
      setRooms(data.rooms);
    }
  }, [data]);

  // ── Save name ──
  useEffect(() => {
    if (userName) localStorage.setItem('wt_name', userName);
  }, [userName]);

  // ── Save volume ──
  useEffect(() => {
    localStorage.setItem('wt_volume', String(volume));
    if (ytPlayerRef.current && typeof ytPlayerRef.current.setVolume === 'function') {
      ytPlayerRef.current.setVolume(volume * 100);
    }
    if (videoRef.current) {
      videoRef.current.volume = volume;
    }
  }, [volume]);

  // ── YouTube IFrame API ──
  useEffect(() => {
    if (window.YT) { ytReadyRef.current = true; return; }
    const tag = document.createElement('script');
    tag.src = 'https://www.youtube.com/iframe_api';
    document.head.appendChild(tag);
    const prev = window.onYouTubeIframeAPIReady;
    window.onYouTubeIframeAPIReady = () => {
      ytReadyRef.current = true;
      if (prev) prev();
    };
  }, []);

  // ── WS send ──
  const wsSend = useCallback((d: Record<string, any>) => {
    if (wsRef.current?.readyState === WebSocket.OPEN) {
      wsRef.current.send(JSON.stringify(d));
    }
  }, []);

  // ── Get current time from active player ──
  const getCurrentTime = useCallback((): number | null => {
    if (currentVideoTypeRef.current === 'youtube' && ytPlayerRef.current && typeof ytPlayerRef.current.getCurrentTime === 'function') {
      return ytPlayerRef.current.getCurrentTime();
    }
    if (currentVideoTypeRef.current === 'direct' && videoRef.current) {
      return videoRef.current.currentTime;
    }
    return null;
  }, []);

  // ── Get duration from active player ──
  const getDuration = useCallback((): number => {
    if (currentVideoTypeRef.current === 'youtube' && ytPlayerRef.current && typeof ytPlayerRef.current.getDuration === 'function') {
      return ytPlayerRef.current.getDuration() || 0;
    }
    if (currentVideoTypeRef.current === 'direct' && videoRef.current) {
      return videoRef.current.duration || 0;
    }
    return 0;
  }, []);

  // ── Destroy player ──
  const destroyPlayer = useCallback(() => {
    if (ytPlayerRef.current) {
      try { ytPlayerRef.current.destroy(); } catch {}
      ytPlayerRef.current = null;
    }
    if (videoRef.current) {
      videoRef.current.pause();
      videoRef.current.removeAttribute('src');
      videoRef.current.load();
    }
    currentVideoTypeRef.current = null;
    if (timeUpdateRef.current) {
      clearInterval(timeUpdateRef.current);
      timeUpdateRef.current = null;
    }
  }, []);

  // ── Load video ──
  const loadVideo = useCallback((url: string) => {
    destroyPlayer();
    setPlayerError(null);
    const parsed = parseVideoUrl(url);
    if (!parsed) return;

    if (parsed.type === 'youtube') {
      currentVideoTypeRef.current = 'youtube';
      if (!ytReadyRef.current || !playerContainerRef.current) return;

      // Create a fresh div for YT player
      const container = playerContainerRef.current;
      const ytDiv = document.createElement('div');
      ytDiv.id = 'wt-yt-player-' + Date.now();
      container.innerHTML = '';
      container.appendChild(ytDiv);

      ytPlayerRef.current = new window.YT.Player(ytDiv.id, {
        videoId: parsed.videoId,
        playerVars: { autoplay: 1, controls: 0, modestbranding: 1, rel: 0 },
        events: {
          onReady: (ev: any) => {
            ev.target.setVolume(volume * 100);
            setDuration(ev.target.getDuration() || 0);
            // Time update interval
            timeUpdateRef.current = setInterval(() => {
              if (ytPlayerRef.current && typeof ytPlayerRef.current.getCurrentTime === 'function') {
                setCurrentTime(ytPlayerRef.current.getCurrentTime());
                setDuration(ytPlayerRef.current.getDuration() || 0);
              }
            }, 500);
          },
          onStateChange: (ev: any) => {
            if (ev.data === window.YT.PlayerState.ENDED) {
              const room = currentRoomRef.current;
              if (room && clientIdRef.current === room.hostId) {
                wsSend({ type: 'skip' });
              }
            }
          },
          onError: (ev: any) => {
            const code = ev.data;
            // 101 or 150 = embedding disabled by video owner
            // 100 = video not found
            // 5 = HTML5 player error
            if (code === 101 || code === 150) {
              setPlayerError('Embedding deaktiviert \u2014 Video kann nur auf YouTube angesehen werden.');
            } else if (code === 100) {
              setPlayerError('Video nicht gefunden oder entfernt.');
            } else {
              setPlayerError('Wiedergabefehler \u2014 Video wird \u00FCbersprungen.');
            }
            // Auto-skip after 3 seconds if host
            setTimeout(() => {
              const room = currentRoomRef.current;
              if (room && clientIdRef.current === room.hostId) {
                wsSend({ type: 'skip' });
              }
            }, 3000);
          },
        },
      });
    } else {
      currentVideoTypeRef.current = 'direct';
      if (videoRef.current) {
        videoRef.current.src = parsed.url;
        videoRef.current.volume = volume;
        videoRef.current.play().catch(() => {});
      }
    }
  }, [destroyPlayer, volume, wsSend]);

  // ── HTML5 video ended handler ──
  useEffect(() => {
    const video = videoRef.current;
    if (!video) return;
    const onEnded = () => {
      const room = currentRoomRef.current;
      if (room && clientIdRef.current === room.hostId) {
        wsSend({ type: 'skip' });
      }
    };
    const onTimeUpdate = () => {
      setCurrentTime(video.currentTime);
      setDuration(video.duration || 0);
    };
    video.addEventListener('ended', onEnded);
    video.addEventListener('timeupdate', onTimeUpdate);
    return () => {
      video.removeEventListener('ended', onEnded);
      video.removeEventListener('timeupdate', onTimeUpdate);
    };
  }, [wsSend]);

  // ── WS message handler ──
  const handleWsMessageRef = useRef<(msg: any) => void>(() => {});
  handleWsMessageRef.current = (msg: any) => {
    switch (msg.type) {
      case 'welcome':
        clientIdRef.current = msg.clientId;
        if (msg.rooms) setRooms(msg.rooms);
        break;

      case 'room_created': {
        const r = msg.room;
        setCurrentRoom({
          id: r.id,
          name: r.name,
          hostId: r.hostId,
          members: r.members || [],
          currentVideo: r.currentVideo || null,
          playing: r.playing || false,
          currentTime: r.currentTime || 0,
          queue: r.queue || [],
        });
        break;
      }

      case 'room_joined': {
        const r = msg.room;
        setCurrentRoom({
          id: r.id,
          name: r.name,
          hostId: r.hostId,
          members: r.members || [],
          currentVideo: r.currentVideo || null,
          playing: r.playing || false,
          currentTime: r.currentTime || 0,
          queue: r.queue || [],
        });
        if (r.currentVideo?.url) {
          setTimeout(() => loadVideo(r.currentVideo.url), 100);
        }
        break;
      }

      case 'playback_state': {
        const room = currentRoomRef.current;
        if (!room) break;

        const newVideo = msg.currentVideo;
        const prevUrl = room.currentVideo?.url;

        // 1. Video URL changed → load new video
        if (newVideo?.url && newVideo.url !== prevUrl) {
          loadVideo(newVideo.url);
        } else if (!newVideo && prevUrl) {
          destroyPlayer();
        }

        // 2. Playing mismatch → play or pause
        if (currentVideoTypeRef.current === 'youtube' && ytPlayerRef.current) {
          const playerState = ytPlayerRef.current.getPlayerState?.();
          if (msg.playing && playerState !== window.YT?.PlayerState?.PLAYING) {
            ytPlayerRef.current.playVideo?.();
          } else if (!msg.playing && playerState === window.YT?.PlayerState?.PLAYING) {
            ytPlayerRef.current.pauseVideo?.();
          }
        } else if (currentVideoTypeRef.current === 'direct' && videoRef.current) {
          if (msg.playing && videoRef.current.paused) {
            videoRef.current.play().catch(() => {});
          } else if (!msg.playing && !videoRef.current.paused) {
            videoRef.current.pause();
          }
        }

        // 3. Drift correction: if |localTime - serverTime| > 2 → seek
        if (msg.currentTime !== undefined && !seekingRef.current) {
          const localTime = getCurrentTime();
          if (localTime !== null && Math.abs(localTime - msg.currentTime) > 2) {
            if (currentVideoTypeRef.current === 'youtube' && ytPlayerRef.current) {
              ytPlayerRef.current.seekTo?.(msg.currentTime, true);
            } else if (currentVideoTypeRef.current === 'direct' && videoRef.current) {
              videoRef.current.currentTime = msg.currentTime;
            }
          }
        }

        setCurrentRoom(prev => prev ? {
          ...prev,
          currentVideo: newVideo || null,
          playing: msg.playing,
          currentTime: msg.currentTime ?? prev.currentTime,
        } : prev);
        break;
      }

      case 'queue_updated':
        setCurrentRoom(prev => prev ? { ...prev, queue: msg.queue } : prev);
        break;

      case 'members_updated':
        setCurrentRoom(prev => prev ? { ...prev, members: msg.members, hostId: msg.hostId } : prev);
        break;

      case 'error':
        if (msg.code === 'WRONG_PASSWORD') {
          setJoinModal(prev => prev ? { ...prev, error: msg.message } : prev);
        } else {
          setError(msg.message);
        }
        break;
    }
  };

  // ── WebSocket connect ──
  const connectWs = useCallback(() => {
    if (wsRef.current && (wsRef.current.readyState === WebSocket.OPEN || wsRef.current.readyState === WebSocket.CONNECTING)) return;

    const proto = location.protocol === 'https:' ? 'wss' : 'ws';
    const ws = new WebSocket(`${proto}://${location.host}/ws/watch-together`);
    wsRef.current = ws;

    ws.onopen = () => { reconnectDelayRef.current = 1000; };

    ws.onmessage = (ev) => {
      let msg: any;
      try { msg = JSON.parse(ev.data); } catch { return; }
      handleWsMessageRef.current(msg);
    };

    ws.onclose = () => {
      if (wsRef.current === ws) {
        wsRef.current = null;
      }
      if (currentRoomRef.current) {
        reconnectTimerRef.current = setTimeout(() => {
          reconnectDelayRef.current = Math.min(reconnectDelayRef.current * 2, 10000);
          connectWs();
        }, reconnectDelayRef.current);
      }
    };

    ws.onerror = () => { ws.close(); };
  }, []);

  // ── Create room ──
  const createRoom = useCallback(() => {
    if (!userName.trim()) { setError('Bitte gib einen Namen ein.'); return; }
    if (!roomName.trim()) { setError('Bitte gib einen Raumnamen ein.'); return; }
    setError(null);
    connectWs();

    const startTime = Date.now();
    const waitForWs = () => {
      if (wsRef.current?.readyState === WebSocket.OPEN) {
        wsSend({
          type: 'create_room',
          name: roomName.trim(),
          userName: userName.trim(),
          password: roomPassword.trim() || undefined,
        });
      } else if (Date.now() - startTime > 10000) {
        setError('Verbindung zum Server fehlgeschlagen.');
      } else {
        setTimeout(waitForWs, 100);
      }
    };
    waitForWs();
  }, [userName, roomName, roomPassword, connectWs, wsSend]);

  // ── Join room ──
  const joinRoom = useCallback((roomId: string, password?: string) => {
    if (!userName.trim()) { setError('Bitte gib einen Namen ein.'); return; }
    setError(null);
    connectWs();

    const startTime = Date.now();
    const waitForWs = () => {
      if (wsRef.current?.readyState === WebSocket.OPEN) {
        wsSend({
          type: 'join_room',
          userName: userName.trim(),
          roomId,
          password: password?.trim() || undefined,
        });
      } else if (Date.now() - startTime > 10000) {
        setError('Verbindung zum Server fehlgeschlagen.');
      } else {
        setTimeout(waitForWs, 100);
      }
    };
    waitForWs();
  }, [userName, connectWs, wsSend]);

  // ── Leave room ──
  const leaveRoom = useCallback(() => {
    wsSend({ type: 'leave_room' });
    destroyPlayer();
    setCurrentRoom(null);
    setQueueUrl('');
    setDuration(0);
    setCurrentTime(0);
  }, [wsSend, destroyPlayer]);

  // ── Add to queue ──
  const addToQueue = useCallback(async () => {
    const url = queueUrl.trim();
    if (!url) return;
    setQueueUrl('');
    setAddingToQueue(true);

    let title = '';
    try {
      const resp = await fetch(`/api/watch-together/video-info?url=${encodeURIComponent(url)}`);
      if (resp.ok) {
        const data = await resp.json();
        title = data.title || '';
      }
    } catch { /* use URL as fallback */ }

    wsSend({ type: 'add_to_queue', url, title: title || undefined });
    setAddingToQueue(false);
  }, [queueUrl, wsSend]);

  // ── Remove from queue ──
  const removeFromQueue = useCallback((index: number) => {
    wsSend({ type: 'remove_from_queue', index });
  }, [wsSend]);

  // ── Playback controls (host only) ──
  const togglePlay = useCallback(() => {
    const room = currentRoomRef.current;
    if (!room) return;
    wsSend({ type: room.playing ? 'pause' : 'resume' });
  }, [wsSend]);

  const skip = useCallback(() => {
    wsSend({ type: 'skip' });
  }, [wsSend]);

  const seek = useCallback((time: number) => {
    seekingRef.current = true;
    wsSend({ type: 'seek', time });
    // Seek locally immediately
    if (currentVideoTypeRef.current === 'youtube' && ytPlayerRef.current) {
      ytPlayerRef.current.seekTo?.(time, true);
    } else if (currentVideoTypeRef.current === 'direct' && videoRef.current) {
      videoRef.current.currentTime = time;
    }
    setCurrentTime(time);
    setTimeout(() => { seekingRef.current = false; }, 1000);
  }, [wsSend]);

  // ── Host time reporting ──
  useEffect(() => {
    if (!isHost || !currentRoom?.playing) return;
    const iv = setInterval(() => {
      const time = getCurrentTime();
      if (time !== null) wsSend({ type: 'report_time', time });
    }, 2000);
    return () => clearInterval(iv);
  }, [isHost, currentRoom?.playing, wsSend, getCurrentTime]);

  // ── Fullscreen ──
  const toggleFullscreen = useCallback(() => {
    const el = roomContainerRef.current;
    if (!el) return;
    if (!document.fullscreenElement) el.requestFullscreen().catch(() => {});
    else document.exitFullscreen().catch(() => {});
  }, []);

  useEffect(() => {
    const handler = () => setIsFullscreen(!!document.fullscreenElement);
    document.addEventListener('fullscreenchange', handler);
    return () => document.removeEventListener('fullscreenchange', handler);
  }, []);

  // ── beforeunload + pagehide ──
  useEffect(() => {
    const beforeUnload = (e: BeforeUnloadEvent) => {
      if (currentRoomRef.current) e.preventDefault();
    };
    const pageHide = () => {
      if (clientIdRef.current) {
        navigator.sendBeacon('/api/watch-together/disconnect', JSON.stringify({ clientId: clientIdRef.current }));
      }
    };
    window.addEventListener('beforeunload', beforeUnload);
    window.addEventListener('pagehide', pageHide);
    return () => {
      window.removeEventListener('beforeunload', beforeUnload);
      window.removeEventListener('pagehide', pageHide);
    };
  }, []);

  // ── Cleanup on unmount ──
  useEffect(() => {
    return () => {
      destroyPlayer();
      if (wsRef.current) wsRef.current.close();
      if (reconnectTimerRef.current) clearTimeout(reconnectTimerRef.current);
    };
  }, [destroyPlayer]);

  // ── Join modal submit ──
  const submitJoinModal = useCallback(() => {
    if (!joinModal) return;
    if (!joinModal.password.trim()) {
      setJoinModal(prev => prev ? { ...prev, error: 'Passwort eingeben.' } : prev);
      return;
    }
    const { roomId, password } = joinModal;
    setJoinModal(null);
    joinRoom(roomId, password);
  }, [joinModal, joinRoom]);

  // ── Tile click ──
  const handleTileClick = useCallback((room: RoomInfo) => {
    if (room.hasPassword) {
      setJoinModal({ roomId: room.id, roomName: room.name, password: '', error: null });
    } else {
      joinRoom(room.id);
    }
  }, [joinRoom]);

  // ── Render: Room View ──
  if (currentRoom) {
    const hostMember = currentRoom.members.find(m => m.id === currentRoom.hostId);
    return (
      <div className="wt-room-overlay" ref={roomContainerRef}>
        <div className="wt-room-header">
          <div className="wt-room-header-left">
            <span className="wt-room-name">{currentRoom.name}</span>
            <span className="wt-room-members">{currentRoom.members.length} Mitglieder</span>
            {hostMember && <span className="wt-host-badge">Host: {hostMember.name}</span>}
          </div>
          <div className="wt-room-header-right">
            <button className="wt-fullscreen-btn" onClick={toggleFullscreen} title={isFullscreen ? 'Vollbild verlassen' : 'Vollbild'}>
              {isFullscreen ? '\u2716' : '\u26F6'}
            </button>
            <button className="wt-leave-btn" onClick={leaveRoom}>Verlassen</button>
          </div>
        </div>

        <div className="wt-room-body">
          <div className="wt-player-section">
            <div className="wt-player-wrap">
              <div ref={playerContainerRef} className="wt-yt-container" style={currentVideoTypeRef.current === 'youtube' ? {} : { display: 'none' }} />
              <video
                ref={videoRef}
                className="wt-video-element"
                style={currentVideoTypeRef.current === 'direct' ? {} : { display: 'none' }}
                playsInline
              />
              {playerError && (
                <div className="wt-player-error">
                  <div className="wt-error-icon">{'\u26A0\uFE0F'}</div>
                  <p>{playerError}</p>
                  {currentRoom.currentVideo?.url && (
                    <a
                      className="wt-yt-link"
                      href={currentRoom.currentVideo.url}
                      target="_blank"
                      rel="noopener noreferrer"
                    >
                      Auf YouTube &ouml;ffnen &#8599;
                    </a>
                  )}
                  <p className="wt-skip-info">Wird in 3 Sekunden &uuml;bersprungen...</p>
                </div>
              )}
              {!currentRoom.currentVideo && (
                <div className="wt-player-placeholder">
                  <div className="wt-placeholder-icon">{'\uD83C\uDFAC'}</div>
                  <p>Fuege ein Video zur Warteschlange hinzu</p>
                </div>
              )}
            </div>

            <div className="wt-controls">
              {isHost ? (
                <>
                  <button className="wt-ctrl-btn" onClick={togglePlay} disabled={!currentRoom.currentVideo} title={currentRoom.playing ? 'Pause' : 'Abspielen'}>
                    {currentRoom.playing ? '\u23F8' : '\u25B6'}
                  </button>
                  <button className="wt-ctrl-btn wt-next-btn" onClick={skip} disabled={!currentRoom.currentVideo && currentRoom.queue.length === 0} title="Nächstes Video">
                    {'\u23ED'} Weiter
                  </button>
                  <input
                    className="wt-seek"
                    type="range"
                    min={0}
                    max={duration || 0}
                    step={0.5}
                    value={currentTime}
                    onChange={e => seek(parseFloat(e.target.value))}
                    disabled={!currentRoom.currentVideo}
                  />
                </>
              ) : (
                <>
                  <span className="wt-ctrl-status">{currentRoom.playing ? '\u25B6' : '\u23F8'}</span>
                  <div className="wt-seek-readonly">
                    <div className="wt-seek-progress" style={{ width: duration > 0 ? `${(currentTime / duration) * 100}%` : '0%' }} />
                  </div>
                </>
              )}
              <span className="wt-time">{formatTime(currentTime)} / {formatTime(duration)}</span>
              <div className="wt-volume">
                <span className="wt-volume-icon">{volume === 0 ? '\uD83D\uDD07' : volume < 0.5 ? '\uD83D\uDD09' : '\uD83D\uDD0A'}</span>
                <input
                  className="wt-volume-slider"
                  type="range"
                  min={0}
                  max={1}
                  step={0.01}
                  value={volume}
                  onChange={e => setVolume(parseFloat(e.target.value))}
                />
              </div>
            </div>
          </div>

          <div className="wt-queue-panel">
            <div className="wt-queue-header">Warteschlange ({currentRoom.queue.length})</div>
            <div className="wt-queue-list">
              {currentRoom.queue.length === 0 ? (
                <div className="wt-queue-empty">Keine Videos in der Warteschlange</div>
              ) : (
                currentRoom.queue.map((item, i) => {
                  const isCurrent = currentRoom.currentVideo?.url === item.url;
                  return (
                    <div
                      key={i}
                      className={`wt-queue-item${isCurrent ? ' playing' : ''}${item.watched && !isCurrent ? ' watched' : ''}${isHost ? ' clickable' : ''}`}
                      onClick={() => isHost && wsSend({ type: 'play_video', index: i })}
                      title={isHost ? 'Klicken zum Abspielen' : undefined}
                    >
                      <div className="wt-queue-item-info">
                        {item.watched && !isCurrent && <span className="wt-queue-item-check">{'\u2713'}</span>}
                        {item.url.match(/youtu/) && (
                          <img
                            className="wt-queue-thumb"
                            src={`https://img.youtube.com/vi/${item.url.match(/(?:youtube\.com\/(?:watch\?v=|embed\/|shorts\/)|youtu\.be\/)([a-zA-Z0-9_-]{11})/)?.[1]}/default.jpg`}
                            alt=""
                          />
                        )}
                        <div className="wt-queue-item-text">
                          <div className="wt-queue-item-title">{item.title || item.url}</div>
                          <div className="wt-queue-item-by">{item.addedBy}</div>
                        </div>
                      </div>
                      {isHost && (
                        <button className="wt-queue-item-remove" onClick={(e) => { e.stopPropagation(); removeFromQueue(i); }} title="Entfernen">
                          {'\u00D7'}
                        </button>
                      )}
                    </div>
                  );
                })
              )}
            </div>
            <div className="wt-queue-add">
              <input
                className="wt-input wt-queue-input"
                placeholder="Video-URL eingeben"
                value={queueUrl}
                onChange={e => setQueueUrl(e.target.value)}
                onKeyDown={e => { if (e.key === 'Enter') addToQueue(); }}
              />
              <button className="wt-btn wt-queue-add-btn" onClick={addToQueue} disabled={addingToQueue}>
                {addingToQueue ? 'Laden...' : 'Hinzufuegen'}
              </button>
            </div>
          </div>
        </div>
      </div>
    );
  }

  // ── Render: Lobby ──
  return (
    <div className="wt-container">
      {error && (
        <div className="wt-error">
          {error}
          <button className="wt-error-dismiss" onClick={() => setError(null)}>{'\u00D7'}</button>
        </div>
      )}

      <div className="wt-topbar">
        <input
          className="wt-input wt-input-name"
          placeholder="Dein Name"
          value={userName}
          onChange={e => setUserName(e.target.value)}
        />
        <input
          className="wt-input wt-input-room"
          placeholder="Raumname"
          value={roomName}
          onChange={e => setRoomName(e.target.value)}
        />
        <input
          className="wt-input wt-input-password"
          type="password"
          placeholder="Passwort (optional)"
          value={roomPassword}
          onChange={e => setRoomPassword(e.target.value)}
        />
        <button className="wt-btn" onClick={createRoom}>Raum erstellen</button>
      </div>

      {rooms.length === 0 ? (
        <div className="wt-empty">
          <div className="wt-empty-icon">{'\uD83C\uDFAC'}</div>
          <h3>Keine aktiven Raeume</h3>
          <p>Erstelle einen Raum, um gemeinsam Videos zu schauen.</p>
        </div>
      ) : (
        <div className="wt-grid">
          {rooms.map(room => (
            <div key={room.id} className="wt-tile" onClick={() => handleTileClick(room)}>
              <div className="wt-tile-preview">
                <span className="wt-tile-icon">{'\uD83C\uDFAC'}</span>
                <span className="wt-tile-members">{'\uD83D\uDC65'} {room.memberCount}</span>
                {room.hasPassword && <span className="wt-tile-lock">{'\uD83D\uDD12'}</span>}
                {room.playing && <span className="wt-tile-playing">{'\u25B6'}</span>}
              </div>
              <div className="wt-tile-info">
                <div className="wt-tile-meta">
                  <div className="wt-tile-name">{room.name}</div>
                  <div className="wt-tile-host">{room.hostName}</div>
                </div>
              </div>
            </div>
          ))}
        </div>
      )}

      {joinModal && (
        <div className="wt-modal-overlay" onClick={() => setJoinModal(null)}>
          <div className="wt-modal" onClick={e => e.stopPropagation()}>
            <h3>{joinModal.roomName}</h3>
            <p>Raum-Passwort</p>
            {joinModal.error && <div className="wt-modal-error">{joinModal.error}</div>}
            <input
              className="wt-input"
              type="password"
              placeholder="Passwort"
              value={joinModal.password}
              onChange={e => setJoinModal(prev => prev ? { ...prev, password: e.target.value, error: null } : prev)}
              onKeyDown={e => { if (e.key === 'Enter') submitJoinModal(); }}
              autoFocus
            />
            <div className="wt-modal-actions">
              <button className="wt-modal-cancel" onClick={() => setJoinModal(null)}>Abbrechen</button>
              <button className="wt-btn" onClick={submitJoinModal}>Beitreten</button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}
