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';
import { TvShowCardData } from './ContentCard';

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[];
  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,
  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 [showData, setShowData] = useState<TvShowCardData | null>(null);
  const [selectedImage, setSelectedImage] = useState<string>();
  const [imageLoaded, setImageLoaded] = useState(false);
  const [ratingInfo, setRatingInfo] = useState<{ rating: string; description: string } | null>(null);
  const containerRef = useRef<HTMLDivElement>(null);
  const videoRef = useRef<HTMLVideoElement>(null);

  const { toast } = useToast();
  const pollingInterval = useRef<NodeJS.Timeout | null>(null);
  const timeoutRef = useRef<NodeJS.Timeout | null>(null);
  const videoFetchedRef = useRef(false);

  // Reset imageLoaded whenever we pick a new image
  useEffect(() => {
    setImageLoaded(false);
  }, [selectedImage]);

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

  // Random image selector with fallback
  const selectRandomImage = (cardData: TvShowCardData) => {
    if (cardData.banner?.length) {
      return cardData.banner[Math.floor(Math.random() * cardData.banner.length)].image;
    }
    if (cardData.portrait?.length) {
      return cardData.portrait[Math.floor(Math.random() * cardData.portrait.length)].image;
    }
    return cardData.image;
  };

  // Fetch or poll for the video URL
  const fetchMovieLink = async () => {
    if (videoFetchedRef.current) return;
    try {
      const response = await getEpisodeLinkByTitle(videoTitle, season, episode);
      if (response.url) {
        pollingInterval.current && clearInterval(pollingInterval.current);
        setVideoUrl(response.url);
        setVideoFetched(true);
        videoFetchedRef.current = true;
        setLoading(false);
      } else if (response.progress_url) {
        const poll = async () => {
          try {
            const res = await fetch(response.progress_url);
            const data = await res.json();
            setProgress(data.progress);
            if (data.progress.progress >= 100) {
              pollingInterval.current && clearInterval(pollingInterval.current);
              timeoutRef.current = setTimeout(fetchMovieLink, 5000);
            }
          } catch (e) {
            console.error(e);
          }
        };
        pollingInterval.current = setInterval(poll, 2000);
      } else {
        throw new Error('No URL or progress URL');
      }
    } catch (e) {
      console.error(e);
      setError('Failed to load episode');
      toast({ title: 'Error', description: 'Could not load the episode', variant: 'destructive' });
      setLoading(false);
    }
  };

  // Main init: fetch TV show card, then fetch link
  useEffect(() => {
    if (!videoTitle || !season || !episode) {
      setError('Missing required video information');
      setLoading(false);
      return;
    }

    setLoading(true);
    setError(null);
    setVideoUrl(null);
    setVideoFetched(false);
    videoFetchedRef.current = false;
    setProgress(null);

    const init = async () => {
      try {
        const data = await getTvShowCard(videoTitle);
        setShowData(data);
        const img = selectRandomImage(data);
        setSelectedImage(img);
        const ratings = data.data?.contentRatings || contentRatings || [];
        if (ratings.length) {
          const us = ratings.find(r => r.country === 'usa') || ratings[0];
          setRatingInfo({ rating: us.name || 'NR', description: us.description || '' });
        }
      } catch (e) {
        console.error('Show card fetch error:', e);
        setError('Failed to load show data');
        toast({ title: 'Error', description: 'Could not load show data', variant: 'destructive' });
        setLoading(false);
        return;
      }
      await fetchMovieLink();
    };

    init();

    return () => {
      pollingInterval.current && clearInterval(pollingInterval.current);
      timeoutRef.current && clearTimeout(timeoutRef.current);
    };
  }, [videoTitle, season, episode]);

  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"
        >
          Back to Show
        </button>
      </div>
    );
  }

  if (loading || !videoFetched || !videoUrl) {
    return (
      <>
        {/* Hero backdrop with fade-in */}
        <div className="absolute top-0 left-0 w-full h-full z-50">
          <div className="absolute inset-0">
            <img
              src={selectedImage}
              onLoad={() => setImageLoaded(true)}
              onError={(e) => {
                const target = e.target as HTMLImageElement;
                target.src = '/placeholder.svg';
              }}
              className={`w-full h-full object-cover transition-opacity duration-700 ease-in-out ${
                imageLoaded ? 'opacity-100' : 'opacity-0'
              }`}
            />
            <div className="absolute inset-0 bg-gradient-to-t from-netflix-black via-netflix-black/50 to-transparent" />
            <div className="absolute inset-0 bg-gradient-to-r from-netflix-black/80 via-netflix-black/40 to-transparent" />
          </div>
        </div>
        <div className="fixed inset-0 z-50 flex flex-col items-center backdrop-blur-sm 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>
      </>
    );
  }

  const tvShowOverlay = (
    <>
      <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>

      <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={selectedImage}
        startTime={startTime}
        onClose={onClosePlayer}
        onProgressUpdate={onProgressUpdate}
        onVideoEnded={onVideoEnded}
        showNextButton={true}
        contentRating={ratingInfo}
        hideTitleInPlayer={true}
        customOverlay={tvShowOverlay}
        containerRef={containerRef}
        videoRef={videoRef}
      />
    </div>
  );
};

export default TVShowPlayer;
