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';

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

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

const MoviePlayer: React.FC<MoviePlayerProps> = ({
  movieTitle,
  videoUrl,
  contentRatings,
  thumbnail,
  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 { 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);
  
  // Update the onProgressUpdate handler to also update currentTime
  const handleProgressUpdate = (time: number, duration: number) => {
    setCurrentTime(time);
    onProgressUpdate?.(time, duration);
  };

  // Handler for seeking from WatchTogether
  const handleSeek = (time: number) => {
    if (videoRef.current) {
      videoRef.current.currentTime = time;
      setCurrentTime(time);
    }
  };

  // --- Link Fetching & Polling ---
  const fetchMovieLink = async () => {
    if (videoFetchedRef.current || videoUrlState) return;
    
    try {
      const response = await getMovieLinkByTitle(movieTitle);
      
      if (response && response.url) {
        // Stop any polling if running
        if (pollingIntervalRef.current) {
          clearInterval(pollingIntervalRef.current);
          pollingIntervalRef.current = null;
        }
        
        setVideoUrlState(response.url);
        setVideoFetched(true);
        videoFetchedRef.current = true;
        setLoading(false); // Ensure loading is set to false when URL is fetched
        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 movie link:', error);
      setError('Failed to load video');
      toast({
        title: "Error",
        description: "Could not load the video",
        variant: "destructive"
      });
    } finally {
      // Only set loading to false if we don't have a video yet
      if (!videoFetchedRef.current && !videoUrlState) {
        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 movieData = await getMovieCard(movieTitle);
        if (movieData && movieData.content_ratings) {
          const ratings = movieData.content_ratings;
          const usRating = ratings.find((r: any) => r.country === 'US') || ratings[0];
          setRatingInfo({
            rating: usRating?.name || 'NR',
            description: usRating?.description || ''
          });
        }
      } catch (error) {
        console.error('Failed to fetch movie ratings:', error);
      }
    };
    
    fetchRatingInfo();
  }, [movieTitle, 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 (pollingIntervalRef.current) {
          clearInterval(pollingIntervalRef.current);
          pollingIntervalRef.current = null;
        }
        
        if (!videoFetchedRef.current) {
          timeoutRef.current = setTimeout(fetchMovieLink, 5000);
        }
      }
    } catch (error) {
      console.error('Error polling progress:', error);
    }
  };

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

  // Cleanup on unmount and when dependencies change
  useEffect(() => {
    if (!videoUrlState) {
      fetchMovieLink();
    } else {
      setVideoFetched(true);
      videoFetchedRef.current = true;
      setLoading(false); // Make sure loading is false when we have a URL
    }
    
    return () => {
      if (pollingIntervalRef.current) clearInterval(pollingIntervalRef.current);
      if (timeoutRef.current) clearTimeout(timeoutRef.current);
    };
  }, [movieTitle, videoUrl]);

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

  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>
    );
  }

  if (loading || !videoFetched || !videoUrlState) {
    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 "${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>
    );
  }

  return (
    <div ref={containerRef} className="fixed inset-0 h-screen w-screen overflow-hidden">
      <VideoPlayer
        url={videoUrlState}
        title={movieTitle}
        poster={poster || thumbnail}
        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;
