import React, { useCallback, useMemo, memo, useState, useEffect } from 'react';
import {
  View,
  Text,
  StyleSheet,
  TouchableOpacity,
  ActivityIndicator,
  FlatList,
  SectionList,
  Platform,
  ImageBackground,
  ScrollView,
  StatusBar,
  Alert
} from 'react-native';
import { useRoute, useNavigation } from '@react-navigation/native';
import { RouteProp } from '@react-navigation/native';
import { NavigationProp } from '@react-navigation/native';
import { MaterialIcons } from '@expo/vector-icons';
import { LinearGradient } from 'expo-linear-gradient';
import { Image } from 'expo-image';
import { RootStackParamList, RootStackNavigationProp } from '../navigation/AppNavigator';
import { useMetadata } from '../hooks/useMetadata';
import { colors } from '../styles/colors';
import { Stream } from '../types/metadata';
import { tmdbService } from '../services/tmdbService';
import { stremioService } from '../services/stremioService';
import { VideoPlayerService } from '../services/videoPlayerService';
import { useSettings } from '../hooks/useSettings';
import Animated, {
  FadeIn,
  FadeInDown,
  SlideInDown,
  withSpring,
  withTiming,
  useAnimatedStyle,
  useSharedValue,
  interpolate,
  Extrapolate,
  runOnJS,
  cancelAnimation,
  SharedValue
} from 'react-native-reanimated';
import { torrentService } from '../services/torrentService';
import { TorrentProgress } from '../services/torrentService';

const TMDB_LOGO = 'https://upload.wikimedia.org/wikipedia/commons/thumb/8/89/Tmdb.new.logo.svg/512px-Tmdb.new.logo.svg.png?20200406190906';
const HDR_ICON = 'https://uxwing.com/wp-content/themes/uxwing/download/video-photography-multimedia/hdr-icon.png';
const DOLBY_ICON = 'https://upload.wikimedia.org/wikipedia/en/thumb/3/3f/Dolby_Vision_%28logo%29.svg/512px-Dolby_Vision_%28logo%29.svg.png?20220908042900';

// Extracted Components
const StreamCard = memo(({ stream, onPress, index, torrentProgress, isLoading, statusMessage }: { 
  stream: Stream; 
  onPress: () => void; 
  index: number;
  torrentProgress?: TorrentProgress;
  isLoading?: boolean;
  statusMessage?: string;
}) => {
  const quality = stream.title?.match(/(\d+)p/)?.[1] || null;
  const isHDR = stream.title?.toLowerCase().includes('hdr');
  const isDolby = stream.title?.toLowerCase().includes('dolby') || stream.title?.includes('DV');
  const size = stream.title?.match(/💾\s*([\d.]+\s*[GM]B)/)?.[1];
  const isTorrent = stream.url?.startsWith('magnet:') || stream.behaviorHints?.isMagnetStream;
  const isDebrid = stream.behaviorHints?.cached;

  const displayTitle = stream.name || stream.title || 'Unnamed Stream';
  const displayAddonName = stream.title || '';

  const entering = useMemo(() => 
    FadeInDown
      .delay(50 + Math.min(index, 10) * 30)
      .springify()
      .damping(15)
      .mass(0.9)
  , [index]);

  const handlePress = useCallback(() => {
    console.log('StreamCard pressed:', {
      isTorrent,
      isDebrid,
      hasProgress: !!torrentProgress,
      url: stream.url,
      behaviorHints: stream.behaviorHints
    });
    onPress();
  }, [isTorrent, isDebrid, torrentProgress, stream.url, stream.behaviorHints, onPress]);

  // Only disable if it's a torrent that's not debrid and not currently downloading
  const isDisabled = isTorrent && !isDebrid && !torrentProgress && !stream.behaviorHints?.notWebReady;

  // Keep track of downloading status
  const isDownloading = !!torrentProgress && isTorrent;

  return (
    <Animated.View entering={entering}>
      <TouchableOpacity 
        style={[
          styles.streamCard, 
          isDisabled && styles.streamCardDisabled,
          isLoading && styles.streamCardLoading
        ]} 
        onPress={handlePress}
        disabled={isDisabled || isLoading}
      >
        <View style={styles.streamDetails}>
          <View style={styles.streamNameRow}>
            <View style={styles.streamTitleContainer}>
              <Text style={styles.streamName}>
                {displayTitle}
              </Text>
              {displayAddonName && displayAddonName !== displayTitle && (
                <Text style={styles.streamAddonName}>
                  {displayAddonName}
                </Text>
              )}
            </View>
            
            {/* Show loading indicator if stream is loading */}
            {isLoading && (
              <View style={styles.loadingIndicator}>
                <ActivityIndicator size="small" color={colors.primary} />
                <Text style={styles.loadingText}>
                  {statusMessage || "Loading..."}
                </Text>
              </View>
            )}
            
            {/* Show download indicator for active downloads */}
            {isDownloading && (
              <View style={styles.downloadingIndicator}>
                <ActivityIndicator size="small" color={colors.primary} />
                <Text style={styles.downloadingText}>Downloading...</Text>
              </View>
            )}
          </View>
          
          <View style={styles.streamMetaRow}>
            {quality && (
              <View style={[styles.chip, { backgroundColor: colors.info }]}>
                <Text style={styles.chipText}>{quality}p</Text>
              </View>
            )}
            
            {isHDR && (
              <View style={[styles.chip, { backgroundColor: colors.success }]}>
                <Text style={styles.chipText}>HDR</Text>
              </View>
            )}
            
            {isDolby && (
              <View style={[styles.chip, { backgroundColor: colors.warning }]}>
                <Text style={styles.chipText}>DOLBY</Text>
              </View>
            )}
            
            {size && (
              <View style={[styles.chip, { backgroundColor: colors.darkGray }]}>
                <Text style={styles.chipText}>{size}</Text>
              </View>
            )}
            
            {isTorrent && !isDebrid && (
              <View style={[styles.chip, { backgroundColor: colors.error }]}>
                <Text style={styles.chipText}>TORRENT</Text>
              </View>
            )}
            
            {isDebrid && (
              <View style={[styles.chip, { backgroundColor: colors.success }]}>
                <Text style={styles.chipText}>DEBRID</Text>
              </View>
            )}
          </View>

          {/* Render progress bar if there's progress */}
          {torrentProgress && (
            <View style={styles.progressContainer}>
              <View 
                style={[
                  styles.progressBar, 
                  { width: `${torrentProgress.bufferProgress}%` }
                ]} 
              />
              <Text style={styles.progressText}>
                {`${Math.round(torrentProgress.bufferProgress)}% • ${Math.round(torrentProgress.downloadSpeed / 1024)} KB/s • ${torrentProgress.seeds} seeds`}
              </Text>
            </View>
          )}
        </View>
        
        <View style={styles.streamAction}>
          <MaterialIcons 
            name="play-arrow" 
            size={24} 
            color={isDisabled ? colors.textMuted : colors.primary} 
          />
        </View>
      </TouchableOpacity>
    </Animated.View>
  );
}, (prevProps, nextProps) => {
  // Custom comparison to prevent unnecessary re-renders
  return prevProps.stream.url === nextProps.stream.url &&
         prevProps.index === nextProps.index &&
         prevProps.torrentProgress?.bufferProgress === nextProps.torrentProgress?.bufferProgress;
});

const QualityTag = React.memo(({ text, color }: { text: string; color: string }) => (
  <View style={[styles.chip, { backgroundColor: color }]}>
    <Text style={styles.chipText}>{text}</Text>
  </View>
));

const ProviderFilter = memo(({ 
  selectedProvider, 
  providers, 
  onSelect 
}: { 
  selectedProvider: string; 
  providers: Array<{ id: string; name: string; }>; 
  onSelect: (id: string) => void;
}) => {
  const renderItem = useCallback(({ item }: { item: { id: string; name: string } }) => (
    <TouchableOpacity
      key={item.id}
      style={[
        styles.filterChip,
        selectedProvider === item.id && styles.filterChipSelected
      ]}
      onPress={() => onSelect(item.id)}
    >
      <Text style={[
        styles.filterChipText,
        selectedProvider === item.id && styles.filterChipTextSelected
      ]}>
        {item.name}
      </Text>
    </TouchableOpacity>
  ), [selectedProvider, onSelect]);

  return (
    <FlatList
      data={providers}
      renderItem={renderItem}
      keyExtractor={item => item.id}
      horizontal
      showsHorizontalScrollIndicator={false}
      style={styles.filterScroll}
      bounces={true}
      overScrollMode="never"
      decelerationRate="fast"
      initialNumToRender={5}
      maxToRenderPerBatch={3}
      windowSize={3}
      getItemLayout={(data, index) => ({
        length: 100, // Approximate width of each item
        offset: 100 * index,
        index,
      })}
    />
  );
});

export const StreamsScreen = () => {
  const route = useRoute<RouteProp<RootStackParamList, 'Streams'>>();
  const navigation = useNavigation<RootStackNavigationProp>();
  const { id, type, episodeId } = route.params;
  const { settings } = useSettings();

  // Add timing logs
  const [loadStartTime, setLoadStartTime] = useState(0);
  const [providerLoadTimes, setProviderLoadTimes] = useState<{[key: string]: number}>({});
  
  const {
    metadata,
    episodes,
    groupedStreams,
    loadingStreams,
    episodeStreams,
    loadingEpisodeStreams,
    selectedEpisode,
    loadStreams,
    loadEpisodeStreams,
    setSelectedEpisode,
    groupedEpisodes,
  } = useMetadata({ id, type });

  const [selectedProvider, setSelectedProvider] = React.useState('all');
  const [availableProviders, setAvailableProviders] = React.useState<Set<string>>(new Set());

  // Optimize animation values with cleanup
  const headerOpacity = useSharedValue(0);
  const heroScale = useSharedValue(0.95);
  const filterOpacity = useSharedValue(0);

  // Add new state for torrent progress
  const [torrentProgress, setTorrentProgress] = React.useState<{[key: string]: TorrentProgress}>({});
  const [activeTorrent, setActiveTorrent] = React.useState<string | null>(null);

  // Add new state to track video player status
  const [isVideoPlaying, setIsVideoPlaying] = React.useState(false);
  
  // Add state for provider loading status
  const [loadingProviders, setLoadingProviders] = useState<{[key: string]: boolean}>({});
  
  // Add state for more detailed provider loading tracking
  const [providerStatus, setProviderStatus] = useState<{
    [key: string]: {
      loading: boolean;
      success: boolean;
      error: boolean;
      message: string;
      timeStarted: number;
      timeCompleted: number;
    }
  }>({});

  // Monitor streams loading start
  useEffect(() => {
    if (loadingStreams || loadingEpisodeStreams) {
      console.log("⏱️ Stream loading started");
      const now = Date.now();
      setLoadStartTime(now);
      setProviderLoadTimes({});
      
      // Reset provider status
      setProviderStatus({
        'source_1': {
          loading: true,
          success: false,
          error: false,
          message: 'Loading...',
          timeStarted: now,
          timeCompleted: 0
        },
        'source_2': {
          loading: true,
          success: false,
          error: false,
          message: 'Loading...',
          timeStarted: now,
          timeCompleted: 0
        },
        'stremio': {
          loading: true,
          success: false,
          error: false,
          message: 'Loading...',
          timeStarted: now,
          timeCompleted: 0
        }
      });
      
      // Also update the simpler loading state
      setLoadingProviders({
        'source_1': true, 
        'source_2': true,
        'stremio': true
      });
    }
  }, [loadingStreams, loadingEpisodeStreams]);
  
  // Monitor new provider results as they appear
  useEffect(() => {
    const streams = type === 'series' ? episodeStreams : groupedStreams;
    const now = Date.now();
    
    // Check for new providers
    Object.keys(streams).forEach(provider => {
      // Identify the parent provider (source_1, source_2, stremio addon)
      let parentProvider = provider;
      if (provider !== 'source_1' && provider !== 'source_2') {
        parentProvider = 'stremio';
      }
      
      // Update provider status when new streams appear
      setProviderStatus(prev => {
        const loadTime = now - loadStartTime;
        console.log(`✅ Provider "${parentProvider}" loaded successfully after ${loadTime}ms with ${streams[provider].streams.length} streams`);
        
        // Only update if it was previously loading
        if (prev[parentProvider]?.loading) {
          return {
            ...prev,
            [parentProvider]: {
              ...prev[parentProvider],
              loading: false,
              success: true,
              message: `Loaded ${streams[provider].streams.length} streams`,
              timeCompleted: now
            }
          };
        }
        return prev;
      });
      
      // Update the simpler loading state
      setLoadingProviders((prev: {[key: string]: boolean}) => ({...prev, [parentProvider]: false}));
    });
  }, [episodeStreams, groupedStreams, type, loadStartTime]);
  
  // Mark loading as complete when all loading is done
  useEffect(() => {
    if (!loadingStreams && !loadingEpisodeStreams) {
      // Check for any providers that are still marked as loading but didn't complete
      setProviderStatus(prev => {
        const updatedStatus = {...prev};
        let updated = false;
        
        Object.keys(updatedStatus).forEach(provider => {
          if (updatedStatus[provider]?.loading) {
            updatedStatus[provider] = {
              ...updatedStatus[provider],
              loading: false,
              error: true,
              message: 'Failed to load',
              timeCompleted: Date.now()
            };
            updated = true;
            console.log(`⚠️ Provider "${provider}" timed out or failed`);
            
            // Update the simpler loading state
            setLoadingProviders((prevLoading: {[key: string]: boolean}) => ({...prevLoading, [provider]: false}));
          }
        });
        
        return updated ? updatedStatus : prev;
      });
    }
  }, [loadingStreams, loadingEpisodeStreams]);

  React.useEffect(() => {
    if (type === 'series' && episodeId) {
      console.log(`🎬 Loading episode streams for: ${episodeId}`);
      setLoadingProviders({
        'source_1': true, 
        'source_2': true,
        'stremio': true
      });
      setSelectedEpisode(episodeId);
      loadEpisodeStreams(episodeId);
    } else if (type === 'movie') {
      console.log(`🎬 Loading movie streams for: ${id}`);
      setLoadingProviders({
        'source_1': true, 
        'source_2': true,
        'stremio': true
      });
      loadStreams();
    }
  }, [type, episodeId]);

  React.useEffect(() => {
    const streams = type === 'series' ? episodeStreams : groupedStreams;
    const providers = new Set(Object.keys(streams));
    setAvailableProviders(providers);
  }, [type, groupedStreams, episodeStreams]);

  React.useEffect(() => {
    // Trigger entrance animations
    headerOpacity.value = withTiming(1, { duration: 400 });
    heroScale.value = withSpring(1, {
      damping: 15,
      stiffness: 100,
      mass: 0.9,
      restDisplacementThreshold: 0.01
    });
    filterOpacity.value = withTiming(1, { duration: 500 });

    return () => {
      // Cleanup animations on unmount
      cancelAnimation(headerOpacity);
      cancelAnimation(heroScale);
      cancelAnimation(filterOpacity);
    };
  }, []);

  // Memoize handlers
  const handleBack = useCallback(() => {
    const cleanup = () => {
      headerOpacity.value = withTiming(0, { duration: 200 });
      heroScale.value = withTiming(0.95, { duration: 200 });
      filterOpacity.value = withTiming(0, { duration: 200 });
    };
    cleanup();
    
    // For series episodes, always replace current screen with metadata screen
    if (type === 'series') {
      navigation.replace('Metadata', {
        id: id,
        type: type
      });
    } else {
      navigation.goBack();
    }
  }, [navigation, headerOpacity, heroScale, filterOpacity, type, id]);

  const handleProviderChange = useCallback((provider: string) => {
    setSelectedProvider(provider);
  }, []);

  const currentEpisode = useMemo(() => {
    if (!selectedEpisode) return null;

    // Search through all episodes in all seasons
    const allEpisodes = Object.values(groupedEpisodes).flat();
    return allEpisodes.find(ep => 
      ep.stremioId === selectedEpisode || 
      `${id}:${ep.season_number}:${ep.episode_number}` === selectedEpisode
    );
  }, [selectedEpisode, groupedEpisodes, id]);

  // Update handleStreamPress
  const handleStreamPress = useCallback(async (stream: Stream) => {
    try {
      if (stream.url) {
        console.log('handleStreamPress called with stream:', {
          url: stream.url,
          behaviorHints: stream.behaviorHints,
          isMagnet: stream.url.startsWith('magnet:'),
          isMagnetStream: stream.behaviorHints?.isMagnetStream,
          useExternalPlayer: settings.useExternalPlayer
        });
        
        // Check if it's a magnet link either directly or through behaviorHints
        const isMagnet = stream.url.startsWith('magnet:') || stream.behaviorHints?.isMagnetStream;
        
        if (isMagnet) {
          console.log('Handling magnet link...');
          // Check if there's already an active torrent
          if (activeTorrent && activeTorrent !== stream.url) {
            Alert.alert(
              'Active Download',
              'There is already an active download. Do you want to stop it and start this one?',
              [
                {
                  text: 'Cancel',
                  style: 'cancel'
                },
                {
                  text: 'Stop and Switch',
                  style: 'destructive',
                  onPress: async () => {
                    console.log('Stopping current torrent and starting new one');
                    await torrentService.stopStreamAndWait();
                    setActiveTorrent(null);
                    setTorrentProgress({});
                    startTorrentStream(stream);
                  }
                }
              ]
            );
            return;
          }

          console.log('Starting torrent stream...');
          startTorrentStream(stream);
        } else {
          console.log('Playing regular stream...');
          
          // Check if external player is enabled in settings
          if (settings.useExternalPlayer) {
            console.log('Using external player for URL:', stream.url);
            // Use VideoPlayerService to launch external player
            try {
              const videoPlayerService = VideoPlayerService;
              await videoPlayerService.playVideo(stream.url, {
                useExternalPlayer: true,
                title: metadata?.name || '',
                episodeTitle: type === 'series' ? currentEpisode?.name : undefined,
                episodeNumber: type === 'series' ? `S${currentEpisode?.season_number}E${currentEpisode?.episode_number}` : undefined,
                releaseDate: metadata?.year?.toString(),
              });
            } catch (externalPlayerError) {
              console.error('External player error:', externalPlayerError);
              // Fallback to built-in player if external player fails
              navigation.navigate('Player', {
                uri: stream.url,
                title: metadata?.name || '',
                episodeTitle: type === 'series' ? currentEpisode?.name : undefined,
                season: type === 'series' ? currentEpisode?.season_number : undefined,
                episode: type === 'series' ? currentEpisode?.episode_number : undefined,
                quality: stream.title?.match(/(\d+)p/)?.[1] || undefined,
                year: metadata?.year,
                streamProvider: stream.name
              });
            }
          } else {
            // Use built-in player
            navigation.navigate('Player', {
              uri: stream.url,
              title: metadata?.name || '',
              episodeTitle: type === 'series' ? currentEpisode?.name : undefined,
              season: type === 'series' ? currentEpisode?.season_number : undefined,
              episode: type === 'series' ? currentEpisode?.episode_number : undefined,
              quality: stream.title?.match(/(\d+)p/)?.[1] || undefined,
              year: metadata?.year,
              streamProvider: stream.name
            });
          }
        }
      }
    } catch (error) {
      console.error('Stream error:', error);
      Alert.alert(
        'Playback Error',
        error instanceof Error ? error.message : 'An error occurred while playing the video'
      );
    }
  }, [metadata, type, currentEpisode, activeTorrent, navigation, settings.useExternalPlayer]);

  // Clean up torrent when component unmounts or when returning from player
  React.useEffect(() => {
    const unsubscribe = navigation.addListener('focus', () => {
      // This runs when returning from the player screen
      console.log('[StreamsScreen] Screen focused, checking if cleanup needed');
      if (isVideoPlaying) {
        console.log('[StreamsScreen] Playback ended, cleaning up torrent');
        setIsVideoPlaying(false);
        
        // Clean up the torrent when returning from video player
        if (activeTorrent) {
          console.log('[StreamsScreen] Stopping torrent after playback');
          torrentService.stopStreamAndWait().catch(error => {
            console.error('[StreamsScreen] Error during cleanup:', error);
          });
          setActiveTorrent(null);
          setTorrentProgress({});
        }
      }
    });

    return () => {
      unsubscribe();
      console.log('[StreamsScreen] Component unmounting, cleaning up torrent');
      if (activeTorrent) {
        console.log('[StreamsScreen] Stopping torrent on unmount');
        torrentService.stopStreamAndWait().catch(error => {
          console.error('[StreamsScreen] Error during cleanup:', error);
        });
      }
    };
  }, [navigation, activeTorrent, isVideoPlaying]);

  const startTorrentStream = useCallback(async (stream: Stream) => {
    if (!stream.url) return;

    try {
      console.log('[StreamsScreen] Starting torrent stream with URL:', stream.url);
      
      // Make sure any existing stream is fully stopped
      if (activeTorrent && activeTorrent !== stream.url) {
        await torrentService.stopStreamAndWait();
        setActiveTorrent(null);
        setTorrentProgress({});
      }
      
      setActiveTorrent(stream.url);
      setIsVideoPlaying(false);
      
      const videoPath = await torrentService.startStream(stream.url, {
        onProgress: (progress) => {
          // Check if progress object is valid and has data
          if (!progress || Object.keys(progress).length === 0) {
            console.log('[StreamsScreen] Received empty progress object, ignoring');
            return;
          }
          
          console.log('[StreamsScreen] Torrent progress update:', {
            url: stream.url,
            progress,
            currentTorrentProgress: torrentProgress[stream.url!]
          });
          
          // Validate progress values before updating state
          if (typeof progress.bufferProgress === 'number' || 
              typeof progress.downloadSpeed === 'number' ||
              typeof progress.progress === 'number' ||
              typeof progress.seeds === 'number') {
            
            setTorrentProgress(prev => ({
              ...prev,
              [stream.url!]: progress
            }));
          }
        }
      });
      
      console.log('[StreamsScreen] Got video path:', videoPath);
      
      // Once we have the video file path, play it using VideoPlayer screen
      if (videoPath) {
        setIsVideoPlaying(true);
        
        try {
          if (settings.useExternalPlayer) {
            console.log('[StreamsScreen] Using external player for torrent video path:', videoPath);
            // Use VideoPlayerService to launch external player
            try {
              const videoPlayerService = VideoPlayerService;
              await videoPlayerService.playVideo(`file://${videoPath}`, {
                useExternalPlayer: true,
                title: metadata?.name || '',
                episodeTitle: type === 'series' ? currentEpisode?.name : undefined,
                episodeNumber: type === 'series' ? `S${currentEpisode?.season_number}E${currentEpisode?.episode_number}` : undefined,
                releaseDate: metadata?.year?.toString(),
              });
            } catch (externalPlayerError) {
              console.error('[StreamsScreen] External player error:', externalPlayerError);
              // Fallback to built-in player if external player fails
              navigation.navigate('Player', {
                uri: `file://${videoPath}`,
                title: metadata?.name || '',
                episodeTitle: type === 'series' ? currentEpisode?.name : undefined,
                season: type === 'series' ? currentEpisode?.season_number : undefined,
                episode: type === 'series' ? currentEpisode?.episode_number : undefined,
                year: metadata?.year
              });
            }
          } else {
            // Use built-in player
            navigation.navigate('Player', {
              uri: `file://${videoPath}`,
              title: metadata?.name || '',
              episodeTitle: type === 'series' ? currentEpisode?.name : undefined,
              season: type === 'series' ? currentEpisode?.season_number : undefined,
              episode: type === 'series' ? currentEpisode?.episode_number : undefined,
              year: metadata?.year
            });
          }
          
          // Note: Cleanup happens in the focus effect when returning from the player
        } catch (playerError) {
          console.error('[StreamsScreen] Video player navigation error:', playerError);
          setIsVideoPlaying(false);
          
          // Also stop the torrent on player error
          console.log('[StreamsScreen] Stopping torrent after player error');
          await torrentService.stopStreamAndWait();
          setActiveTorrent(null);
          setTorrentProgress({});
          
          throw playerError;
        }
      } else {
        // If we didn't get a video path, there's a problem
        console.error('[StreamsScreen] No video path returned from torrent service');
        Alert.alert(
          'Playback Error',
          'No video file found in torrent'
        );
        await torrentService.stopStreamAndWait();
        setActiveTorrent(null);
        setTorrentProgress({});
      }
      
    } catch (error) {
      console.error('[StreamsScreen] Torrent error:', error);
      // Clean up on error
      setIsVideoPlaying(false);
      await torrentService.stopStreamAndWait();
      setActiveTorrent(null);
      setTorrentProgress({});
      Alert.alert(
        'Download Error',
        error instanceof Error ? error.message : 'An error occurred while playing the video'
      );
    }
  }, [metadata, type, currentEpisode, torrentProgress, activeTorrent, navigation, settings.useExternalPlayer]);

  const filterItems = useMemo(() => {
    const installedAddons = stremioService.getInstalledAddons();
    const streams = type === 'series' ? episodeStreams : groupedStreams;

    return [
      { id: 'all', name: 'All Providers' },
      ...Array.from(availableProviders)
        .sort((a, b) => {
          const indexA = installedAddons.findIndex(addon => addon.id === a);
          const indexB = installedAddons.findIndex(addon => addon.id === b);
          
          if (indexA !== -1 && indexB !== -1) return indexA - indexB;
          if (indexA !== -1) return -1;
          if (indexB !== -1) return 1;
          return 0;
        })
        .map(provider => {
          const addonInfo = streams[provider];
          const installedAddon = installedAddons.find(addon => addon.id === provider);
          
          let displayName = provider;
          if (provider === 'source_1') displayName = 'Source 1';
          else if (provider === 'source_2') displayName = 'Source 2';
          else if (provider === 'external_sources') displayName = 'External Sources';
          else if (installedAddon) displayName = installedAddon.name;
          else if (addonInfo?.addonName) displayName = addonInfo.addonName;
          
          return { id: provider, name: displayName };
        })
    ];
  }, [availableProviders, type, episodeStreams, groupedStreams]);

  const sections = useMemo(() => {
    const streams = type === 'series' ? episodeStreams : groupedStreams;
    const installedAddons = stremioService.getInstalledAddons();

    // Remove test addon section
    return Object.entries(streams)
      .filter(([addonId]) => {
        // Filter out test_addon and source_1
        if (addonId === 'test_addon' || addonId === 'source_1') return false;
        return selectedProvider === 'all' || selectedProvider === addonId;
      })
      .sort(([addonIdA], [addonIdB]) => {
        const indexA = installedAddons.findIndex(addon => addon.id === addonIdA);
        const indexB = installedAddons.findIndex(addon => addon.id === addonIdB);
        
        if (indexA !== -1 && indexB !== -1) return indexA - indexB;
        if (indexA !== -1) return -1;
        if (indexB !== -1) return 1;
        return 0;
      })
      .map(([addonId, { addonName, streams }]) => ({
        title: addonName,
        addonId,
        data: streams
      }));
  }, [selectedProvider, type, episodeStreams, groupedStreams]);

  const episodeImage = useMemo(() => {
    if (!currentEpisode) return null;
    if (currentEpisode.still_path) {
      return tmdbService.getImageUrl(currentEpisode.still_path, 'original');
    }
    return metadata?.poster || null;
  }, [currentEpisode, metadata]);

  const isLoading = type === 'series' ? loadingEpisodeStreams : loadingStreams;
  const streams = type === 'series' ? episodeStreams : groupedStreams;

  const heroStyle = useAnimatedStyle(() => ({
    transform: [{ scale: heroScale.value }],
    opacity: headerOpacity.value
  }));

  const filterStyle = useAnimatedStyle(() => ({
    opacity: filterOpacity.value,
    transform: [
      { 
        translateY: interpolate(
          filterOpacity.value,
          [0, 1],
          [20, 0],
          Extrapolate.CLAMP
        )
      }
    ]
  }));

  const renderItem = useCallback(({ item, index, section }: { item: Stream; index: number; section: any }) => {
    const stream = item;
    const progress = torrentProgress[stream.url!];
    const isLoading = loadingProviders[section.addonId];
    
    return (
      <StreamCard 
        stream={stream} 
        onPress={() => handleStreamPress(stream)} 
        index={index}
        torrentProgress={progress}
        isLoading={isLoading}
        statusMessage={providerStatus[section.addonId]?.message}
      />
    );
  }, [handleStreamPress, torrentProgress, loadingProviders, providerStatus]);

  const renderSectionHeader = useCallback(({ section }: { section: { title: string } }) => (
    <Animated.View
      entering={FadeInDown.delay(150).springify()}
    >
      <Text style={styles.streamGroupTitle}>{section.title}</Text>
    </Animated.View>
  ), []);

  return (
    <View style={styles.container}>
      <StatusBar
        translucent
        backgroundColor="transparent"
        barStyle="light-content"
      />
      
      <Animated.View
        entering={FadeIn.duration(300)}
        style={[styles.backButtonContainer]}
      >
        <TouchableOpacity 
          style={styles.backButton}
          onPress={handleBack}
          activeOpacity={0.7}
        >
          <MaterialIcons name="arrow-back" size={24} color="#fff" />
          <Text style={styles.backButtonText}>
            {type === 'series' ? 'Back to Episodes' : 'Back to Info'}
          </Text>
        </TouchableOpacity>
      </Animated.View>

      {type === 'series' && currentEpisode && (
        <Animated.View style={[styles.streamsHeroContainer, heroStyle]}>
          <ImageBackground
            source={episodeImage ? { uri: episodeImage } : undefined}
            style={styles.streamsHeroBackground}
            fadeDuration={0}
            resizeMode="cover"
          >
            <LinearGradient
              colors={[
                'rgba(0,0,0,0)',
                'rgba(0,0,0,0.4)',
                'rgba(0,0,0,0.7)',
                'rgba(0,0,0,0.85)',
                'rgba(0,0,0,0.95)',
                colors.darkBackground
              ]}
              locations={[0, 0.3, 0.5, 0.7, 0.85, 1]}
              style={styles.streamsHeroGradient}
            >
              <View style={styles.streamsHeroContent}>
                <View style={styles.streamsHeroInfo}>
                  <Text style={styles.streamsHeroEpisodeNumber}>
                    {currentEpisode.episodeString}
                  </Text>
                  <Text style={styles.streamsHeroTitle} numberOfLines={1}>
                    {currentEpisode.name}
                  </Text>
                  {currentEpisode.overview && (
                    <Text style={styles.streamsHeroOverview} numberOfLines={2}>
                      {currentEpisode.overview}
                    </Text>
                  )}
                  <View style={styles.streamsHeroMeta}>
                    <Text style={styles.streamsHeroReleased}>
                      {tmdbService.formatAirDate(currentEpisode.air_date)}
                    </Text>
                    {currentEpisode.vote_average > 0 && (
                      <View style={styles.streamsHeroRating}>
                        <Image
                          source={{ uri: TMDB_LOGO }}
                          style={styles.tmdbLogo}
                          contentFit="contain"
                        />
                        <Text style={styles.streamsHeroRatingText}>
                          {currentEpisode.vote_average.toFixed(1)}
                        </Text>
                      </View>
                    )}
                  </View>
                </View>
              </View>
            </LinearGradient>
          </ImageBackground>
        </Animated.View>
      )}

      <View style={[
        styles.streamsMainContent,
        type === 'movie' && styles.streamsMainContentMovie
      ]}>
        <Animated.View style={[styles.filterContainer, filterStyle]}>
          {Object.keys(streams).length > 0 && (
            <ProviderFilter
              selectedProvider={selectedProvider}
              providers={filterItems}
              onSelect={handleProviderChange}
            />
          )}
        </Animated.View>

        {isLoading && Object.keys(streams).length === 0 ? (
          <Animated.View 
            entering={FadeIn.duration(300)}
            style={styles.loadingContainer}
          >
            <ActivityIndicator size="large" color={colors.primary} />
            <Text style={styles.loadingText}>Finding available streams...</Text>
          </Animated.View>
        ) : Object.keys(streams).length === 0 ? (
          <Animated.View 
            entering={FadeIn.duration(300)}
            style={styles.noStreams}
          >
            <MaterialIcons name="error-outline" size={48} color={colors.textMuted} />
            <Text style={styles.noStreamsText}>No streams available</Text>
          </Animated.View>
        ) : (
          <SectionList
            sections={sections}
            keyExtractor={(item, index) => `${item.url}-${index}`}
            renderItem={renderItem}
            renderSectionHeader={renderSectionHeader}
            stickySectionHeadersEnabled={false}
            initialNumToRender={8}
            maxToRenderPerBatch={4}
            windowSize={5}
            removeClippedSubviews={true}
            contentContainerStyle={styles.streamsContainer}
            style={styles.streamsContent}
            showsVerticalScrollIndicator={false}
            bounces={true}
            overScrollMode="never"
            getItemLayout={(data, index) => ({
              length: 86, // Height of each stream card + margin
              offset: 86 * index,
              index,
            })}
            maintainVisibleContentPosition={{
              minIndexForVisible: 0,
              autoscrollToTopThreshold: 10
            }}
            ListFooterComponent={
              isLoading ? (
                <View style={styles.footerLoading}>
                  <ActivityIndicator size="small" color={colors.primary} />
                  <Text style={styles.footerLoadingText}>Loading more sources...</Text>
                </View>
              ) : null
            }
          />
        )}
      </View>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: colors.darkBackground,
  },
  backButtonContainer: {
    position: 'absolute',
    top: 0,
    left: 0,
    right: 0,
    zIndex: 1,
  },
  backButton: {
    flexDirection: 'row',
    alignItems: 'center',
    gap: 8,
    padding: 14,
    paddingTop: Platform.OS === 'android' ? 35 : 45,
  },
  backButtonText: {
    color: colors.highEmphasis,
    fontSize: 13,
    fontWeight: '600',
  },
  streamsMainContent: {
    flex: 1,
    backgroundColor: colors.darkBackground,
    paddingTop: 20,
  },
  streamsMainContentMovie: {
    paddingTop: Platform.OS === 'android' ? 90 : 100,
  },
  filterContainer: {
    paddingHorizontal: 16,
    paddingBottom: 12,
  },
  filterScroll: {
    flexGrow: 0,
  },
  filterChip: {
    backgroundColor: colors.transparentLight,
    paddingHorizontal: 16,
    paddingVertical: 8,
    borderRadius: 20,
    marginRight: 8,
    borderWidth: 1,
    borderColor: colors.transparent,
  },
  filterChipSelected: {
    backgroundColor: colors.transparentLight,
    borderColor: colors.primary,
  },
  filterChipText: {
    color: colors.text,
    fontWeight: '500',
  },
  filterChipTextSelected: {
    color: colors.primary,
    fontWeight: 'bold',
  },
  streamsContent: {
    flex: 1,
    width: '100%',
  },
  streamsContainer: {
    paddingHorizontal: 16,
    paddingBottom: 16,
    width: '100%',
  },
  streamGroup: {
    marginBottom: 24,
    width: '100%',
  },
  streamGroupTitle: {
    color: colors.text,
    fontSize: 16,
    fontWeight: '600',
    marginBottom: 4,
    marginTop: 0,
    backgroundColor: 'transparent',
  },
  streamCard: {
    flexDirection: 'row',
    alignItems: 'flex-start',
    padding: 12,
    borderRadius: 12,
    marginBottom: 8,
    minHeight: 70,
    backgroundColor: colors.elevation1,
    borderWidth: 1,
    borderColor: 'rgba(255,255,255,0.05)',
    width: '100%',
  },
  streamCardDisabled: {
    backgroundColor: colors.elevation2,
  },
  streamCardLoading: {
    opacity: 0.7,
  },
  streamDetails: {
    flex: 1,
  },
  streamNameRow: {
    flexDirection: 'row',
    alignItems: 'flex-start',
    justifyContent: 'space-between',
    width: '100%',
    flexWrap: 'wrap',
    gap: 8
  },
  streamTitleContainer: {
    flex: 1,
  },
  streamName: {
    fontSize: 14,
    fontWeight: '600',
    marginBottom: 2,
    lineHeight: 20,
    color: colors.highEmphasis,
  },
  streamAddonName: {
    fontSize: 13,
    lineHeight: 18,
    color: colors.mediumEmphasis,
    marginBottom: 6,
  },
  streamMetaRow: {
    flexDirection: 'row',
    flexWrap: 'wrap',
    gap: 4,
    marginBottom: 6,
    alignItems: 'center',
  },
  chip: {
    paddingHorizontal: 8,
    paddingVertical: 2,
    borderRadius: 4,
    marginRight: 4,
    marginBottom: 4,
  },
  chipText: {
    color: colors.highEmphasis,
    fontSize: 12,
    fontWeight: '600',
  },
  progressContainer: {
    height: 20,
    backgroundColor: colors.transparentLight,
    borderRadius: 10,
    overflow: 'hidden',
    marginBottom: 6,
  },
  progressBar: {
    height: '100%',
    backgroundColor: colors.primary,
  },
  progressText: {
    color: colors.highEmphasis,
    fontSize: 12,
    fontWeight: '600',
    marginLeft: 8,
  },
  streamAction: {
    width: 40,
    height: 40,
    borderRadius: 20,
    backgroundColor: colors.elevation2,
    justifyContent: 'center',
    alignItems: 'center',
  },
  skeletonCard: {
    opacity: 0.7,
  },
  skeletonTitle: {
    height: 24,
    width: '40%',
    backgroundColor: colors.transparentLight,
    borderRadius: 4,
    marginBottom: 16,
  },
  skeletonIcon: {
    width: 24,
    height: 24,
    borderRadius: 12,
    backgroundColor: colors.transparentLight,
    marginRight: 12,
  },
  skeletonText: {
    height: 16,
    borderRadius: 4,
    marginBottom: 8,
    backgroundColor: colors.transparentLight,
  },
  skeletonTag: {
    width: 60,
    height: 20,
    borderRadius: 4,
    marginRight: 8,
    backgroundColor: colors.transparentLight,
  },
  noStreams: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    padding: 32,
  },
  noStreamsText: {
    color: colors.textMuted,
    fontSize: 16,
    marginTop: 16,
  },
  streamsHeroContainer: {
    width: '100%',
    height: 300,
    marginBottom: 0,
    position: 'relative',
    backgroundColor: colors.black,
  },
  streamsHeroBackground: {
    width: '100%',
    height: '100%',
    backgroundColor: colors.black,
  },
  streamsHeroGradient: {
    flex: 1,
    justifyContent: 'flex-end',
    padding: 16,
    paddingBottom: 0,
  },
  streamsHeroContent: {
    width: '100%',
  },
  streamsHeroInfo: {
    width: '100%',
  },
  streamsHeroEpisodeNumber: {
    color: colors.primary,
    fontSize: 14,
    fontWeight: 'bold',
    marginBottom: 2,
    textShadowColor: 'rgba(0,0,0,0.75)',
    textShadowOffset: { width: 0, height: 1 },
    textShadowRadius: 2,
  },
  streamsHeroTitle: {
    color: colors.highEmphasis,
    fontSize: 24,
    fontWeight: 'bold',
    marginBottom: 4,
    textShadowColor: 'rgba(0,0,0,0.75)',
    textShadowOffset: { width: 0, height: 1 },
    textShadowRadius: 3,
  },
  streamsHeroOverview: {
    color: colors.mediumEmphasis,
    fontSize: 14,
    lineHeight: 20,
    marginBottom: 2,
    textShadowColor: 'rgba(0,0,0,0.75)',
    textShadowOffset: { width: 0, height: 1 },
    textShadowRadius: 2,
  },
  streamsHeroMeta: {
    flexDirection: 'row',
    alignItems: 'center',
    gap: 12,
    marginTop: 0,
  },
  streamsHeroReleased: {
    color: colors.mediumEmphasis,
    fontSize: 14,
    textShadowColor: 'rgba(0,0,0,0.75)',
    textShadowOffset: { width: 0, height: 1 },
    textShadowRadius: 2,
  },
  streamsHeroRating: {
    flexDirection: 'row',
    alignItems: 'center',
    backgroundColor: 'rgba(0,0,0,0.7)',
    paddingHorizontal: 6,
    paddingVertical: 3,
    borderRadius: 4,
    marginTop: 0,
  },
  tmdbLogo: {
    width: 20,
    height: 14,
  },
  streamsHeroRatingText: {
    color: '#01b4e4',
    fontSize: 13,
    fontWeight: '700',
    marginLeft: 4,
  },
  loadingContainer: {
    alignItems: 'center',
    paddingVertical: 24,
  },
  loadingText: {
    color: colors.primary,
    fontSize: 12,
    marginLeft: 4,
    fontWeight: '500',
  },
  downloadingIndicator: {
    flexDirection: 'row',
    alignItems: 'center',
    backgroundColor: colors.transparentLight,
    paddingHorizontal: 8,
    paddingVertical: 2,
    borderRadius: 12,
    marginLeft: 8,
  },
  downloadingText: {
    color: colors.primary,
    fontSize: 12,
    marginLeft: 4,
    fontWeight: '500',
  },
  loadingIndicator: {
    flexDirection: 'row',
    alignItems: 'center',
    paddingHorizontal: 8,
    paddingVertical: 2,
    borderRadius: 12,
    marginLeft: 8,
  },
  footerLoading: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'center',
    padding: 16,
  },
  footerLoadingText: {
    color: colors.primary,
    fontSize: 12,
    marginLeft: 8,
    fontWeight: '500',
  },
});

export default memo(StreamsScreen); 