import { useRef, useEffect, useState, useCallback } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import Hls from 'hls.js';
import {
  Play,
  Pause,
  Volume2,
  VolumeX,
  Maximize,
  Minimize,
  Settings,
  SkipBack,
  SkipForward,
  ArrowLeft,
  Loader2,
  Wifi,
  Users,
  HardDrive,
  Subtitles,
  AlertTriangle,
  MonitorPlay,
} from 'lucide-react';
import { useNavigate } from 'react-router-dom';
import { clsx } from 'clsx';
import type { Movie, Subtitle } from '../../types';
import type { StreamSession } from '../../services/streaming/streamingService';
import { searchSubtitles, downloadSubtitle, convertSrtToVtt } from '../../services/subtitles/opensubtitles';
import { useSettingsStore } from '../../stores/settingsStore';
import { isCapacitor } from '../../utils/platform';
import { playWithNativePlayer } from '../../plugins/ExoPlayer';
import CastButton from './CastButton';
import { useCast } from '../../hooks/useCast';

interface StreamingPlayerProps {
  movie: Movie;
  streamUrl: string;
  hlsUrl?: string;
  streamSession?: StreamSession | null;
  onTimeUpdate?: (currentTime: number, duration: number) => void;
  initialTime?: number;
}

export default function StreamingPlayer({
  movie,
  streamUrl,
  hlsUrl,
  streamSession,
  onTimeUpdate,
  initialTime = 0,
}: StreamingPlayerProps) {
  const videoRef = useRef<HTMLVideoElement>(null);
  const hlsRef = useRef<Hls | null>(null);
  const containerRef = useRef<HTMLDivElement>(null);
  const controlsTimeoutRef = useRef<NodeJS.Timeout>();
  const currentSourceRef = useRef<string | null>(null); // Track current source to avoid re-setting
  const hasAppliedInitialTimeRef = useRef(false); // Track if initial seek has been applied
  const lastPlaybackPositionRef = useRef<number>(0); // Track last playback position for source switches
  const navigate = useNavigate();

  const [isPlaying, setIsPlaying] = useState(false);
  const [currentTime, setCurrentTime] = useState(0);
  const [duration, setDuration] = useState(0);
  const [volume, setVolume] = useState(1);
  const [isMuted, setIsMuted] = useState(false);
  const [isFullscreen, setIsFullscreen] = useState(false);
  const [showControls, setShowControls] = useState(true);
  const [isBuffering, setIsBuffering] = useState(true);
  const [buffered, setBuffered] = useState(0);
  const [quality, setQuality] = useState('auto');
  const [showSettings, setShowSettings] = useState(false);
  const [showSubtitles, setShowSubtitles] = useState(false);
  const [availableSubtitles, setAvailableSubtitles] = useState<Subtitle[]>([]);
  const [selectedSubtitle, setSelectedSubtitle] = useState<Subtitle | null>(null);
  const [, setSubtitleTrack] = useState<TextTrack | null>(null);
  const [isLoadingSubtitles, setIsLoadingSubtitles] = useState(false);
  const [networkSpeed, setNetworkSpeed] = useState<number>(0);
  const [currentQualityLevel, setCurrentQualityLevel] = useState<string>('auto');
  const [availableQualities, setAvailableQualities] = useState<string[]>(['auto']);
  const [audioWarning, setAudioWarning] = useState<string | null>(null);
  const [audioWarningDismissed, setAudioWarningDismissed] = useState(false);
  const [useNativePlayer, setUseNativePlayer] = useState(false);
  const [isNativePlayerPlaying, setIsNativePlayerPlaying] = useState(false);
  const { settings } = useSettingsStore();

  // Cast integration
  const { castMedia } = useCast();

  // Detect potential audio issues on Android with MKV files and enable native player
  useEffect(() => {
    // Only check on Capacitor (Android) since desktop has FFmpeg transcoding
    if (!isCapacitor()) return;
    
    // Check if this is an MKV file (common for TV shows from EZTV)
    const videoName = streamSession?.videoFile?.name?.toLowerCase() || '';
    const isMkv = videoName.endsWith('.mkv');
    
    if (isMkv && !hlsUrl) {
      // MKV files often have AC3/DTS audio that Android WebView can't play
      // Enable native player option
      setUseNativePlayer(true);
      setAudioWarning(
        'This video uses an MKV format. Click "Play with Native Player" for better audio codec support, or try a different torrent with MP4 format.'
      );
    } else {
      setAudioWarning(null);
      setUseNativePlayer(false);
    }
  }, [streamSession?.videoFile?.name, hlsUrl]);

  // Handle launching native ExoPlayer for better codec support
  const handleNativePlayerLaunch = useCallback(async () => {
    if (!streamUrl) return;
    
    setIsNativePlayerPlaying(true);
    
    // Pause webview video
    if (videoRef.current) {
      videoRef.current.pause();
    }
    
    const title = movie.title || 'Video';
    const startPos = currentTime;
    
    console.log('[NativePlayer] Launching ExoPlayer with URL:', streamUrl);
    
    const result = await playWithNativePlayer(streamUrl, title, startPos);
    
    setIsNativePlayerPlaying(false);
    
    if (result && result.success) {
      console.log('[NativePlayer] Playback ended at:', result.position, 'completed:', result.completed);
      
      // Update current time from native player
      if (result.position > 0) {
        setCurrentTime(result.position);
        if (videoRef.current) {
          videoRef.current.currentTime = result.position;
        }
        // Report time to parent
        if (onTimeUpdate) {
          onTimeUpdate(result.position, result.duration || duration);
        }
      }
      
      // If video completed, navigate back
      if (result.completed) {
        navigate(-1);
      }
    } else {
      console.error('[NativePlayer] Failed to play with native player');
      // Show error and fall back to webview
      setAudioWarning('Native player failed. Using built-in player which may have audio issues with this format.');
    }
  }, [streamUrl, movie.title, currentTime, duration, navigate, onTimeUpdate]);

  // Format time to MM:SS or HH:MM:SS
  const formatTime = (seconds: number): string => {
    if (!isFinite(seconds)) return '0:00';
    const hrs = Math.floor(seconds / 3600);
    const mins = Math.floor((seconds % 3600) / 60);
    const secs = Math.floor(seconds % 60);

    if (hrs > 0) {
      return `${hrs}:${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
    }
    return `${mins}:${secs.toString().padStart(2, '0')}`;
  };

  // Format bytes
  const formatBytes = (bytes: number): string => {
    if (bytes === 0) return '0 B';
    const k = 1024;
    const sizes = ['B', 'KB', 'MB', 'GB'];
    const i = Math.floor(Math.log(bytes) / Math.log(k));
    return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i];
  };

  // Format speed
  const formatSpeed = (bytesPerSecond: number): string => {
    return formatBytes(bytesPerSecond) + '/s';
  };

  // Initialize HLS or direct video
  useEffect(() => {
    const video = videoRef.current;
    if (!video) return;

    // Reset available qualities when source changes
    setAvailableQualities(['auto']);
    setCurrentQualityLevel('auto');
    setQuality('auto');

    const useHls = hlsUrl && Hls.isSupported();

    // Save current playback position before potentially switching sources
    // This prevents the video from jumping back to initialTime when HLS becomes available
    if (video.currentTime > 0 && !video.paused) {
      lastPlaybackPositionRef.current = video.currentTime;
      console.log('[Source] Saving current position before switch:', video.currentTime);
    }

    if (useHls) {
      // Skip if we already have this HLS source loaded
      if (currentSourceRef.current === hlsUrl && hlsRef.current) {
        return;
      }
      
      console.log('Using HLS playback');
      currentSourceRef.current = hlsUrl;
      
      // Cleanup previous HLS instance
      if (hlsRef.current) {
        hlsRef.current.destroy();
      }
      
      const hls = new Hls({
        enableWorker: true,
        lowLatencyMode: false, // Disable for better adaptive streaming
        backBufferLength: 90,
        // Enhanced adaptive bitrate configuration
        abrEwmaDefaultEstimate: 500000, // 500KB/s initial estimate
        abrEwmaSlowVoD: 3, // Slow VoD estimate
        abrEwmaFastVoD: 9, // Fast VoD estimate
        abrEwmaSlowLive: 3, // Slow live estimate
        abrEwmaFastLive: 9, // Fast live estimate
        abrBandWidthFactor: 0.95, // Bandwidth factor
        abrBandWidthUpFactor: 0.7, // Bandwidth up factor
        abrMaxWithRealBitrate: false,
        maxBufferLength: 30, // Max buffer length in seconds
        maxMaxBufferLength: 60, // Max max buffer length
        maxBufferSize: 60 * 1000 * 1000, // 60MB max buffer
        maxBufferHole: 0.5, // Max buffer hole in seconds
        highBufferWatchdogPeriod: 2, // High buffer watchdog period
        nudgeOffset: 0.1, // Nudge offset
        nudgeMaxRetry: 3, // Max retry for nudge
        fragLoadingTimeOut: 20000, // Fragment loading timeout
        manifestLoadingTimeOut: 10000, // Manifest loading timeout
        levelLoadingTimeOut: 10000, // Level loading timeout
        // Enable automatic quality switching
        capLevelToPlayerSize: false, // Don't cap to player size, use network conditions
        startLevel: -1, // Auto-select starting level
        // Network monitoring
        testBandwidth: true,
        progressive: false,
      });

      hls.loadSource(hlsUrl);
      hls.attachMedia(video);

      hls.on(Hls.Events.MANIFEST_PARSED, () => {
        setIsBuffering(false);
        
        // Extract available quality levels from HLS manifest
        const levels = hls.levels;
        const qualities = new Set<string>(['auto']);
        
        levels.forEach((level) => {
          const height = level.height || 0;
          if (height >= 2160) {
            qualities.add('2160p');
          } else if (height >= 1080) {
            qualities.add('1080p');
          } else if (height >= 720) {
            qualities.add('720p');
          } else if (height >= 480) {
            qualities.add('480p');
          } else if (height >= 360) {
            qualities.add('360p');
          }
        });
        
        // Sort qualities (auto first, then highest to lowest)
        const sortedQualities = Array.from(qualities).sort((a, b) => {
          if (a === 'auto') return -1;
          if (b === 'auto') return 1;
          const aNum = parseInt(a) || 0;
          const bNum = parseInt(b) || 0;
          return bNum - aNum;
        });
        
        setAvailableQualities(sortedQualities);
        console.log('[HLS] Available qualities:', sortedQualities);
        
        // Determine the correct seek position:
        // - If we were already playing (source switch), use last playback position
        // - If this is first load and initialTime is set, use that
        // - Otherwise start from beginning
        const seekPosition = lastPlaybackPositionRef.current > 0 
          ? lastPlaybackPositionRef.current 
          : (!hasAppliedInitialTimeRef.current && initialTime > 0 ? initialTime : 0);
        
        if (seekPosition > 0) {
          console.log('[HLS] Seeking to position:', seekPosition);
          video.currentTime = seekPosition;
        }
        hasAppliedInitialTimeRef.current = true;
        video.play().catch(console.error);
      });

      // Monitor quality level changes
      hls.on(Hls.Events.LEVEL_SWITCHED, (_event, data) => {
        const level = hls.levels[data.level];
        if (level) {
          setCurrentQualityLevel(`${level.height}p` || 'auto');
          console.log('Quality switched to:', level.height + 'p');
        }
      });

      // Monitor network speed
      hls.on(Hls.Events.FRAG_LOADED, (_event, data) => {
        if (data.frag) {
          // Try to get stats from the fragment if available
          const frag = data.frag;
          if (frag && 'stats' in frag && frag.stats) {
            const stats = frag.stats as { tload?: number; tfirst?: number };
            if (stats.tload && stats.tfirst) {
              const loadTime = (stats.tload - stats.tfirst) / 1000; // in seconds
              const bytes = (frag as any).loaded || 0;
              if (loadTime > 0 && bytes > 0) {
                const speed = (bytes / loadTime) * 8; // bits per second
                setNetworkSpeed(speed);
              }
            }
          }
        }
      });

      hls.on(Hls.Events.ERROR, (_event, data) => {
        console.error('HLS error:', data);
        if (data.fatal) {
          switch (data.type) {
            case Hls.ErrorTypes.NETWORK_ERROR:
              hls.startLoad();
              break;
            case Hls.ErrorTypes.MEDIA_ERROR:
              hls.recoverMediaError();
              break;
            default:
              hls.destroy();
              break;
          }
        }
      });

      hlsRef.current = hls;

      return () => {
        hls.destroy();
        hlsRef.current = null;
      };
    } else if (video.canPlayType('application/vnd.apple.mpegurl') && hlsUrl) {
      // Safari native HLS - skip if same source
      if (currentSourceRef.current === hlsUrl) {
        return;
      }
      currentSourceRef.current = hlsUrl;
      video.src = hlsUrl;
      video.play().catch(console.error);
    } else if (streamUrl) {
      // Direct video stream - skip if same source
      if (currentSourceRef.current === streamUrl) {
        return;
      }
      
      console.log('Using direct video playback:', streamUrl);
      currentSourceRef.current = streamUrl;
      video.src = streamUrl;
      
      // Set up event handlers only once
      const handleCanPlay = () => {
        console.log('[Video] Can play, starting playback...');
        setIsBuffering(false);
        
        // Determine the correct seek position:
        // - If we were already playing (source switch), use last playback position
        // - If this is first load and initialTime is set, use that
        // - Otherwise start from beginning
        const seekPosition = lastPlaybackPositionRef.current > 0 
          ? lastPlaybackPositionRef.current 
          : (!hasAppliedInitialTimeRef.current && initialTime > 0 ? initialTime : 0);
        
        if (seekPosition > 0) {
          console.log('[Video] Seeking to position:', seekPosition);
          video.currentTime = seekPosition;
        }
        hasAppliedInitialTimeRef.current = true;
        
        video.play().catch((err) => {
          console.warn('[Video] Auto-play blocked:', err.message);
          // Some browsers block autoplay, that's ok - user can click play
          setIsBuffering(false);
        });
      };
      
      const handleLoadedMetadata = () => {
        console.log('[Video] Metadata loaded, duration:', video.duration);
        setDuration(video.duration);
        
        // Check for audio tracks on Android - if no audio tracks detected, show warning
        if (isCapacitor()) {
          const audioTracks = (video as any).audioTracks;
          
          // Log audio tracks info for debugging
          console.log('[Video] Audio tracks:', audioTracks?.length || 'unknown');
          
          if (audioTracks && audioTracks.length === 0) {
            setAudioWarning(
              'No audio track detected. This video file may use an audio codec that Android cannot play. Try a different torrent.'
            );
          }
        }
      };
      
      const handleLoadedData = () => {
        console.log('[Video] Data loaded');
      };
      
      const handleLoadStart = () => {
        console.log('[Video] Load started');
        setIsBuffering(true);
      };
      
      const handleProgress = () => {
        if (video.buffered.length > 0) {
          const bufferedEnd = video.buffered.end(video.buffered.length - 1);
          const bufferedPercent = video.duration > 0 ? (bufferedEnd / video.duration) * 100 : 0;
          setBuffered(bufferedPercent);
        }
      };
      
      const handleError = (_e: Event) => {
        const error = video.error;
        if (error) {
          let errorMsg = 'Unknown error';
          switch (error.code) {
            case error.MEDIA_ERR_ABORTED:
              errorMsg = 'Video loading aborted';
              break;
            case error.MEDIA_ERR_NETWORK:
              errorMsg = 'Network error while loading video';
              break;
            case error.MEDIA_ERR_DECODE:
              errorMsg = 'Video decoding error - codec not supported';
              // If HLS is available, try switching to it
              if (hlsUrl && !hlsRef.current) {
                console.log('[Video] Decode error detected, switching to HLS transcoding...');
                // Save current position before switching
                const currentPosition = video.currentTime > 0 ? video.currentTime : lastPlaybackPositionRef.current;
                // Force HLS playback
                const hls = new Hls({
                  enableWorker: true,
                  lowLatencyMode: false,
                });
                hls.loadSource(hlsUrl);
                hls.attachMedia(video);
                hls.on(Hls.Events.MANIFEST_PARSED, () => {
                  if (currentPosition > 0) {
                    video.currentTime = currentPosition;
                  }
                  video.play().catch(console.error);
                });
                hlsRef.current = hls;
              }
              break;
            case error.MEDIA_ERR_SRC_NOT_SUPPORTED:
              errorMsg = 'Video format not supported';
              // If HLS is available, try switching to it
              if (hlsUrl && !hlsRef.current) {
                console.log('[Video] Format not supported, switching to HLS transcoding...');
                // Save current position before switching
                const currentPosition = video.currentTime > 0 ? video.currentTime : lastPlaybackPositionRef.current;
                const hls = new Hls({
                  enableWorker: true,
                  lowLatencyMode: false,
                });
                hls.loadSource(hlsUrl);
                hls.attachMedia(video);
                hls.on(Hls.Events.MANIFEST_PARSED, () => {
                  if (currentPosition > 0) {
                    video.currentTime = currentPosition;
                  }
                  video.play().catch(console.error);
                });
                hlsRef.current = hls;
              }
              break;
          }
          console.error('[Video] Error:', errorMsg, error);
        }
        setIsBuffering(false);
      };
      
      const handleStalled = () => {
        console.warn('[Video] Loading stalled');
      };
      
      const handleWaiting = () => {
        console.log('[Video] Waiting for data...');
        setIsBuffering(true);
      };
      
      const handlePlaying = () => {
        console.log('[Video] Playing');
        setIsPlaying(true);
        setIsBuffering(false);
      };
      
      const handlePause = () => {
        console.log('[Video] Paused');
        setIsPlaying(false);
      };
      
      video.addEventListener('canplay', handleCanPlay);
      video.addEventListener('loadedmetadata', handleLoadedMetadata);
      video.addEventListener('loadeddata', handleLoadedData);
      video.addEventListener('loadstart', handleLoadStart);
      video.addEventListener('progress', handleProgress);
      video.addEventListener('error', handleError);
      video.addEventListener('stalled', handleStalled);
      video.addEventListener('waiting', handleWaiting);
      video.addEventListener('playing', handlePlaying);
      video.addEventListener('pause', handlePause);
      
      return () => {
        video.removeEventListener('canplay', handleCanPlay);
        video.removeEventListener('loadedmetadata', handleLoadedMetadata);
        video.removeEventListener('loadeddata', handleLoadedData);
        video.removeEventListener('loadstart', handleLoadStart);
        video.removeEventListener('progress', handleProgress);
        video.removeEventListener('error', handleError);
        video.removeEventListener('stalled', handleStalled);
        video.removeEventListener('waiting', handleWaiting);
        video.removeEventListener('playing', handlePlaying);
        video.removeEventListener('pause', handlePause);
      };
    }

    return () => {
      if (hlsRef.current) {
        hlsRef.current.destroy();
      }
    };
    // Note: initialTime intentionally omitted - only used on first load via hasAppliedInitialTimeRef
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [streamUrl, hlsUrl]);

  // Show/hide controls
  const handleMouseMove = useCallback(() => {
    setShowControls(true);
    if (controlsTimeoutRef.current) {
      clearTimeout(controlsTimeoutRef.current);
    }
    controlsTimeoutRef.current = setTimeout(() => {
      if (isPlaying) {
        setShowControls(false);
      }
    }, 3000);
  }, [isPlaying]);

  // Video event handlers
  useEffect(() => {
    const video = videoRef.current;
    if (!video) return;

    const handleTimeUpdate = () => {
      setCurrentTime(video.currentTime);
      // Keep track of playback position for source switches
      if (video.currentTime > 0) {
        lastPlaybackPositionRef.current = video.currentTime;
      }
      onTimeUpdate?.(video.currentTime, video.duration);
    };

    const handleLoadedMetadata = () => {
      setDuration(video.duration);
    };

    const handleProgress = () => {
      if (video.buffered.length > 0) {
        const bufferedEnd = video.buffered.end(video.buffered.length - 1);
        setBuffered((bufferedEnd / video.duration) * 100);
      }
    };

    const handleWaiting = () => setIsBuffering(true);
    const handleCanPlay = () => setIsBuffering(false);
    const handlePlay = () => setIsPlaying(true);
    const handlePause = () => setIsPlaying(false);

    video.addEventListener('timeupdate', handleTimeUpdate);
    video.addEventListener('loadedmetadata', handleLoadedMetadata);
    video.addEventListener('progress', handleProgress);
    video.addEventListener('waiting', handleWaiting);
    video.addEventListener('canplay', handleCanPlay);
    video.addEventListener('play', handlePlay);
    video.addEventListener('pause', handlePause);

    return () => {
      video.removeEventListener('timeupdate', handleTimeUpdate);
      video.removeEventListener('loadedmetadata', handleLoadedMetadata);
      video.removeEventListener('progress', handleProgress);
      video.removeEventListener('waiting', handleWaiting);
      video.removeEventListener('canplay', handleCanPlay);
      video.removeEventListener('play', handlePlay);
      video.removeEventListener('pause', handlePause);
    };
  }, [onTimeUpdate]);

  // Toggle play/pause (defined before keyboard controls to avoid initialization error)
  const togglePlay = useCallback(() => {
    if (videoRef.current) {
      if (isPlaying) {
        videoRef.current.pause();
      } else {
        videoRef.current.play();
      }
    }
  }, [isPlaying]);

  // Toggle fullscreen (defined before keyboard controls to avoid initialization error)
  const toggleFullscreen = useCallback(() => {
    if (!document.fullscreenElement) {
      containerRef.current?.requestFullscreen();
    } else {
      document.exitFullscreen();
    }
  }, []);

  // Keyboard controls
  useEffect(() => {
    const handleKeyDown = (e: KeyboardEvent) => {
      const video = videoRef.current;
      if (!video) return;

      switch (e.key) {
        case ' ':
        case 'k':
          e.preventDefault();
          togglePlay();
          break;
        case 'ArrowLeft':
          e.preventDefault();
          video.currentTime = Math.max(0, video.currentTime - 10);
          break;
        case 'ArrowRight':
          e.preventDefault();
          video.currentTime = Math.min(duration, video.currentTime + 10);
          break;
        case 'ArrowUp':
          e.preventDefault();
          setVolume((v) => Math.min(1, v + 0.1));
          break;
        case 'ArrowDown':
          e.preventDefault();
          setVolume((v) => Math.max(0, v - 0.1));
          break;
        case 'm':
          e.preventDefault();
          setIsMuted((m) => !m);
          break;
        case 'f':
          e.preventDefault();
          toggleFullscreen();
          break;
        case 'c':
          e.preventDefault();
          setShowSubtitles(!showSubtitles);
          break;
        case 'Escape':
          if (isFullscreen) {
            document.exitFullscreen();
          } else {
            navigate(-1);
          }
          break;
      }
    };

    window.addEventListener('keydown', handleKeyDown);
    return () => window.removeEventListener('keydown', handleKeyDown);
  }, [duration, isFullscreen, navigate, togglePlay, toggleFullscreen, showSubtitles]);

  // Load subtitles when movie is available
  useEffect(() => {
    if (!movie?.imdb_code) return;

    const loadSubtitles = async () => {
      setIsLoadingSubtitles(true);
      try {
        const subtitles = await searchSubtitles(movie.imdb_code, settings.preferredLanguage);
        setAvailableSubtitles(subtitles);
        
        // Auto-select preferred language if available
        if (subtitles.length > 0) {
          const preferred = subtitles.find(s => s.language === settings.preferredLanguage) || subtitles[0];
          await selectSubtitle(preferred);
        }
      } catch (error) {
        console.error('Error loading subtitles:', error);
      } finally {
        setIsLoadingSubtitles(false);
      }
    };

    loadSubtitles();
  }, [movie?.imdb_code, settings.preferredLanguage]);

  // Select and load subtitle
  const selectSubtitle = useCallback(async (subtitle: Subtitle) => {
    if (!videoRef.current) return;

    try {
      // Remove existing subtitle tracks
      const existingTracks = Array.from(videoRef.current.querySelectorAll('track'));
      existingTracks.forEach(track => track.remove());
      
      const textTracks = Array.from(videoRef.current.textTracks);
      textTracks.forEach(track => {
        track.mode = 'hidden';
      });

      // Download subtitle
      const subtitleUrl = await downloadSubtitle(subtitle.id);
      if (!subtitleUrl) {
        console.error('Failed to download subtitle');
        return;
      }

      // Fetch and convert subtitle
      const response = await fetch(subtitleUrl);
      const srtContent = await response.text();
      const vttContent = await convertSrtToVtt(srtContent);

      // Create blob URL for subtitle
      const blob = new Blob([vttContent], { type: 'text/vtt' });
      const vttUrl = URL.createObjectURL(blob);

      // Add subtitle track to video using track element
      const trackElement = document.createElement('track');
      trackElement.kind = 'subtitles';
      trackElement.label = subtitle.languageName;
      trackElement.srclang = subtitle.language;
      trackElement.src = vttUrl;
      trackElement.default = true;
      
      videoRef.current.appendChild(trackElement);
      
      // Wait for track to load
      trackElement.addEventListener('load', () => {
        const track = videoRef.current?.textTracks.getTrackById(trackElement.track?.id || '');
        if (track) {
          track.mode = 'showing';
          setSubtitleTrack(track);
        }
      });
      
      setSelectedSubtitle(subtitle);
    } catch (error) {
      console.error('Error loading subtitle:', error);
    }
  }, []);


  // Update volume
  useEffect(() => {
    if (videoRef.current) {
      videoRef.current.volume = volume;
      videoRef.current.muted = isMuted;
    }
  }, [volume, isMuted]);

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

  const handleSeek = (e: React.MouseEvent<HTMLDivElement>) => {
    const rect = e.currentTarget.getBoundingClientRect();
    const pos = (e.clientX - rect.left) / rect.width;
    if (videoRef.current) {
      videoRef.current.currentTime = pos * duration;
    }
  };

  const skip = (seconds: number) => {
    if (videoRef.current) {
      videoRef.current.currentTime = Math.max(
        0,
        Math.min(duration, videoRef.current.currentTime + seconds)
      );
    }
  };

  return (
    <div
      ref={containerRef}
      className="relative w-full h-full bg-black"
      onMouseMove={handleMouseMove}
      onMouseLeave={() => isPlaying && setShowControls(false)}
    >
      {/* Video Element */}
      <video
        ref={videoRef}
        className="w-full h-full"
        onClick={(e) => {
          // Don't toggle play if clicking on controls
          if (e.target === videoRef.current) {
            togglePlay();
          }
        }}
        playsInline
      />

      {/* Audio Warning Banner for Android MKV files with Native Player option */}
      <AnimatePresence>
        {audioWarning && !audioWarningDismissed && useNativePlayer && (
          <motion.div
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
            exit={{ opacity: 0 }}
            className="absolute inset-0 z-50 flex items-center justify-center bg-black/90"
          >
            <div className="max-w-md mx-4 text-center">
              <AlertTriangle size={48} className="text-yellow-500 mx-auto mb-4" />
              <h2 className="text-xl font-bold text-white mb-2">Audio May Not Work</h2>
              <p className="text-gray-300 mb-6">
                This video uses an MKV format with audio codecs that may not play in the browser.
                Use the Native Player for full audio support.
              </p>
              <div className="flex flex-col gap-3">
                <button
                  onClick={handleNativePlayerLaunch}
                  disabled={isNativePlayerPlaying}
                  className="flex items-center justify-center gap-2 px-6 py-3 bg-netflix-red hover:bg-netflix-red-hover rounded-lg font-semibold text-white transition-colors disabled:opacity-50"
                >
                  <MonitorPlay size={20} />
                  {isNativePlayerPlaying ? 'Opening...' : 'Use Native Player (Recommended)'}
                </button>
                <button
                  onClick={() => setAudioWarningDismissed(true)}
                  className="px-6 py-3 bg-white/10 hover:bg-white/20 rounded-lg font-medium text-gray-300 transition-colors"
                >
                  Try Browser Player Anyway
                </button>
              </div>
              <p className="text-gray-500 text-sm mt-4">
                Tip: MP4 torrents usually have better compatibility
              </p>
            </div>
          </motion.div>
        )}
      </AnimatePresence>

      {/* Native Player Loading Overlay */}
      <AnimatePresence>
        {isNativePlayerPlaying && (
          <motion.div
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
            exit={{ opacity: 0 }}
            className="absolute inset-0 flex flex-col items-center justify-center bg-black/80 z-50"
          >
            <Loader2 size={48} className="animate-spin text-netflix-red mb-4" />
            <p className="text-white text-lg">Opening Native Player...</p>
            <p className="text-gray-400 text-sm mt-2">ExoPlayer with full codec support</p>
          </motion.div>
        )}
      </AnimatePresence>
      
      {/* Click outside to close menus */}
      {(showSettings || showSubtitles) && (
        <div
          className="fixed inset-0 z-40"
          onClick={() => {
            setShowSettings(false);
            setShowSubtitles(false);
          }}
        />
      )}

      {/* Buffering Indicator */}
      <AnimatePresence>
        {isBuffering && (
          <motion.div
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
            exit={{ opacity: 0 }}
            className="absolute inset-0 flex flex-col items-center justify-center bg-black/50"
          >
            <Loader2 size={48} className="animate-spin text-netflix-red mb-4" />
            {streamSession && streamSession.status === 'downloading' && (
              <div className="text-center">
                <p className="text-lg mb-2">Buffering...</p>
                <p className="text-sm text-gray-400">
                  {(streamSession.progress * 100).toFixed(1)}% downloaded
                </p>
              </div>
            )}
          </motion.div>
        )}
      </AnimatePresence>

      {/* Controls Overlay */}
      <AnimatePresence>
        {showControls && (
          <motion.div
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
            exit={{ opacity: 0 }}
            transition={{ duration: 0.2 }}
            className="absolute inset-0 flex flex-col justify-between"
          >
            {/* Top Bar */}
            <div className="bg-gradient-to-b from-black/80 to-transparent p-4 flex items-center gap-4">
              <button
                onClick={() => navigate(-1)}
                className="p-2 hover:bg-white/10 rounded-full transition-colors"
              >
                <ArrowLeft size={24} />
              </button>
              <div className="flex-1">
                <h1 className="text-xl font-semibold">{movie.title}</h1>
                <p className="text-sm text-gray-400">{movie.year}</p>
              </div>
              
              {/* Stream Stats */}
              {streamSession && (
                <div className="flex items-center gap-4 text-xs text-gray-400">
                  <span className="flex items-center gap-1">
                    <Wifi size={14} className="text-green-400" />
                    {formatSpeed(streamSession.downloadSpeed)}
                  </span>
                  <span className="flex items-center gap-1">
                    <Users size={14} />
                    {streamSession.peers}
                  </span>
                  <span className="flex items-center gap-1">
                    <HardDrive size={14} />
                    {formatBytes(streamSession.downloaded)}
                  </span>
                </div>
              )}
            </div>

            {/* Center Play Button */}
            <div className="flex-1 flex items-center justify-center">
              {!isBuffering && (
                <motion.button
                  whileHover={{ scale: 1.1 }}
                  whileTap={{ scale: 0.9 }}
                  onClick={togglePlay}
                  className="w-20 h-20 rounded-full bg-white/20 backdrop-blur-sm flex items-center justify-center"
                >
                  {isPlaying ? (
                    <Pause size={40} fill="white" />
                  ) : (
                    <Play size={40} fill="white" className="ml-1" />
                  )}
                </motion.button>
              )}
            </div>

            {/* Bottom Controls */}
            <div className="bg-gradient-to-t from-black/80 to-transparent p-4 space-y-3">
              {/* Download Progress (if still downloading) */}
              {streamSession && streamSession.progress < 1 && (
                <div className="flex items-center gap-2 text-xs text-gray-400">
                  <div className="flex-1 h-1 bg-white/20 rounded-full overflow-hidden">
                    <div
                      className="h-full bg-blue-500 rounded-full transition-all"
                      style={{ width: `${streamSession.progress * 100}%` }}
                    />
                  </div>
                  <span>{(streamSession.progress * 100).toFixed(0)}% buffered</span>
                </div>
              )}

              {/* Progress Bar */}
              <div
                className="relative h-1 bg-white/20 rounded-full cursor-pointer group"
                onClick={handleSeek}
              >
                {/* Buffered */}
                <div
                  className="absolute h-full bg-white/30 rounded-full"
                  style={{ width: `${buffered}%` }}
                />
                {/* Progress */}
                <div
                  className="absolute h-full bg-netflix-red rounded-full"
                  style={{ width: `${(currentTime / duration) * 100 || 0}%` }}
                />
                {/* Scrubber */}
                <div
                  className="absolute top-1/2 -translate-y-1/2 w-4 h-4 bg-netflix-red rounded-full opacity-0 group-hover:opacity-100 transition-opacity"
                  style={{ left: `calc(${(currentTime / duration) * 100 || 0}% - 8px)` }}
                />
              </div>

              {/* Controls Row */}
              <div className="flex items-center justify-between">
                <div className="flex items-center gap-2">
                  {/* Play/Pause */}
                  <button
                    onClick={togglePlay}
                    className="p-2 hover:bg-white/10 rounded-full transition-colors"
                  >
                    {isPlaying ? <Pause size={24} /> : <Play size={24} />}
                  </button>

                  {/* Skip Back */}
                  <button
                    onClick={() => skip(-10)}
                    className="p-2 hover:bg-white/10 rounded-full transition-colors"
                  >
                    <SkipBack size={20} />
                  </button>

                  {/* Skip Forward */}
                  <button
                    onClick={() => skip(10)}
                    className="p-2 hover:bg-white/10 rounded-full transition-colors"
                  >
                    <SkipForward size={20} />
                  </button>

                  {/* Volume */}
                  <div className="flex items-center gap-2 group/vol">
                    <button
                      onClick={() => setIsMuted(!isMuted)}
                      className="p-2 hover:bg-white/10 rounded-full transition-colors"
                    >
                      {isMuted || volume === 0 ? (
                        <VolumeX size={20} />
                      ) : (
                        <Volume2 size={20} />
                      )}
                    </button>
                    <input
                      type="range"
                      min="0"
                      max="1"
                      step="0.1"
                      value={isMuted ? 0 : volume}
                      onChange={(e) => {
                        setVolume(parseFloat(e.target.value));
                        setIsMuted(false);
                      }}
                      className="w-20 accent-netflix-red opacity-0 group-hover/vol:opacity-100 transition-opacity"
                    />
                  </div>

                  {/* Time */}
                  <span className="text-sm ml-2">
                    {formatTime(currentTime)} / {formatTime(duration)}
                  </span>
                </div>

                <div className="flex items-center gap-2">
                  {/* Subtitles */}
                  <div className="relative">
                    <button
                      onClick={() => setShowSubtitles(!showSubtitles)}
                      className={clsx(
                        'p-2 hover:bg-white/10 rounded-full transition-colors',
                        selectedSubtitle && 'text-netflix-red'
                      )}
                      title="Subtitles"
                    >
                      <Subtitles size={20} />
                    </button>
                    
                    {showSubtitles && (
                      <div className="absolute bottom-full right-0 mb-2 p-3 bg-black/95 rounded-lg min-w-[200px] max-h-[300px] overflow-y-auto z-50">
                        <p className="text-xs text-gray-400 mb-2 font-semibold">Subtitles</p>
                        {isLoadingSubtitles ? (
                          <div className="flex items-center gap-2 py-2">
                            <Loader2 size={14} className="animate-spin" />
                            <span className="text-xs text-gray-400">Loading...</span>
                          </div>
                        ) : availableSubtitles.length === 0 ? (
                          <p className="text-xs text-gray-500 py-2">No subtitles available</p>
                        ) : (
                          <>
                            <button
                              onClick={() => {
                                if (videoRef.current) {
                                  const tracks = Array.from(videoRef.current.textTracks);
                                  tracks.forEach(track => {
                                    track.mode = 'hidden';
                                  });
                                  setSelectedSubtitle(null);
                                  setSubtitleTrack(null);
                                }
                                setShowSubtitles(false);
                              }}
                              className={clsx(
                                'block w-full text-left px-3 py-1.5 rounded hover:bg-white/10 text-xs',
                                !selectedSubtitle && 'text-netflix-red'
                              )}
                            >
                              Off
                            </button>
                            {availableSubtitles.map((sub) => (
                              <button
                                key={sub.id}
                                onClick={async () => {
                                  await selectSubtitle(sub);
                                  setShowSubtitles(false);
                                }}
                                className={clsx(
                                  'block w-full text-left px-3 py-1.5 rounded hover:bg-white/10 text-xs',
                                  selectedSubtitle?.id === sub.id && 'text-netflix-red'
                                )}
                              >
                                {sub.languageName}
                              </button>
                            ))}
                          </>
                        )}
                      </div>
                    )}
                  </div>

                  {/* Settings */}
                  <div className="relative">
                    <button 
                      onClick={() => setShowSettings(!showSettings)}
                      className="p-2 hover:bg-white/10 rounded-full transition-colors"
                    >
                      <Settings size={20} />
                    </button>
                    
                    {showSettings && (
                      <div className="absolute bottom-full right-0 mb-2 p-3 bg-black/95 rounded-lg min-w-[200px] z-50">
                        <p className="text-xs text-gray-400 mb-2 font-semibold">Quality</p>
                        {hlsRef.current ? (
                          // HLS stream - show available qualities
                          availableQualities.map((q) => {
                            const isAvailable = q === 'auto' || availableQualities.includes(q);
                            return (
                              <button
                                key={q}
                                onClick={() => {
                                  if (!isAvailable) return;
                                  
                                  setQuality(q);
                                  if (q !== 'auto') {
                                    // Manual quality selection - find exact or closest match
                                    const levels = hlsRef.current!.levels;
                                    const targetHeight = parseInt(q) || 0;
                                    
                                    // Find the level with the closest height to target
                                    let bestMatch = -1;
                                    let bestDiff = Infinity;
                                    
                                    levels.forEach((level, index) => {
                                      const height = level.height || 0;
                                      const diff = Math.abs(height - targetHeight);
                                      
                                      // Prefer exact match or closest below target
                                      if (height <= targetHeight && diff < bestDiff) {
                                        bestMatch = index;
                                        bestDiff = diff;
                                      }
                                    });
                                    
                                    if (bestMatch !== -1) {
                                      hlsRef.current!.currentLevel = bestMatch;
                                      console.log(`[HLS] Switched to quality: ${q} (level ${bestMatch})`);
                                    } else {
                                      console.warn(`[HLS] Quality ${q} not available`);
                                    }
                                  } else {
                                    // Auto quality
                                    hlsRef.current!.currentLevel = -1;
                                    console.log('[HLS] Switched to auto quality');
                                  }
                                  setShowSettings(false);
                                }}
                                disabled={!isAvailable}
                                className={clsx(
                                  'block w-full text-left px-3 py-1.5 rounded hover:bg-white/10 text-xs transition-colors',
                                  quality === q && 'text-netflix-red font-semibold',
                                  !isAvailable && 'opacity-50 cursor-not-allowed'
                                )}
                              >
                                {q === 'auto' ? `Auto (${currentQualityLevel})` : q}
                              </button>
                            );
                          })
                        ) : (
                          // Direct stream - quality selection not available
                          <div className="px-3 py-1.5 text-xs text-gray-500">
                            Quality selection not available for direct streams
                          </div>
                        )}
                        {networkSpeed > 0 && (
                          <div className="mt-2 pt-2 border-t border-white/10">
                            <p className="text-xs text-gray-500">
                              Network: {formatSpeed(networkSpeed / 8)}
                            </p>
                          </div>
                        )}
                      </div>
                    )}
                  </div>

                  {/* Cast Button */}
                  <CastButton
                    size={20}
                    onCastStart={() => {
                      // Cast the current stream
                      const streamTocast = hlsUrl || streamUrl;
                      if (streamTocast) {
                        castMedia({
                          url: streamTocast,
                          title: movie.title,
                          subtitle: `${movie.year} • ${movie.runtime} min`,
                          imageUrl: movie.large_cover_image || movie.medium_cover_image,
                          startTime: currentTime,
                        });
                        // Pause local playback when casting starts
                        videoRef.current?.pause();
                      }
                    }}
                    onCastEnd={() => {
                      // Resume local playback when casting ends
                      videoRef.current?.play();
                    }}
                  />

                  {/* Fullscreen */}
                  <button
                    onClick={toggleFullscreen}
                    className="p-2 hover:bg-white/10 rounded-full transition-colors"
                  >
                    {isFullscreen ? <Minimize size={20} /> : <Maximize size={20} />}
                  </button>
                </div>
              </div>
            </div>
          </motion.div>
        )}
      </AnimatePresence>
    </div>
  );
}

