'use client';

import React, { useRef, useEffect, useState, useCallback } from 'react';
import Hls from 'hls.js';
import { motion, AnimatePresence } from 'framer-motion';
import {
  FiPlay, FiPause, FiMaximize, FiMinimize,
  FiVolume2, FiVolumeX, FiSettings, FiRotateCcw,
  FiAlertTriangle, FiChevronLeft, FiChevronRight, FiCheck,
} from 'react-icons/fi';
import Spinner from '@/components/ui/Spinner';
import { cn, formatTime } from '@/lib/utils';
import { PLAYBACK_SPEEDS, QUALITIES, CONTROLS_HIDE_DELAY } from '@/lib/constants';
import { useProfileStore } from '@/stores/profileStore';
import { usePlayerStore } from '@/stores/playerStore';
import { useRouter } from 'next/navigation';
import { useMultiStreamStore } from '@/stores/multiStreamStore';
import MultiStreamPlayer from './MultiStreamPlayer';
import AddStreamModal from './AddStreamModal';

const PictureInPictureIcon = ({ size = 18 }: { size?: number }) => (
  <svg
    width={size}
    height={size}
    viewBox="0 0 24 24"
    fill="none"
    stroke="currentColor"
    strokeWidth="2.2"
    strokeLinecap="round"
    strokeLinejoin="round"
  >
    <rect width="18" height="13" x="3" y="4" rx="2" />
    <rect width="8" height="6" x="13" y="11" rx="1" fill="currentColor" />
  </svg>
);

interface VideoPlayerProps {
  streamUrl: string;
  title: string;
  poster?: string;
  onProgress?: (time: number, duration: number) => void;
  autoPlay?: boolean;
  muted?: boolean;
  contentId?: string;
  contentType?: 'movie' | 'series' | 'live';
  categoryId?: string;
  seriesId?: string;
  isMini?: boolean;
  isMultiViewChild?: boolean;
}

function SingleVideoPlayer({
  streamUrl,
  title,
  poster,
  onProgress,
  autoPlay = false,
  muted = false,
  contentId,
  contentType,
  categoryId,
  seriesId,
  isMini = false,
  isMultiViewChild = false,
}: VideoPlayerProps) {
  const videoRef = useRef<HTMLVideoElement>(null);
  const containerRef = useRef<HTMLDivElement>(null);
  const router = useRouter();
  const hlsRef = useRef<Hls | null>(null);
  const controlsTimerRef = useRef<NodeJS.Timeout | null>(null);
  
  const [isModalOpen, setIsModalOpen] = useState(false);
  const { isActive: multiActive, streams, startMultiStream, addStream, pendingResume } = useMultiStreamStore();
  const progressRef = useRef<HTMLDivElement>(null);
  const lastSavedTimeRef = useRef<number>(0);

  const { saveProgress, getProgress, clearProgress } = useProfileStore();
  const isMinimized = usePlayerStore((state) => state.isMinimized);

  const [showResumeBanner, setShowResumeBanner] = useState(false);
  const [resumeTime, setResumeTime] = useState(0);

  const [isPlaying, setIsPlaying] = useState(false);
  const [currentTime, setCurrentTime] = useState(0);
  const [duration, setDuration] = useState(0);
  const [volume, setVolume] = useState(1);
  const [isMuted, setIsMuted] = useState(muted);
  const [isFullscreen, setIsFullscreen] = useState(false);

  // Seamless auto-resume when closing multi-screen
  useEffect(() => {
    const video = videoRef.current;
    if (!video || !streamUrl || !pendingResume) return;

    if (pendingResume.url === streamUrl) {
      const resumeInfo = pendingResume;
      // Clear immediately to avoid loops
      useMultiStreamStore.setState({ pendingResume: null });

      const handleResume = () => {
        video.currentTime = resumeInfo.time;
        if (resumeInfo.isPlaying) {
          video.play().catch(() => {});
          setIsPlaying(true);
        }
        video.removeEventListener('loadedmetadata', handleResume);
      };

      video.addEventListener('loadedmetadata', handleResume);
      
      // Fallback in case loadedmetadata already fired
      if (video.readyState >= 1) {
        handleResume();
      }
    }
  }, [streamUrl, pendingResume]);

  // Sync with muted prop changes
  useEffect(() => {
    setIsMuted(muted);
    const video = videoRef.current;
    if (video) {
      video.muted = muted;
    }
  }, [muted]);
  const [isBuffering, setIsBuffering] = useState(true);
  const [showControls, setShowControls] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [playbackSpeed, setPlaybackSpeed] = useState(1);
  const [showSettings, setShowSettings] = useState(false);
  const [quality, setQuality] = useState('Auto');
  const [audioTracks, setAudioTracks] = useState<{ id: number; name: string; lang: string }[]>([]);
  const [activeAudioTrack, setActiveAudioTrack] = useState(-1);
  const [subtitleTracks, setSubtitleTracks] = useState<{ id: number; name: string; lang: string }[]>([]);
  const [activeSubtitleTrack, setActiveSubtitleTrack] = useState(-1);
  const [useNativeFallback, setUseNativeFallback] = useState(false);
  const [settingsView, setSettingsView] = useState<'main' | 'quality' | 'speed' | 'audio' | 'subtitles'>('main');
  const [isPiP, setIsPiP] = useState(false);
  const [pipSupported, setPipSupported] = useState(true);

  // Sync initial playback time from player store if available (e.g. for PiP transitions)
  const isTimeSyncedRef = useRef(false);
  useEffect(() => {
    isTimeSyncedRef.current = false;
  }, [streamUrl]);
  // Keyboard shortcuts
  useEffect(() => {
    const handleKeyDown = (e: KeyboardEvent) => {
      // Ignore if user is typing in an input/textarea
      const activeEl = document.activeElement;
      if (activeEl && (activeEl.tagName === 'INPUT' || activeEl.tagName === 'TEXTAREA')) {
        return;
      }

      const video = videoRef.current;
      if (!video) return;

      switch (e.key) {
        case ' ':
          e.preventDefault();
          togglePlay();
          break;
        case 'f':
        case 'F':
          e.preventDefault();
          toggleFullscreen();
          break;
        case 'm':
        case 'M':
          e.preventDefault();
          toggleMute();
          break;
        case 'ArrowRight':
          e.preventDefault();
          video.currentTime = Math.min(video.duration || 0, video.currentTime + 10);
          break;
        case 'ArrowLeft':
          e.preventDefault();
          video.currentTime = Math.max(0, video.currentTime - 10);
          break;
        case 'ArrowUp':
          e.preventDefault();
          const upVol = Math.min(1, video.volume + 0.05);
          video.volume = upVol;
          setVolume(upVol);
          setIsMuted(false);
          break;
        case 'ArrowDown':
          e.preventDefault();
          const downVol = Math.max(0, video.volume - 0.05);
          video.volume = downVol;
          setVolume(downVol);
          if (downVol === 0) {
            setIsMuted(true);
          }
          break;
        default:
          break;
      }
    };

    window.addEventListener('keydown', handleKeyDown);
    return () => {
      window.removeEventListener('keydown', handleKeyDown);
    };
  }, []);
  useEffect(() => {
    if (!duration) return;
    if (isTimeSyncedRef.current) return;

    // Skip time synchronization for live TV streams (since they are real-time and shouldn't seek)
    const isLiveStream = (streamUrl && streamUrl.includes('/live/')) || contentType === 'live';
    if (isLiveStream) {
      isTimeSyncedRef.current = true;
      return;
    }

    const video = videoRef.current;
    if (!video) return;

    const activeVideo = usePlayerStore.getState().activeVideo;
    if (activeVideo && activeVideo.contentId === (contentId || streamUrl) && activeVideo.currentTime) {
      const diff = Math.abs(video.currentTime - activeVideo.currentTime);
      if (diff > 2) {
        video.currentTime = activeVideo.currentTime;
        // Force play request after seeking to resume playback in full size
        video.play().catch(() => {});
      }
      isTimeSyncedRef.current = true;
    }
  }, [streamUrl, duration, contentId, contentType]);

  // Cleanup effect: Close video player if unmounting without active PiP
  useEffect(() => {
    return () => {
      if (typeof window === 'undefined') return;
      const activeVideo = usePlayerStore.getState().activeVideo;
      const isPipActive = usePlayerStore.getState().isPipActive;
      
      if (activeVideo && activeVideo.contentId === (contentId || streamUrl) && !isPipActive) {
        const pathname = window.location.pathname;
        const isMoviePage = activeVideo.contentType === 'movie' && pathname === `/movies/${activeVideo.contentId}`;
        const isSeriesPage = activeVideo.contentType === 'series' && pathname === `/series/${activeVideo.seriesId || activeVideo.contentId}`;
        const isTvPage = activeVideo.contentType === 'live' && pathname === `/tv/${activeVideo.contentId}`;
        
        if (!isMoviePage && !isSeriesPage && !isTvPage) {
          usePlayerStore.getState().closeVideo();
        }
      }
    };
  }, [contentId, streamUrl]);

  // Listen to enter/leave Picture in Picture events
  useEffect(() => {
    const video = videoRef.current;
    if (!video) return;

    const handleEnterPiP = () => setIsPiP(true);
    const handleLeavePiP = () => setIsPiP(false);

    video.addEventListener('enterpictureinpicture', handleEnterPiP);
    video.addEventListener('leavepictureinpicture', handleLeavePiP);

    return () => {
      video.removeEventListener('enterpictureinpicture', handleEnterPiP);
      video.removeEventListener('leavepictureinpicture', handleLeavePiP);
    };
  }, []);

  // Load saved watch progress on metadata loaded (resume feature)
  useEffect(() => {
    if (!duration || !streamUrl) return;

    // Do not save or load progress for live streams
    const isLiveStream = streamUrl.includes('/live/');
    if (isLiveStream) return;

    // If this is a PiP maximize transition, activeVideo in the store has the most up-to-date currentTime.
    // We should skip profile progress seek and let the activeVideo time sync effect handle it to avoid double seeking!
    // If transitioning from PiP, activeVideo already has the synchronized time. Skip profile sync to avoid double seeking
    const activeVideo = usePlayerStore.getState().activeVideo;
    const isPipTransition = activeVideo && activeVideo.contentId === (contentId || streamUrl) && activeVideo.currentTime;
    if (isPipTransition) {
      lastSavedTimeRef.current = activeVideo.currentTime || 0;
      return;
    }

    const progress = getProgress(contentId || streamUrl);
    if (progress && progress.currentTime > 10 && progress.currentTime < progress.duration - 15) {
      setResumeTime(progress.currentTime);
      setShowResumeBanner(true);
      
      const video = videoRef.current;
      if (video) {
        video.currentTime = progress.currentTime;
        lastSavedTimeRef.current = progress.currentTime;
      }

      // Hide resume banner after 6 seconds
      const timer = setTimeout(() => {
        setShowResumeBanner(false);
      }, 6000);
      return () => clearTimeout(timer);
    } else {
      setShowResumeBanner(false);
      setResumeTime(0);
    }
  }, [streamUrl, duration, contentId, getProgress]);

  // Reset settings view when settings menu is closed
  useEffect(() => {
    if (!showSettings) {
      setSettingsView('main');
    }
  }, [showSettings]);

  // Reset native fallback when stream URL changes
  useEffect(() => {
    console.log('🎬 Player Stream URL changed. Resetting native fallback to false. URL:', streamUrl);
    setUseNativeFallback(false);
  }, [streamUrl]);

  // Initialize HLS
  useEffect(() => {
    const video = videoRef.current;
    if (!video || !streamUrl) {
      console.warn('⚠️ Player Init skipped: video element or streamUrl is missing');
      return;
    }

    console.log('🎬 Player Init Effect - URL:', streamUrl, 'useNativeFallback:', useNativeFallback);

    setError(null);
    setIsBuffering(true);
    setAudioTracks([]);
    setActiveAudioTrack(-1);
    setSubtitleTracks([]);
    setActiveSubtitleTrack(-1);

    // Self-healing URLs: Check if it's a direct VOD (movie/series) link
    const isMovieOrSeriesDirect = 
      (streamUrl.includes('/movie/') || streamUrl.includes('/series/')) && 
      !streamUrl.toLowerCase().includes('.m3u8');

    let primaryUrl = streamUrl;
    let fallbackUrl: string | null = null;

    if (isMovieOrSeriesDirect) {
      const lastSlash = streamUrl.lastIndexOf('/');
      const lastDot = streamUrl.lastIndexOf('.');
      if (lastDot !== -1 && lastDot > lastSlash) {
        primaryUrl = streamUrl.substring(0, lastDot) + '.m3u8';
        fallbackUrl = streamUrl;
        console.log('🔮 Direct VOD detected. Trying HLS (.m3u8) first:', primaryUrl, 'Fallback progressive:', fallbackUrl);
      }
    }

    const playUrl = useNativeFallback ? (fallbackUrl || streamUrl) : primaryUrl;
    const isHls = playUrl.toLowerCase().includes('.m3u8') || (playUrl.includes('/live/') && !useNativeFallback);

    if (isHls && Hls.isSupported()) {
      console.log('📡 Initializing HLS.js for URL:', playUrl);
      const hls = new Hls({
        enableWorker: true,
        lowLatencyMode: true,
        manifestLoadingTimeOut: isMovieOrSeriesDirect ? 1000 : 10000,
        manifestLoadingMaxRetry: isMovieOrSeriesDirect ? 0 : 3,
        manifestLoadingRetryDelay: isMovieOrSeriesDirect ? 0 : 1000,
      });
      hlsRef.current = hls;
      hls.loadSource(playUrl);
      hls.attachMedia(video);

      hls.on(Hls.Events.MANIFEST_PARSED, () => {
        console.log('✅ HLS Manifest Parsed successfully');
        setIsBuffering(false);
        
        // Extract audio tracks
        const tracks = hls.audioTracks.map((t, idx) => ({
          id: idx,
          name: t.name || t.lang || `Audio ${idx + 1}`,
          lang: t.lang || ''
        }));
        setAudioTracks(tracks);
        setActiveAudioTrack(hls.audioTrack);

        // Extract subtitle tracks
        const subs = hls.subtitleTracks.map((t, idx) => ({
          id: idx,
          name: t.name || t.lang || `Subtítulo ${idx + 1}`,
          lang: t.lang || ''
        }));
        setSubtitleTracks(subs);
        setActiveSubtitleTrack(hls.subtitleTrack);

        if (autoPlay) {
          video.play().catch((err) => console.warn('⚠️ HLS autoPlay failed:', err.message));
        }
      });

      hls.on(Hls.Events.AUDIO_TRACKS_UPDATED, () => {
        setAudioTracks(hls.audioTracks.map((t, idx) => ({
          id: idx,
          name: t.name || t.lang || `Audio ${idx + 1}`,
          lang: t.lang || ''
        })));
      });

      hls.on(Hls.Events.SUBTITLE_TRACKS_UPDATED, () => {
        setSubtitleTracks(hls.subtitleTracks.map((t, idx) => ({
          id: idx,
          name: t.name || t.lang || `Subtítulo ${idx + 1}`,
          lang: t.lang || ''
        })));
      });

      hls.on(Hls.Events.AUDIO_TRACK_SWITCHED, () => {
        setActiveAudioTrack(hls.audioTrack);
      });

      hls.on(Hls.Events.SUBTITLE_TRACK_SWITCH, () => {
        setActiveSubtitleTrack(hls.subtitleTrack);
      });

      hls.on(Hls.Events.ERROR, (_, data) => {
        if (data.fatal) {
          console.error('❌ Fatal HLS Error:', data.type, 'Details:', data.details);
          
          if (fallbackUrl) {
            console.log('🚨 HLS failed. Triggering native fallback immediately to:', fallbackUrl);
            setUseNativeFallback(true);
          } else {
            // No fallback (e.g. Live TV channel). Try standard recovery or set error.
            switch (data.type) {
              case Hls.ErrorTypes.NETWORK_ERROR:
                console.warn('HLS Network error. Retrying load...');
                hls.startLoad();
                break;
              case Hls.ErrorTypes.MEDIA_ERROR:
                console.warn('HLS Media error. Recovering...');
                hls.recoverMediaError();
                break;
              default:
                setError('Error al cargar el stream.');
                hls.destroy();
                break;
            }
          }
        }
      });

      return () => {
        console.log('🧹 Cleaning up HLS.js player instance');
        hls.destroy();
        hlsRef.current = null;
      };
    } else {
      console.log('🎞️ Initializing Native Progressive Player for URL:', playUrl);
      video.src = playUrl;
      video.load();
      
      const onLoadedMetadata = () => {
        console.log('✅ Native Progressive Metadata loaded successfully');
        setIsBuffering(false);
        
        // Extract native audio tracks if supported (e.g. Safari)
        const nativeAudioList: any[] = [];
        const audioList = (video as any).audioTracks;
        if (audioList) {
          for (let i = 0; i < audioList.length; i++) {
            const track = audioList[i];
            nativeAudioList.push({
              id: i,
              name: track.label || track.language || `Audio ${i + 1}`,
              lang: track.language || ''
            });
          }
          setAudioTracks(nativeAudioList);
          const activeAud = nativeAudioList.findIndex(t => audioList[t.id].enabled);
          setActiveAudioTrack(activeAud);
        }

        // Extract text tracks (subtitles)
        const nativeTracks: any[] = [];
        for (let i = 0; i < video.textTracks.length; i++) {
          const track = video.textTracks[i];
          nativeTracks.push({
            id: i,
            name: track.label || track.language || `Subtítulo ${i + 1}`,
            lang: track.language || ''
          });
        }
        setSubtitleTracks(nativeTracks);
        const activeSub = nativeTracks.findIndex(t => video.textTracks[t.id].mode === 'showing');
        setActiveSubtitleTrack(activeSub);

        if (autoPlay) {
          video.play().catch((err) => console.warn('⚠️ Native autoPlay failed:', err.message));
        }
      };

      const onNativeError = () => {
        console.error('🚨 Native video tag error code:', video.error?.code, 'Message:', video.error?.message);
        setError(`Error al reproducir el video (Código ${video.error?.code || 'desconocido'}).`);
        setIsBuffering(false);
      };

      video.addEventListener('loadedmetadata', onLoadedMetadata);
      video.addEventListener('error', onNativeError);

      return () => {
        console.log('🧹 Cleaning up Native Progressive player source');
        video.removeEventListener('loadedmetadata', onLoadedMetadata);
        video.removeEventListener('error', onNativeError);
        video.src = '';
      };
    }
  }, [streamUrl, autoPlay, useNativeFallback]);

  // Sync active video to player store when props change (ensures instant store updates)
  useEffect(() => {
    if (!streamUrl) return;
    if (isMini) return;

    const currentActive = usePlayerStore.getState().activeVideo;
    const sameContent = currentActive && currentActive.contentId === (contentId || streamUrl);

    usePlayerStore.getState().playVideo({
      streamUrl,
      title,
      poster,
      contentId: contentId || streamUrl,
      contentType: contentType === 'live' ? 'live' : (contentType || 'movie'),
      categoryId,
      seriesId,
      currentTime: sameContent ? (currentActive.currentTime || 0) : 0,
      duration: sameContent ? (currentActive.duration || 0) : 0
    });
  }, [streamUrl, contentId, isMini, title, poster, contentType, categoryId, seriesId]);

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

    const onPlay = () => {
      setIsPlaying(true);
      const activeVideo = usePlayerStore.getState().activeVideo;
      if (!activeVideo || activeVideo.contentId !== (contentId || streamUrl)) {
        usePlayerStore.getState().playVideo({
          streamUrl,
          title,
          poster,
          contentId: contentId || streamUrl,
          contentType: contentType === 'live' ? 'live' : (contentType || 'movie'),
          categoryId,
          seriesId,
          currentTime: video.currentTime,
          duration: video.duration
        });
      } else {
        usePlayerStore.getState().setIsPlaying(true);
      }
    };
    const onPause = () => {
      setIsPlaying(false);
      const activeVideo = usePlayerStore.getState().activeVideo;
      if (activeVideo && activeVideo.contentId === (contentId || streamUrl)) {
        usePlayerStore.getState().setIsPlaying(false);
      }
    };
    const onTimeUpdate = () => {
      const time = video.currentTime;
      setCurrentTime(time);
      onProgress?.(time, video.duration);

      const activeVideo = usePlayerStore.getState().activeVideo;
      if (activeVideo && activeVideo.contentId === (contentId || streamUrl)) {
        usePlayerStore.getState().updateTime(time, video.duration || 0);
      }

      // Save progress every 5 seconds for non-live streams
      const isLiveStream = streamUrl.includes('/live/');
      if (!isLiveStream && video.duration > 0 && Math.abs(time - lastSavedTimeRef.current) > 5) {
        lastSavedTimeRef.current = time;
        
        // Infer content type
        const isSeries = contentType === 'series' || title.includes('— T') || title.toLowerCase().includes('temporada');
        const type = isSeries ? 'series' : 'movie';
        
        // Category routing
        const catId = categoryId || (streamUrl.includes('/movie/') ? 'movies' : streamUrl.includes('/series/') ? 'series' : '0');

        saveProgress(
          contentId || streamUrl,
          type,
          title,
          poster || '',
          streamUrl,
          catId,
          time,
          video.duration,
          seriesId ? { seriesId } : undefined
        );
      }
    };
    const onDurationChange = () => setDuration(video.duration || 0);
    const onWaiting = () => setIsBuffering(true);
    const onCanPlay = () => setIsBuffering(false);
    const onEnded = () => {
      setIsPlaying(false);
      clearProgress(contentId || streamUrl);
    };

    video.addEventListener('play', onPlay);
    video.addEventListener('pause', onPause);
    video.addEventListener('timeupdate', onTimeUpdate);
    video.addEventListener('durationchange', onDurationChange);
    video.addEventListener('waiting', onWaiting);
    video.addEventListener('canplay', onCanPlay);
    video.addEventListener('ended', onEnded);

    return () => {
      video.removeEventListener('play', onPlay);
      video.removeEventListener('pause', onPause);
      video.removeEventListener('timeupdate', onTimeUpdate);
      video.removeEventListener('durationchange', onDurationChange);
      video.removeEventListener('waiting', onWaiting);
      video.removeEventListener('canplay', onCanPlay);
      video.removeEventListener('ended', onEnded);
    };
  }, [onProgress]);

  const handleAudioTrackChange = (trackId: number) => {
    if (hlsRef.current) {
      hlsRef.current.audioTrack = trackId;
      setActiveAudioTrack(trackId);
    } else {
      // Native audio tracks
      const video = videoRef.current;
      if (!video) return;
      const audioList = (video as any).audioTracks;
      if (audioList) {
        for (let i = 0; i < audioList.length; i++) {
          audioList[i].enabled = (i === trackId);
        }
        setActiveAudioTrack(trackId);
      }
    }
  };

  const handleSubtitleTrackChange = (trackId: number) => {
    const video = videoRef.current;
    if (hlsRef.current) {
      hlsRef.current.subtitleTrack = trackId;
      setActiveSubtitleTrack(trackId);
      
      // Force native track modes to match HLS selection to guarantee browser renders them
      if (video && video.textTracks) {
        for (let i = 0; i < video.textTracks.length; i++) {
          video.textTracks[i].mode = (i === trackId) ? 'showing' : 'disabled';
        }
      }
    } else {
      // Native text tracks
      if (!video) return;
      for (let i = 0; i < video.textTracks.length; i++) {
        video.textTracks[i].mode = (i === trackId) ? 'showing' : 'disabled';
      }
      setActiveSubtitleTrack(trackId);
    }
  };

  // Auto-hide controls
  const resetControlsTimer = useCallback(() => {
    setShowControls(true);
    if (controlsTimerRef.current) clearTimeout(controlsTimerRef.current);
    if (isPlaying) {
      controlsTimerRef.current = setTimeout(() => {
        setShowControls(false);
        setShowSettings(false);
      }, CONTROLS_HIDE_DELAY);
    }
  }, [isPlaying]);

  useEffect(() => {
    resetControlsTimer();
    return () => {
      if (controlsTimerRef.current) clearTimeout(controlsTimerRef.current);
    };
  }, [isPlaying, resetControlsTimer]);

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

  // Player actions
  const togglePlay = () => {
    const video = videoRef.current;
    if (!video) return;
    if (video.paused) video.play().catch(() => {});
    else video.pause();
  };

  const toggleMute = () => {
    const video = videoRef.current;
    if (!video) return;
    video.muted = !video.muted;
    setIsMuted(!isMuted);
  };

  const handleVolumeChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const v = parseFloat(e.target.value);
    const video = videoRef.current;
    if (!video) return;
    video.volume = v;
    setVolume(v);
    setIsMuted(v === 0);
  };

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

  const toggleFullscreen = () => {
    const container = containerRef.current;
    if (!container) return;
    if (!document.fullscreenElement) {
      container.requestFullscreen().catch(() => {});
    } else {
      document.exitFullscreen().catch(() => {});
    }
  };

  const togglePiP = () => {
    const activeVideo = usePlayerStore.getState().activeVideo;
    if (!activeVideo) return;

    const isPipActive = usePlayerStore.getState().isPipActive;
    
    if (!isPipActive) {
      usePlayerStore.getState().setPipActive(true);
      usePlayerStore.getState().minimizeVideo();
      router.back();
    } else {
      usePlayerStore.getState().setPipActive(false);
    }
  };

  const handleSpeedChange = (speed: number) => {
    const video = videoRef.current;
    if (!video) return;
    video.playbackRate = speed;
    setPlaybackSpeed(speed);
  };

  const retry = () => {
    setError(null);
    const hls = hlsRef.current;
    if (hls) {
      hls.destroy();
    }
    // Re-trigger the effect by forcing re-render
    const video = videoRef.current;
    if (video) {
      video.load();
    }
    window.location.reload();
  };

  const progress = duration ? (currentTime / duration) * 100 : 0;

  if (isMinimized && !isMini) {
    return <div className="w-full aspect-video bg-black rounded-xl" />;
  }

  return (
    <div
      ref={containerRef}
      className={cn(
        "relative w-full bg-black rounded-xl overflow-hidden group",
        isMultiViewChild ? "h-full" : "aspect-video"
      )}
      onMouseMove={resetControlsTimer}
      onMouseLeave={() => isPlaying && setShowControls(false)}
    >
      {/* Video */}
      <video
        ref={videoRef}
        className="w-full h-full object-contain"
        poster={poster}
        playsInline
        preload="auto"
        autoPlay={autoPlay}
        onClick={isMini ? undefined : togglePlay}
      />

      {/* Buffering spinner */}
      <AnimatePresence>
        {isBuffering && !error && (
          <motion.div
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
            exit={{ opacity: 0 }}
            className="absolute inset-0 flex items-center justify-center bg-black/40"
          >
            <Spinner size="xl" color="primary" />
          </motion.div>
        )}
      </AnimatePresence>

      {/* Resume playback banner */}
      <AnimatePresence>
        {showResumeBanner && !isMini && (
          <motion.div
            initial={{ opacity: 0, y: 20 }}
            animate={{ opacity: 1, y: 0 }}
            exit={{ opacity: 0, y: 20 }}
            className="absolute bottom-16 left-4 md:left-6 bg-dark-200/90 backdrop-blur border border-white/10 px-4 py-3 rounded-lg flex items-center gap-3 z-30 shadow-2xl"
          >
            <span className="text-xs text-white font-medium select-none">
              Reanudado en <span className="text-primary font-bold">{formatTime(resumeTime)}</span>
            </span>
            <button
              onClick={() => {
                const video = videoRef.current;
                if (video) video.currentTime = 0;
                setShowResumeBanner(false);
                clearProgress(streamUrl);
              }}
              className="text-[10px] font-black uppercase tracking-wider text-white bg-white/10 hover:bg-white/20 px-2.5 py-1.5 rounded transition-colors font-sans"
            >
              Empezar de nuevo
            </button>
            <button
              onClick={() => setShowResumeBanner(false)}
              className="text-[10px] font-black uppercase tracking-wider text-white/50 hover:text-white px-1.5 py-1.5 rounded transition-colors font-sans"
            >
              Ocultar
            </button>
          </motion.div>
        )}
      </AnimatePresence>

      {/* Error state */}
      <AnimatePresence>
        {error && (
          <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 gap-4"
          >
            <FiAlertTriangle size={48} className="text-primary" />
            <p className="text-white/70 text-center max-w-sm">{error}</p>
            <button
              onClick={retry}
              className="flex items-center gap-2 px-6 py-3 bg-primary hover:bg-primary-hover text-white rounded-lg font-semibold transition-all"
            >
              <FiRotateCcw size={18} />
              Reintentar
            </button>
          </motion.div>
        )}
      </AnimatePresence>

      {/* Big play button overlay when paused */}
      <AnimatePresence>
        {!isPlaying && !isBuffering && !error && !isMini && (
          <motion.div
            initial={{ opacity: 0, scale: 0.8 }}
            animate={{ opacity: 1, scale: 1 }}
            exit={{ opacity: 0, scale: 0.8 }}
            className="absolute inset-0 flex items-center justify-center cursor-pointer"
            onClick={togglePlay}
          >
            <div className="w-20 h-20 rounded-full bg-primary/90 backdrop-blur flex items-center justify-center shadow-2xl shadow-primary/40 hover:scale-110 transition-transform">
              <FiPlay size={36} className="ml-1.5 text-white" />
            </div>
          </motion.div>
        )}
      </AnimatePresence>

      {/* Controls overlay */}
      <AnimatePresence>
        {showControls && !error && !isMini && (
          <motion.div
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
            exit={{ opacity: 0 }}
            transition={{ duration: 0.2 }}
            className="player-controls"
          >
             {/* Title & Add stream button */}
             <div className="flex items-center justify-between gap-4 mb-3">
               <p className="text-white font-semibold text-sm md:text-base truncate">{title}</p>
               {!isMini && !isMultiViewChild && (
                 <button
                   type="button"
                   onClick={() => setIsModalOpen(true)}
                   className="flex items-center gap-1.5 px-3 py-1.5 bg-primary/20 text-primary border border-primary/30 hover:bg-primary hover:text-white rounded-lg text-xs font-semibold transition-all duration-300 pointer-events-auto shadow-md"
                 >
                   <span>+</span> Añadir programa
                 </button>
               )}
             </div>

            {/* Progress bar */}
            <div
              ref={progressRef}
              className="progress-bar mb-3 group group/progress"
              onClick={handleSeek}
            >
              <div className="progress-fill" style={{ width: `${progress}%` }} />
            </div>

            {/* Controls row */}
            <div className="flex items-center justify-between gap-3">
              <div className="flex items-center gap-2">
                {/* Play/Pause */}
                <button
                  onClick={togglePlay}
                  className="p-2 rounded-lg text-white hover:bg-white/10 transition-all"
                >
                  {isPlaying ? <FiPause size={22} /> : <FiPlay size={22} className="ml-0.5" />}
                </button>

                {/* Volume */}
                <div className="flex items-center gap-1 group/vol">
                  <button
                    onClick={toggleMute}
                    className="p-2 rounded-lg text-white hover:bg-white/10 transition-all"
                  >
                    {isMuted || volume === 0 ? <FiVolumeX size={20} /> : <FiVolume2 size={20} />}
                  </button>
                  <input
                    type="range"
                    min="0"
                    max="1"
                    step="0.05"
                    value={isMuted ? 0 : volume}
                    onChange={handleVolumeChange}
                    className="w-0 group-hover/vol:w-20 transition-all duration-300 accent-primary cursor-pointer h-1 appearance-none bg-white/20 rounded-full"
                  />
                </div>

                {/* Time */}
                <span className="text-xs text-white/60 font-mono ml-2">
                  {formatTime(currentTime)} / {formatTime(duration)}
                </span>

                {/* Scanned features badges */}
                {audioTracks.length > 1 && (
                  <span className="ml-2.5 px-1.5 py-0.5 rounded bg-primary/20 text-primary border border-primary/30 text-[9px] font-bold tracking-wide uppercase select-none">
                    Dual
                  </span>
                )}
                {subtitleTracks.length > 0 && (
                  <span className="ml-1.5 px-1.5 py-0.5 rounded bg-white/10 text-white/70 border border-white/20 text-[9px] font-bold tracking-wide uppercase select-none">
                    CC
                  </span>
                )}
              </div>

              <div className="flex items-center gap-1">
                {/* Speed */}
                <button
                  onClick={() => {
                    const speeds = PLAYBACK_SPEEDS as readonly number[];
                    const i = speeds.indexOf(playbackSpeed);
                    handleSpeedChange(speeds[(i + 1) % speeds.length]);
                  }}
                  className="px-2 py-1 rounded text-xs font-bold text-white/70 hover:text-white hover:bg-white/10 transition-all"
                >
                  {playbackSpeed}x
                </button>

                {/* Settings */}
                <div className="relative">
                  <button
                    onClick={() => setShowSettings(!showSettings)}
                    className="p-2 rounded-lg text-white/70 hover:text-white hover:bg-white/10 transition-all"
                  >
                    <FiSettings size={18} />
                  </button>
                  <AnimatePresence>
                    {showSettings && (
                      <motion.div
                        initial={{ opacity: 0, y: 8 }}
                        animate={{ opacity: 1, y: 0 }}
                        exit={{ opacity: 0, y: 8 }}
                        className="absolute bottom-full right-0 mb-2 w-56 bg-dark-200/95 backdrop-blur-lg border border-white/10 rounded-lg shadow-2xl overflow-hidden text-white"
                      >
                        {settingsView === 'main' && (
                          <div className="p-1">
                            {/* Main Menu */}
                            <button
                              onClick={() => setSettingsView('quality')}
                              className="w-full flex items-center justify-between px-3 py-2.5 text-sm rounded hover:bg-white/5 transition-colors"
                            >
                              <span className="text-white/70 font-medium">Calidad</span>
                              <span className="text-xs text-primary flex items-center gap-1">
                                {quality}
                                <FiChevronRight size={14} />
                              </span>
                            </button>

                            <button
                              onClick={() => setSettingsView('speed')}
                              className="w-full flex items-center justify-between px-3 py-2.5 text-sm rounded hover:bg-white/5 transition-colors border-t border-white/5"
                            >
                              <span className="text-white/70 font-medium">Velocidad</span>
                              <span className="text-xs text-primary flex items-center gap-1">
                                {playbackSpeed}x
                                <FiChevronRight size={14} />
                              </span>
                            </button>

                            <button
                              onClick={() => setSettingsView('audio')}
                              className="w-full flex items-center justify-between px-3 py-2.5 text-sm rounded hover:bg-white/5 transition-colors border-t border-white/5"
                            >
                              <span className="text-white/70 font-medium">Audio / Idioma</span>
                              <span className="text-xs text-primary flex items-center gap-1 max-w-[100px] truncate">
                                {audioTracks.length > 0
                                  ? (audioTracks.find(t => t.id === activeAudioTrack)?.name || 'Por defecto')
                                  : 'Único / Por defecto'}
                                <FiChevronRight size={14} />
                              </span>
                            </button>

                            <button
                              onClick={() => setSettingsView('subtitles')}
                              className="w-full flex items-center justify-between px-3 py-2.5 text-sm rounded hover:bg-white/5 transition-colors border-t border-white/5"
                            >
                              <span className="text-white/70 font-medium">Subtítulos</span>
                              <span className="text-xs text-primary flex items-center gap-1 max-w-[100px] truncate">
                                {subtitleTracks.length > 0
                                  ? (activeSubtitleTrack === -1 ? 'Desactivados' : (subtitleTracks.find(t => t.id === activeSubtitleTrack)?.name || 'Activados'))
                                  : 'No disponibles'}
                                <FiChevronRight size={14} />
                              </span>
                            </button>
                          </div>
                        )}

                        {settingsView === 'quality' && (
                          <div className="p-2">
                            <button
                              onClick={() => setSettingsView('main')}
                              className="w-full flex items-center gap-1.5 px-2 py-1.5 text-xs text-white/40 font-semibold uppercase hover:text-white transition-colors mb-1"
                            >
                              <FiChevronLeft size={14} />
                              Atrás
                            </button>
                            <div className="max-h-48 overflow-y-auto font-sans">
                              {(QUALITIES as readonly string[]).map((q) => (
                                <button
                                  key={q}
                                  onClick={() => { setQuality(q); setShowSettings(false); }}
                                  className={cn(
                                    'w-full flex items-center justify-between px-3 py-2 text-sm rounded transition-colors',
                                    quality === q ? 'text-primary bg-primary/10' : 'text-white/70 hover:bg-white/5'
                                  )}
                                >
                                  {q}
                                  {quality === q && <FiCheck size={14} />}
                                </button>
                              ))}
                            </div>
                          </div>
                        )}

                        {settingsView === 'speed' && (
                          <div className="p-2">
                            <button
                              onClick={() => setSettingsView('main')}
                              className="w-full flex items-center gap-1.5 px-2 py-1.5 text-xs text-white/40 font-semibold uppercase hover:text-white transition-colors mb-1"
                            >
                              <FiChevronLeft size={14} />
                              Atrás
                            </button>
                            {(PLAYBACK_SPEEDS as readonly number[]).map((s) => (
                              <button
                                key={s}
                                onClick={() => { handleSpeedChange(s); setShowSettings(false); }}
                                className={cn(
                                  'w-full flex items-center justify-between px-3 py-2 text-sm rounded transition-colors',
                                  playbackSpeed === s ? 'text-primary bg-primary/10' : 'text-white/70 hover:bg-white/5'
                                )}
                              >
                                {s}x
                                {playbackSpeed === s && <FiCheck size={14} />}
                              </button>
                            ))}
                          </div>
                        )}

                        {settingsView === 'audio' && (
                          <div className="p-2">
                            <button
                              onClick={() => setSettingsView('main')}
                              className="w-full flex items-center gap-1.5 px-2 py-1.5 text-xs text-white/40 font-semibold uppercase hover:text-white transition-colors mb-1"
                            >
                              <FiChevronLeft size={14} />
                              Atrás
                            </button>
                            <div className="max-h-48 overflow-y-auto">
                              {audioTracks.length === 0 ? (
                                <div className="px-3 py-2 text-xs text-white/40 font-sans text-center">
                                  <p className="font-medium text-white/70">Audio por defecto (Español)</p>
                                </div>
                              ) : (
                                audioTracks.map((t) => (
                                  <button
                                    key={t.id}
                                    onClick={() => { handleAudioTrackChange(t.id); setShowSettings(false); }}
                                    className={cn(
                                      'w-full flex items-center justify-between px-3 py-2 text-sm rounded transition-colors',
                                      activeAudioTrack === t.id ? 'text-primary bg-primary/10' : 'text-white/70 hover:bg-white/5'
                                    )}
                                  >
                                    <span className="truncate pr-2">{t.name}</span>
                                    {activeAudioTrack === t.id && <FiCheck size={14} />}
                                  </button>
                                ))
                              )}
                            </div>
                          </div>
                        )}

                        {settingsView === 'subtitles' && (
                          <div className="p-2">
                            <button
                              onClick={() => setSettingsView('main')}
                              className="w-full flex items-center gap-1.5 px-2 py-1.5 text-xs text-white/40 font-semibold uppercase hover:text-white transition-colors mb-1"
                            >
                              <FiChevronLeft size={14} />
                              Atrás
                            </button>
                            <div className="max-h-48 overflow-y-auto">
                              {subtitleTracks.length === 0 ? (
                                <div className="px-3 py-2 text-xs text-white/40 font-sans text-center">
                                  <p className="font-medium text-white/70">No hay subtítulos disponibles</p>
                                </div>
                              ) : (
                                <>
                                  <button
                                    onClick={() => { handleSubtitleTrackChange(-1); setShowSettings(false); }}
                                    className={cn(
                                      'w-full flex items-center justify-between px-3 py-2 text-sm rounded transition-colors',
                                      activeSubtitleTrack === -1 ? 'text-primary bg-primary/10' : 'text-white/70 hover:bg-white/5'
                                    )}
                                  >
                                    Desactivados
                                    {activeSubtitleTrack === -1 && <FiCheck size={14} />}
                                  </button>

                                  {subtitleTracks.map((t) => (
                                    <button
                                      key={t.id}
                                      onClick={() => { handleSubtitleTrackChange(t.id); setShowSettings(false); }}
                                      className={cn(
                                        'w-full flex items-center justify-between px-3 py-2 text-sm rounded transition-colors',
                                        activeSubtitleTrack === t.id ? 'text-primary bg-primary/10' : 'text-white/70 hover:bg-white/5'
                                      )}
                                    >
                                      <span className="truncate pr-2">{t.name}</span>
                                      {activeSubtitleTrack === t.id && <FiCheck size={14} />}
                                    </button>
                                  ))}
                                </>
                              )}
                            </div>
                          </div>
                        )}
                      </motion.div>
                    )}
                  </AnimatePresence>
                </div>

                {/* Picture in Picture */}
                {pipSupported && (
                  <button
                    onClick={togglePiP}
                    className={cn(
                      "p-2 rounded-lg transition-all",
                      isPiP ? "text-primary hover:bg-primary/10" : "text-white/70 hover:text-white hover:bg-white/10"
                    )}
                    title={isPiP ? "Cerrar Mini Reproductor" : "Reproductor flotante (PiP)"}
                  >
                    <PictureInPictureIcon size={18} />
                  </button>
                )}

                {/* Fullscreen */}
                <button
                  onClick={toggleFullscreen}
                  className="p-2 rounded-lg text-white/70 hover:text-white hover:bg-white/10 transition-all"
                >
                  {isFullscreen ? <FiMinimize size={18} /> : <FiMaximize size={18} />}
                </button>
              </div>
            </div>
          </motion.div>
        )}
      </AnimatePresence>

      {/* Search Modal to add additional streams */}
      {!isMultiViewChild && (
        <AddStreamModal
          isOpen={isModalOpen}
          onClose={() => setIsModalOpen(false)}
          onSelect={(newItem) => {
            if (!multiActive) {
              startMultiStream({
                id: contentId || streamUrl,
                url: streamUrl,
                title: title,
                type: contentType === 'live' ? 'tv' : (contentType || 'movie') as any,
                posterUrl: poster || '',
              });
            }
            addStream(newItem);
          }}
        />
      )}
    </div>
  );
}

export default function VideoPlayer(props: VideoPlayerProps) {
  const { isActive: multiActive, streams } = useMultiStreamStore();

  if (!props.isMultiViewChild && multiActive && streams.length > 0) {
    return <MultiStreamPlayer />;
  }

  return <SingleVideoPlayer {...props} />;
}
