import React, { useEffect, useState } from 'react';
import { useParams, useNavigate, useSearchParams } from 'react-router-dom';
import { getTvShowMetadata } from '../lib/api';
import { useToast } from '@/hooks/use-toast';
import TVShowPlayer from '../components/TVShowPlayer';
import EpisodesPanel from '../components/EpisodesPanel';

interface FileStructureItem {
  type: string;
  path: string;
  contents?: FileStructureItem[];
  size?: number;
}

interface Episode {
  episode_number: number;
  name: string;
  overview: string;
  still_path: string;
  air_date: string;
  runtime: number;
  fileName?: string; // The actual file name with extension
}

interface Season {
  season_number: number;
  name: string;
  episodes: Episode[];
}

interface PlaybackProgress {
  [key: string]: {
    currentTime: number;
    duration: number;
    lastPlayed: string;
    completed: boolean;
  };
}

const TvShowPlayerPage = () => {
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [showInfo, setShowInfo] = useState<any>(null);
  const [showName, setShowName] = useState<string>('');
  const [seasons, setSeasons] = useState<Season[]>([]);
  const [selectedSeason, setSelectedSeason] = useState<string>('');
  const [selectedEpisode, setSelectedEpisode] = useState<string>('');
  const [activeEpisodeIndex, setActiveEpisodeIndex] = useState<number>(0);
  const [activeSeasonIndex, setActiveSeasonIndex] = useState<number>(0);
  const [showEpisodeSelector, setShowEpisodeSelector] = useState(false);
  const [playbackProgress, setPlaybackProgress] = useState<PlaybackProgress>({});
  const [needsReload, setNeedsReload] = useState(false); // Flag to trigger video reload

  const { title } = useParams<{ title: string }>();
  const [searchParams] = useSearchParams();
  const seasonParam = searchParams.get('season');
  const episodeParam = searchParams.get('episode');

  const navigate = useNavigate();
  const { toast } = useToast();

  // Helper function to extract episode info from file path
  const extractEpisodeInfoFromPath = (filePath: string): Episode | null => {
    const fileName = filePath.split('/').pop() || filePath;
    const episodeRegex = /S(\d+)E(\d+)\s*-\s*(.+?)(?=\.\w+$)/i;
    const match = fileName.match(episodeRegex);

    if (match) {
      const episodeNumber = parseInt(match[2], 10);
      const episodeName = match[3].trim();
      const isHD = fileName.toLowerCase().includes('720p') ||
        fileName.toLowerCase().includes('1080p') ||
        fileName.toLowerCase().includes('hdtv');

      return {
        episode_number: episodeNumber,
        name: episodeName,
        overview: '',
        still_path: '/placeholder.svg',
        air_date: '',
        runtime: isHD ? 24 : 22,
        fileName: fileName
      };
    }

    return null;
  };

  // Helper function to extract season info from directory path
  const getSeasonInfoFromPath = (path: string): { number: number, name: string } => {
    const seasonRegex = /Season\s*(\d+)/i;
    const specialsRegex = /Specials/i;

    if (specialsRegex.test(path)) {
      return { number: 0, name: 'Specials' };
    }

    const match = path.match(seasonRegex);
    if (match) {
      return {
        number: parseInt(match[1], 10),
        name: `Season ${match[1]}`
      };
    }

    return { number: 1, name: 'Season 1' };
  };

  // Process the file structure to extract seasons and episodes
  const processTvShowFileStructure = (fileStructure: any): Season[] => {
    if (!fileStructure || !fileStructure.contents) {
      return [];
    }

    const extractedSeasons: Season[] = [];

    // Find season directories
    const seasonDirectories = fileStructure.contents.filter(
      (item: FileStructureItem) => item.type === 'directory'
    );

    seasonDirectories.forEach((seasonDir: FileStructureItem) => {
      if (!seasonDir.contents) return;

      const seasonInfo = getSeasonInfoFromPath(seasonDir.path);
      const episodesArr: Episode[] = [];

      // Process files in this season directory
      seasonDir.contents.forEach((item: FileStructureItem) => {
        if (item.type === 'file') {
          const episode = extractEpisodeInfoFromPath(item.path);
          if (episode) {
            episodesArr.push(episode);
          }
        }
      });

      // Sort episodes by episode number
      episodesArr.sort((a, b) => a.episode_number - b.episode_number);

      if (episodesArr.length > 0) {
        extractedSeasons.push({
          season_number: seasonInfo.number,
          name: seasonInfo.name,
          episodes: episodesArr
        });
      }
    });

    // Sort seasons by season number
    extractedSeasons.sort((a, b) => a.season_number - b.season_number);
    return extractedSeasons;
  };

  // Select first available episode when none is specified
  const selectFirstAvailableEpisode = (seasons: Season[]) => {
    if (seasons.length === 0) return;

    // First try to find Season 1
    const regularSeason = seasons.find(s => s.season_number === 1);
    // If not available, use the first available season (could be Specials/Season 0)
    const firstSeason = regularSeason || seasons[0];

    if (firstSeason && firstSeason.episodes.length > 0) {
      setSelectedSeason(firstSeason.name);
      setSelectedEpisode(firstSeason.episodes[0].fileName || '');
      setActiveSeasonIndex(seasons.indexOf(firstSeason));
      setActiveEpisodeIndex(0);
    }
  };

  // Load playback progress from localStorage
  const loadPlaybackProgress = () => {
    try {
      const storedProgress = localStorage.getItem(`playback-${title}`);
      if (storedProgress) {
        setPlaybackProgress(JSON.parse(storedProgress));
      }
    } catch (error) {
      console.error("Failed to load playback progress:", error);
    }
  };

  // Save playback progress to localStorage
  const savePlaybackProgress = (episodeId: string, currentTime: number, duration: number, completed: boolean = false) => {
    try {
      const newProgress = {
        ...playbackProgress,
        [episodeId]: {
          currentTime,
          duration,
          lastPlayed: new Date().toISOString(),
          completed
        }
      };

      localStorage.setItem(`playback-${title}`, JSON.stringify(newProgress));
      setPlaybackProgress(newProgress);
    } catch (error) {
      console.error("Failed to save playback progress:", error);
    }
  };

  // Function to load the next episode and reset the video
  const loadNextEpisode = () => {
    if (!seasons.length) return;

    const currentSeason = seasons[activeSeasonIndex];
    if (!currentSeason) return;

    // If there's another episode in the current season
    if (activeEpisodeIndex < currentSeason.episodes.length - 1) {
      const nextEpisode = currentSeason.episodes[activeEpisodeIndex + 1];
      setSelectedEpisode(nextEpisode.fileName || '');
      setActiveEpisodeIndex(activeEpisodeIndex + 1);
      setNeedsReload(true); // Flag to reload the video

      // Update URL without page reload
      navigate(`/tv-show/${encodeURIComponent(title || '')}/watch?season=${encodeURIComponent(currentSeason.name)}&episode=${encodeURIComponent(nextEpisode.fileName || '')}`, { replace: true });

      toast({
        title: "Playing Next Episode",
        description: `${nextEpisode.name}`,
      });
    }
    // If there's another season available
    else if (activeSeasonIndex < seasons.length - 1) {
      const nextSeason = seasons[activeSeasonIndex + 1];
      if (nextSeason.episodes.length > 0) {
        const firstEpisode = nextSeason.episodes[0];
        setSelectedSeason(nextSeason.name);
        setSelectedEpisode(firstEpisode.fileName || '');
        setActiveSeasonIndex(activeSeasonIndex + 1);
        setActiveEpisodeIndex(0);
        setNeedsReload(true); // Flag to reload the video

        // Update URL without page reload
        navigate(`/tv-show/${encodeURIComponent(title || '')}/watch?season=${encodeURIComponent(nextSeason.name)}&episode=${encodeURIComponent(firstEpisode.fileName || '')}`, { replace: true });

        toast({
          title: "Starting Next Season",
          description: `${nextSeason.name}: ${firstEpisode.name}`,
        });
      }
    } else {
      toast({
        title: "End of Series",
        description: "You've watched all available episodes.",
      });
    }
  };

  // Watch for changes in seasons or episodes selection
  useEffect(() => {
    if (seasons.length && selectedSeason && selectedEpisode) {
      // Find active season and episode indexes
      const seasonIndex = seasons.findIndex(s => s.name === selectedSeason);
      if (seasonIndex >= 0) {
        setActiveSeasonIndex(seasonIndex);

        const episodeIndex = seasons[seasonIndex].episodes.findIndex(
          e => e.fileName === selectedEpisode
        );
        if (episodeIndex >= 0) {
          setActiveEpisodeIndex(episodeIndex);
        }
      }
    }
  }, [seasons, selectedSeason, selectedEpisode]);

  useEffect(() => {
    const fetchData = async () => {
      if (!title) return;

      try {
        setLoading(true);
        setError(null);

        // Load saved playback progress
        loadPlaybackProgress();

        // Get TV show metadata first
        const showData = await getTvShowMetadata(title);
        setShowInfo(showData);
        console.log('TV Show Metadata:', showData);
        setShowName(showInfo?.data?.translations?.nameTranslations?.find((t: any) => t.language === 'eng')?.name || showInfo?.name || '');
        // Process seasons and episodes from file structure
        if (showData && showData.file_structure) {
          const processedSeasons = processTvShowFileStructure(showData.file_structure);
          setSeasons(processedSeasons);

          // Set selected season and episode from URL params or select first available
          if (seasonParam && episodeParam) {
            setSelectedSeason(seasonParam);
            setSelectedEpisode(episodeParam);
          } else {
            selectFirstAvailableEpisode(processedSeasons);
          }
        }
      } catch (error) {
        console.error(`Error fetching metadata for ${title}:`, error);
        setError('Failed to load episode data');
        toast({
          title: "Error Loading Data",
          description: "Please try again later",
          variant: "destructive"
        });
      } finally {
        setLoading(false);
      }
    };

    fetchData();
  }, [title, seasonParam, episodeParam, toast]);

  const handleBack = () => {
    navigate(`/tv-show/${encodeURIComponent(title || '')}`);
  };

  const getEpisodeNumber = () => {
    if (!selectedEpisode) return "1";

    const episodeMatch = selectedEpisode.match(/E(\d+)/i);
    return episodeMatch ? episodeMatch[1] : "1";
  };

  const handleSelectEpisode = (seasonName: string, episode: Episode) => {
    // Only reload if we're changing episodes
    if (selectedEpisode !== episode.fileName) {
      setSelectedSeason(seasonName);
      setSelectedEpisode(episode.fileName || '');
      setNeedsReload(true);

      // Update URL
      navigate(`/tv-show/${encodeURIComponent(title || '')}/watch?season=${encodeURIComponent(seasonName)}&episode=${encodeURIComponent(episode.fileName || '')}`, { replace: true });
    }

    setShowEpisodeSelector(false);
  };

  const handleProgressUpdate = (currentTime: number, duration: number) => {
    if (!selectedEpisode || !title) return;

    const episodeId = `${selectedSeason}-${selectedEpisode}`;
    const isCompleted = (currentTime / duration) > 0.9; // Mark as completed if watched 90%

    savePlaybackProgress(episodeId, currentTime, duration, isCompleted);
  };

  const getStartTime = () => {
    if (!selectedSeason || !selectedEpisode) return 0;

    const episodeId = `${selectedSeason}-${selectedEpisode}`;
    const progress = playbackProgress[episodeId];

    if (progress && !progress.completed) {
      return progress.currentTime;
    }
    return 0;
  };

  const episodeTitle = showInfo
    ? `${showInfo.data?.name} ${selectedSeason}E${getEpisodeNumber()}`
    : `Episode`;
  // Reset needs reload flag when video has been updated
  useEffect(() => {
    if (needsReload) {
      setNeedsReload(false);
    }
  }, [selectedEpisode, selectedSeason]);

  if (loading) {
    return (
      <div className="flex items-center justify-center min-h-screen bg-black">
        <div className="animate-spin rounded-full h-12 w-12 border-t-2 border-b-2 border-red-600"></div>
      </div>
    );
  }

  // To force reload of video component when changing episodes
  const tvShowPlayerKey = `${selectedSeason}-${selectedEpisode}-${needsReload ? 'reload' : 'loaded'}`;

  return (
    <div className="min-h-screen bg-black relative overflow-hidden">
      {/* Episodes panel */}
      {showEpisodeSelector && (
        <div className="fixed inset-0 z-40 bg-black/80" onClick={() => setShowEpisodeSelector(false)}>
          <div
            className="fixed right-0 top-0 bottom-0 w-full md:w-1/3 lg:w-1/4 bg-gray-900 z-50 overflow-y-auto"
            onClick={e => e.stopPropagation()}
          >
            <EpisodesPanel
              seasons={seasons}
              selectedSeason={selectedSeason}
              selectedEpisode={selectedEpisode}
              playbackProgress={playbackProgress}
              onSelectEpisode={handleSelectEpisode}
              onClose={() => setShowEpisodeSelector(false)}
              showTitle={showName || 'Episodes'}
            />
          </div>
        </div>
      )}

      {/* TV Show Player component with key to force reload */}
      <TVShowPlayer
        key={tvShowPlayerKey}
        videoTitle={title || ''}
        season={selectedSeason}
        episode={selectedEpisode}
        movieTitle={title || ''}
        contentRatings={showInfo?.data?.contentRatings || []}
        thumbnail={showInfo?.data?.image || showInfo?.data?.poster_path}
        poster={showInfo?.data?.poster_path}
        startTime={getStartTime()}
        onClosePlayer={handleBack}
        onProgressUpdate={handleProgressUpdate}
        onVideoEnded={loadNextEpisode}
        onShowEpisodes={() => setShowEpisodeSelector(true)}
      />
    </div>
  );
};

export default TvShowPlayerPage;
