import React, { useEffect, useState, useRef } from 'react';
import { getMovieLinkByTitle, getMovieCard } from '../lib/api';
import { useToast } from '@/hooks/use-toast';
import VideoPlayer from './VideoPlayer';
import VideoPlayerControls from './VideoPlayerControls';
import { Loader2, Play } from 'lucide-react';
import { MovieCardData } from './ContentCard';

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

interface MoviePlayerProps {
  movieTitle: string;
  videoUrl?: string;
  contentRatings?: any[];
  poster?: string;
  startTime?: number;
  onClosePlayer?: () => void;
  onProgressUpdate?: (currentTime: number, duration: number) => void;
  onVideoEnded?: () => void;
  showNextButton?: boolean;
}

const MoviePlayer: React.FC<MoviePlayerProps> = ({
  movieTitle,
  videoUrl,
  contentRatings,
  poster,
  startTime = 0,
  onClosePlayer,
  onProgressUpdate,
  onVideoEnded,
  showNextButton = false
}) => {
  const [videoUrlState, setVideoUrlState] = useState<string | null>(videoUrl || null);
  const [loading, setLoading] = useState(!videoUrl);
  const [error, setError] = useState<string | null>(null);
  const [progress, setProgress] = useState<ProgressData | null>(null);
  const [videoFetched, setVideoFetched] = useState(!!videoUrl);
  const [cardData, setCardData] = useState<MovieCardData | null>(null);
  const [selectedImage, setSelectedImage] = useState<string | null>(null);
  const [imageLoaded, setImageLoaded] = useState(false);
  const { toast } = useToast();

  const pollingIntervalRef = useRef<NodeJS.Timeout | null>(null);
  const timeoutRef = useRef<NodeJS.Timeout | null>(null);
  const videoFetchedRef = useRef(!!videoUrl);
  const [ratingInfo, setRatingInfo] = useState<{ rating: string; description: string } | null>(null);
  const [currentTime, setCurrentTime] = useState(startTime);
  const containerRef = useRef<HTMLDivElement>(null);
  const videoRef = useRef<HTMLVideoElement>(null);

  // Reset fade state when image changes
  useEffect(() => {
    setImageLoaded(false);
  }, [selectedImage]);

  // Update progress and propagate up
  const handleProgressUpdate = (time: number, duration: number) => {
    setCurrentTime(time);
    onProgressUpdate?.(time, duration);
  };

  // Seek handler
  const handleSeek = (time: number) => {
    if (videoRef.current) {
      videoRef.current.currentTime = time;
      setCurrentTime(time);
    }
  };

  // Random image selector
  const selectRandomImage = (card: MovieCardData | null) => {
    if (!card) return null;
    if (card.banner && card.banner.length > 0) {
      return card.banner[Math.floor(Math.random() * card.banner.length)].image;
    }
    if (card.portrait && card.portrait.length > 0) {
      return card.portrait[Math.floor(Math.random() * card.portrait.length)].image;
    }
    return card.image;
  };

  // Fetch movie link or start polling
  const fetchMovieLink = async () => {
    if (videoFetchedRef.current || videoUrlState) return;

    try {
      const response = await getMovieLinkByTitle(movieTitle);
      if (response.url) {
        pollingIntervalRef.current && clearInterval(pollingIntervalRef.current);
        setVideoUrlState(response.url);
        setVideoFetched(true);
        videoFetchedRef.current = true;
        setLoading(false);
      } else if (response.progress_url) {
        if (!pollingIntervalRef.current) {
          pollingIntervalRef.current = setInterval(async () => {
            try {
              const res = await fetch(response.progress_url!);
              const data = await res.json();
              setProgress(data.progress);
              if (data.progress.progress >= 100) {
                clearInterval(pollingIntervalRef.current!);
                timeoutRef.current = setTimeout(fetchMovieLink, 5000);
              }
            } catch (e) {
              console.error(e);
            }
          }, 2000);
        }
      } else {
        throw new Error('No URL or progress URL');
      }
    } catch (e) {
      console.error('Error fetching movie link:', e);
      setError('Failed to load video');
      toast({ title: 'Error', description: 'Could not load the video', variant: 'destructive' });
      setLoading(false);
    }
  };

  // Fetch card data & ratings
  useEffect(() => {
    const fetchCard = async () => {
      try {
        const movieData = await getMovieCard(movieTitle);
        setCardData(movieData);
        const img = selectRandomImage(movieData);
        setSelectedImage(img);
        // Poster fallback
        if (!poster) {
          poster = movieData.image || poster;
        }
        // Ratings
        const ratings = contentRatings && contentRatings.length > 0
          ? contentRatings
          : movieData.content_ratings || [];
        if (ratings.length) {
          const us = ratings.find((r: any) => r.country === 'usa') || ratings[0];
          setRatingInfo({ rating: us.name || 'NR', description: us.description || '' });
        }
      } catch (e) {
        console.error('Failed to fetch movie card:', e);
      }
    };
    fetchCard();
  }, [movieTitle, contentRatings, poster]);

  // Initial link fetch / cleanup
  useEffect(() => {
    if (!videoUrlState) {
      fetchMovieLink();
    } else {
      setVideoFetched(true);
      videoFetchedRef.current = true;
      setLoading(false);
    }
    return () => {
      pollingIntervalRef.current && clearInterval(pollingIntervalRef.current);
      timeoutRef.current && clearTimeout(timeoutRef.current);
    };
  }, [movieTitle, videoUrlState]);

  // Sync loading state
  useEffect(() => {
    if (videoUrlState) setLoading(false);
  }, [videoUrlState]);

  // Error UI
  if (error) {
    return (
      <div className="fixed inset-0 z-50 bg-black flex flex-col items-center justify-center">
        <div className="text-4xl mb-4 text-theme-error">😢</div>
        <h2 className="text-2xl font-bold mb-2 text-white">Error Playing Movie</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 text-white"
        >
          Back to Browse
        </button>
      </div>
    );
  }

  // Loading / preparing UI with fade‑in backdrop
  if (loading || !videoFetched || !videoUrlState) {
    return (
      <>
        <div className="relative w-full h-full">
          <div className="absolute inset-0">
            <img
              src={selectedImage}
              onLoad={() => setImageLoaded(true)}
              onError={(e) => {
                (e.target as HTMLImageElement).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 "${movieTitle}"`
                : `Loading "${movieTitle}"`
              }
            </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>
      </>
    );
  }

  // Playback UI
  return (
    <div ref={containerRef} className="fixed inset-0 h-screen w-screen overflow-hidden">
      <VideoPlayer
        url={videoUrlState}
        title={movieTitle}
        poster={selectedImage || undefined}
        startTime={startTime}
        onClose={onClosePlayer}
        onProgressUpdate={handleProgressUpdate}
        onVideoEnded={onVideoEnded}
        showNextButton={showNextButton}
        contentRating={ratingInfo}
        containerRef={containerRef}
        videoRef={videoRef}
      />
      <VideoPlayerControls
        title={movieTitle}
        currentTime={currentTime}
        duration={videoRef.current?.duration || 0}
        onSeek={handleSeek}
      />
    </div>
  );
};

export default MoviePlayer;
