import React, { useEffect, useState, useRef } from 'react';
import { getEpisodeLinkByTitle, getTvShowCard } from '../lib/api';
import { useToast } from '@/hooks/use-toast';
import { Film, GalleryVerticalEnd, Loader2, Play } from 'lucide-react';
import VideoPlayer from './VideoPlayer';

interface ProgressData {
  status: string;
  progress: number;
  downloaded: number;
  total: number;
}

interface ContentRating {
  country: string;
  name: string;
  description: string;
}

interface TVShowPlayerProps {
  videoTitle: string;
  season: string;
  episode: string;
  movieTitle: string;
  contentRatings?: ContentRating[];
  thumbnail?: string;
  poster?: string;
  startTime?: number;
  onClosePlayer?: () => void;
  onProgressUpdate?: (currentTime: number, duration: number) => void;
  onVideoEnded?: () => void;
  onShowEpisodes?: () => void;
}

const TVShowPlayer: React.FC<TVShowPlayerProps> = ({
  videoTitle,
  season,
  episode,
  movieTitle,
  contentRatings,
  thumbnail,
  poster,
  startTime = 0,
  onClosePlayer,
  onProgressUpdate,
  onVideoEnded,
  onShowEpisodes
}) => {
  const [videoUrl, setVideoUrl] = useState<string | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [progress, setProgress] = useState<ProgressData | null>(null);
  const [videoFetched, setVideoFetched] = useState(false);
  const { toast } = useToast();
  
  const pollingInterval = useRef<NodeJS.Timeout | null>(null);
  const timeoutRef = useRef<NodeJS.Timeout | null>(null);
  const videoFetchedRef = useRef(false);
  const [ratingInfo, setRatingInfo] = useState<{ rating: string, description: string } | null>(null);
  const containerRef = useRef<HTMLDivElement>(null);
  const [isFullscreen, setIsFullscreen] = useState(false);
  const videoRef = useRef<HTMLVideoElement>(null);

  // Parse episode info
  const getEpisodeInfo = () => {
    if (!episode) return { number: '1', title: 'Unknown Episode' };
    
    const episodeMatch = episode.match(/E(\d+)\s*-\s*(.+?)(?=\.\w+$)/i);
    const number = episodeMatch ? episodeMatch[1] : '1';
    const title = episodeMatch ? episodeMatch[2].trim() : 'Unknown Episode';
    
    return { number, title };
  };

  const { number: episodeNumber, title: episodeTitle } = getEpisodeInfo();

  // --- Link Fetching & Polling ---
  const fetchMovieLink = async () => {
    if (videoFetchedRef.current) return;
    
    try {
      const response = await getEpisodeLinkByTitle(videoTitle, season, episode);
      
      if (response && response.url) {
        // Stop any polling if running
        if (pollingInterval.current) {
          clearInterval(pollingInterval.current);
          pollingInterval.current = null;
        }
        
        setVideoUrl(response.url);
        setVideoFetched(true);
        videoFetchedRef.current = true;
        setLoading(false);
        console.log('Video URL fetched:', response.url);
      } else if (response && response.progress_url) {
        startPolling(response.progress_url);
      } else {
        console.error('No video URL or progress URL found in response:', response);
        setError('Video URL not available');
      }
    } catch (error) {
      console.error('Error fetching episode link:', error);
      setError('Failed to load episode');
      toast({
        title: "Error",
        description: "Could not load the episode",
        variant: "destructive"
      });
    } finally {
      if (!videoFetchedRef.current && !videoUrl) {
        setLoading(false);
      }
    }
  };

  // Fetch content ratings if not provided
  useEffect(() => {
    const fetchRatingInfo = async () => {
      if (contentRatings && contentRatings.length > 0) {
        const usRating = contentRatings.find(r => r.country === 'usa') || contentRatings[0];
        setRatingInfo({
          rating: usRating.name || 'NR',
          description: usRating.description || ''
        });
        return;
      }
      
      try {
        const showData = await getTvShowCard(videoTitle);
        if (showData && showData.data && showData.data.contentRatings) {
          const ratings = showData.data.contentRatings;
          const usRating = ratings.find((r: any) => r.country === 'US') || ratings[0];
          setRatingInfo({
            rating: usRating?.name || 'TV-14',
            description: usRating?.description || ''
          });
        }
      } catch (error) {
        console.error('Failed to fetch show ratings:', error);
      }
    };
    
    fetchRatingInfo();
  }, [videoTitle, contentRatings]);

  const pollProgress = async (progressUrl: string) => {
    try {
      const res = await fetch(progressUrl);
      const data = await res.json();
      
      setProgress(data.progress);
      
      if (data.progress.progress >= 100) {
        if (pollingInterval.current) {
          clearInterval(pollingInterval.current);
          pollingInterval.current = null;
        }
        
        if (!videoFetchedRef.current) {
          timeoutRef.current = setTimeout(fetchMovieLink, 5000);
        }
      }
    } catch (error) {
      console.error('Error polling progress:', error);
    }
  };

  const startPolling = (progressUrl: string) => {
    if (!pollingInterval.current) {
      const interval = setInterval(() => pollProgress(progressUrl), 2000);
      pollingInterval.current = interval;
    }
  };

  useEffect(() => {
    if (!videoTitle || !season || !episode) {
      setError('Missing required video information');
      setLoading(false);
      return;
    }
    
    // Reset state for new episode
    setVideoUrl(null);
    setVideoFetched(false);
    videoFetchedRef.current = false;
    setLoading(true);
    setProgress(null);
    setError(null);
    
    // Start fetching
    fetchMovieLink();
    
    return () => {
      if (pollingInterval.current) clearInterval(pollingInterval.current);
      if (timeoutRef.current) clearTimeout(timeoutRef.current);
    };
  }, [videoTitle, season, episode]);

  // Add effect to update loading state when videoUrl changes
  useEffect(() => {
    if (videoUrl) {
      setLoading(false);
    }
  }, [videoUrl]);

  if (error) {
    return (
      <div className="flex flex-col items-center justify-center min-h-screen bg-black text-white">
        <div className="text-4xl mb-4 text-theme-error">😢</div>
        <h2 className="text-2xl font-bold mb-2">Error Playing Episode</h2>
        <p className="text-gray-400 mb-6">{error}</p>
        <button
          onClick={onClosePlayer}
          className="px-6 py-2 bg-theme-primary hover:bg-theme-primary-hover rounded font-medium transition-colors"
        >
          Back to Show
        </button>
      </div>
    );
  }

  if (loading || !videoFetched || !videoUrl) {
    return (
      <div className="fixed inset-0 z-50 bg-gradient-to-br from-theme-background-dark to-black flex flex-col items-center justify-center">
        <div className="text-center max-w-md px-6">
          <div className="mb-6 flex justify-center">
            {poster ? (
              <img src={poster} alt={movieTitle} className="h-auto w-24 rounded-lg shadow-lg" />
            ) : (
              <div className="flex items-center justify-center h-24 w-24 bg-theme-primary/20 rounded-lg">
                <Play className="h-12 w-12 text-theme-primary" />
              </div>
            )}
          </div>
          
          <h2 className="text-2xl md:text-3xl font-bold text-white mb-4">
            {progress && progress.progress < 100 
              ? `Preparing "${episodeTitle}"`
              : `Loading "${episodeTitle}"`
            }
          </h2>
          
          {progress ? (
            <>
              <p className="text-gray-300 mb-4">
                {progress.progress < 5
                  ? 'Initializing your stream...'
                  : progress.progress < 100
                    ? 'Your stream is being prepared.'
                    : 'Almost ready! Starting playback soon...'}
              </p>
              <div className="relative w-full h-2 bg-gray-800 rounded-full overflow-hidden mb-2">
                <div
                  className="absolute top-0 left-0 h-full bg-gradient-to-r from-theme-primary to-theme-primary-light transition-all duration-300"
                  style={{ width: `${Math.min(100, Math.max(0, progress.progress))}%` }}
                />
              </div>
              <p className="text-sm text-gray-400">
                {Math.round(progress.progress)}% complete
              </p>
            </>
          ) : (
            <div className="flex justify-center">
              <Loader2 className="h-8 w-8 animate-spin text-theme-primary" />
            </div>
          )}
        </div>
      </div>
    );
  }

  // TV Show specific overlay elements that will be passed to VideoPlayer
  const tvShowOverlay = (
    <>
      {/* Top info bar */}
      <div className="absolute top-0 left-0 right-0 z-10 flex items-center p-4 bg-gradient-to-b from-black/80 to-transparent">
        <div>
          <div className="flex items-center">
            <Film className="text-primary mr-2" size={20} />
            <span className="text-white text-sm font-medium truncate">
              {videoTitle}
            </span>
            <span className="mx-2 text-gray-400">•</span>
            <span className="text-white text-sm">
              {season} • Episode {episodeNumber}
            </span>
          </div>
          <h1 className="text-white text-lg font-bold">{episodeTitle}</h1>
        </div>
      </div>
      
      {/* Episodes button */}
      <div className="absolute top-4 right-16 z-20">
        <button
          onClick={onShowEpisodes}
          className="bg-gray-800/80 hover:bg-gray-700/80 p-2 rounded-full transition-colors"
          title="Show Episodes"
        >
          <GalleryVerticalEnd className="text-white" size={20} />
        </button>
      </div>
    </>
  );

  return (
    <div ref={containerRef} className="fixed inset-0 w-screen h-screen overflow-hidden">
      <VideoPlayer
        url={videoUrl}
        title={`${videoTitle} - ${season}E${episodeNumber}`}
        poster={poster || thumbnail}
        startTime={startTime}
        onClose={onClosePlayer}
        onProgressUpdate={onProgressUpdate}
        onVideoEnded={onVideoEnded}
        showNextButton={true}
        contentRating={ratingInfo}
        hideTitleInPlayer={true}
        customOverlay={tvShowOverlay}
        containerRef={containerRef}
        videoRef={videoRef}
      />
    </div>
  );
};

export default TVShowPlayer;
