'use client';

import React, { createContext, useContext, useState, useEffect, useMemo, useCallback, useRef } from 'react';
import { Song } from '@/lib/navidrome';
import { getNavidromeAPI } from '@/lib/navidrome';
import { useToast } from "@/hooks/use-toast";
import { AudioEffects } from '@/lib/audio-effects';

export interface Track {
  id: string;
  name: string;
  url: string;
  artist: string;
  album: string;
  duration: number;
  coverArt?: string;
  albumId: string;
  artistId: string;
  autoPlay?: boolean;
  starred?: boolean;
  replayGain?: number; // Added ReplayGain field
}

interface AudioSettings {
  crossfadeDuration: number;
  equalizer: string;
  replayGainEnabled: boolean;
  gaplessPlayback: boolean;
}

interface AudioPlayerContextProps {
  currentTrack: Track | null;
  playTrack: (track: Track, autoPlay?: boolean) => void;
  queue: Track[];
  addToQueue: (track: Track) => void;
  insertAtBeginningOfQueue: (track: Track) => void;
  playNextTrack: () => void;
  clearQueue: () => void;
  addAlbumToQueue: (albumId: string) => Promise<void>;
  playAlbum: (albumId: string) => Promise<void>;
  playAlbumFromTrack: (albumId: string, startingSongId: string) => Promise<void>;
  removeTrackFromQueue: (index: number) => void;
  reorderQueue: (oldIndex: number, newIndex: number) => void;
  skipToTrackInQueue: (index: number) => void;
  addArtistToQueue: (artistId: string) => Promise<void>;
  playPreviousTrack: () => void;
  isLoading: boolean;
  shuffle: boolean;
  toggleShuffle: () => void;
  shuffleAllAlbums: () => Promise<void>;
  playArtist: (artistId: string) => Promise<void>;
  playedTracks: Track[];
  clearHistory: () => void;
  toggleCurrentTrackStar: () => Promise<void>;
  updateTrackStarred: (trackId: string, starred: boolean) => void;
  // Audio settings
  audioSettings: AudioSettings;
  updateAudioSettings: (settings: Partial<AudioSettings>) => void;
  equalizerPreset: string;
  setEqualizerPreset: (preset: string) => void;
  audioEffects: AudioEffects | null;
  // Playback state
  isPlaying: boolean;
  togglePlayPause: () => Promise<void>;
}

const AudioPlayerContext = createContext<AudioPlayerContextProps | undefined>(undefined);

export // Default audio settings
const DEFAULT_AUDIO_SETTINGS: AudioSettings = {
  crossfadeDuration: 3,
  equalizer: 'normal',
  replayGainEnabled: true,
  gaplessPlayback: true
};

export const AudioPlayerProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
  const [currentTrack, setCurrentTrack] = useState<Track | null>(null);
  const [queue, setQueue] = useState<Track[]>([]);
  const [playedTracks, setPlayedTracks] = useState<Track[]>([]);
  const [isLoading, setIsLoading] = useState(false);
  const [shuffle, setShuffle] = useState(false);
  const [audioSettings, setAudioSettings] = useState<AudioSettings>(DEFAULT_AUDIO_SETTINGS);
  const [equalizerPreset, setEqualizerPreset] = useState('normal');
  const [audioEffects, setAudioEffects] = useState<AudioEffects | null>(null);
  const audioRef = useRef<HTMLAudioElement | null>(null);
  const { toast } = useToast();
  const api = useMemo(() => {
    const navidromeApi = getNavidromeAPI();
    if (!navidromeApi) {
      console.warn('⚠️ Navidrome API not configured');
    } else {
      console.log('✅ Navidrome API initialized');
    }
    return navidromeApi;
  }, []);

  useEffect(() => {
    const savedQueue = localStorage.getItem('navidrome-audioQueue');
    if (savedQueue) {
      try {
        setQueue(JSON.parse(savedQueue));
      } catch (error) {
        console.error('Failed to parse saved queue:', error);
      }
    }
  }, []);

  useEffect(() => {
    localStorage.setItem('navidrome-audioQueue', JSON.stringify(queue));
  }, [queue]);

  useEffect(() => {
    const savedCurrentTrack = localStorage.getItem('navidrome-currentTrack');
    if (savedCurrentTrack) {
      try {
        const track = JSON.parse(savedCurrentTrack);
        // Check if there's a saved playback position - if so, user was likely playing
        const savedTime = localStorage.getItem('navidrome-current-track-time');
        track.autoPlay = savedTime !== null && parseFloat(savedTime) > 0;
        setCurrentTrack(track);
      } catch (error) {
        console.error('Failed to parse saved current track:', error);
      }
    }
  }, []);

  useEffect(() => {
    if (currentTrack) {
      // Remove autoPlay flag when saving to localStorage
      const { autoPlay, ...trackToSave } = currentTrack;
      localStorage.setItem('navidrome-currentTrack', JSON.stringify(trackToSave));
    } else {
      localStorage.removeItem('navidrome-currentTrack');
    }
  }, [currentTrack]);

  // Initialize audio effects when audio element is available
  useEffect(() => {
    const audioElement = audioRef.current;
    if (audioElement && !audioEffects) {
      const effects = new AudioEffects(audioElement);
      setAudioEffects(effects);

      // Load saved audio settings
      const savedSettings = localStorage.getItem('navidrome-audio-settings');
      if (savedSettings) {
        try {
          const settings = JSON.parse(savedSettings);
          setAudioSettings(settings);
          effects.setPreset(settings.equalizer);
          setEqualizerPreset(settings.equalizer);
        } catch (error) {
          console.error('Failed to load audio settings:', error);
        }
      }

      return () => {
        effects.disconnect();
      };
    }
  }, [audioEffects]);

  // Save all audio-related settings
  const saveSettings = useCallback(() => {
    try {
      // Save audio settings
      localStorage.setItem('navidrome-audio-settings', JSON.stringify(audioSettings));
      // Save equalizer preset
      localStorage.setItem('navidrome-equalizer-preset', equalizerPreset);
      // Save other playback settings
      const playbackSettings = {
        replayGainEnabled: audioSettings.replayGainEnabled,
        gaplessPlayback: audioSettings.gaplessPlayback,
        crossfadeDuration: audioSettings.crossfadeDuration,
        volume: audioRef.current?.volume || 1,
        lastPosition: audioRef.current?.currentTime || 0
      };
      localStorage.setItem('navidrome-playback-settings', JSON.stringify(playbackSettings));
    } catch (error) {
      console.error('Failed to save settings:', error);
    }
  }, [audioSettings, equalizerPreset]);

  // Save settings whenever they change
  useEffect(() => {
    saveSettings();
  }, [audioSettings, equalizerPreset, saveSettings]);

  // Update equalizer when preset changes
  useEffect(() => {
    if (audioEffects) {
      audioEffects.setPreset(equalizerPreset);
    }
  }, [equalizerPreset, audioEffects]);

  const updateAudioSettings = useCallback((settings: Partial<AudioSettings>) => {
    setAudioSettings(prev => {
      const newSettings = { ...prev, ...settings };
      localStorage.setItem('navidrome-audio-settings', JSON.stringify(newSettings));
      return newSettings;
    });
  }, []);

  const songToTrack = useMemo(() => (song: Song): Track => {
    if (!api) {
      throw new Error('Navidrome API not configured');
    }
    
    const streamUrl = api.getStreamUrl(song.id);
    console.log('🎵 Creating track with stream URL:', streamUrl);
    
    return {
      id: song.id,
      name: song.title,
      url: streamUrl,
      artist: song.artist,
      album: song.album,
      duration: song.duration,
      coverArt: song.coverArt ? api.getCoverArtUrl(song.coverArt, 512) : undefined,
      albumId: song.albumId,
      artistId: song.artistId,
      starred: !!song.starred,
      replayGain: song.replayGain || 0 // Add ReplayGain support
    };
  }, [api]);

  const playTrack = useCallback((track: Track, autoPlay: boolean = false) => {
    // Clear saved timestamp when manually playing a track
    localStorage.removeItem('navidrome-current-track-time');
    
    if (currentTrack) {
      setPlayedTracks((prev) => [...prev, currentTrack]);
    }
    
    // Set autoPlay flag on the track
    const trackWithAutoPlay = { ...track, autoPlay };
    setCurrentTrack(trackWithAutoPlay);
    
    // Scrobble the track if API is available
    if (api) {
      api.scrobble(track.id).catch(error => {
        console.error('Failed to scrobble track:', error);
      });
    }
  }, [currentTrack, api]);

  const addToQueue = useCallback((track: Track) => {
    setQueue((prevQueue) => {
      if (shuffle && prevQueue.length > 0) {
        // If shuffle is enabled, insert the track at a random position
        const randomIndex = Math.floor(Math.random() * (prevQueue.length + 1));
        const newQueue = [...prevQueue];
        newQueue.splice(randomIndex, 0, track);
        return newQueue;
      } else {
        // Normal behavior: add to the end
        return [...prevQueue, track];
      }
    });
  }, [shuffle]);

  const insertAtBeginningOfQueue = useCallback((track: Track) => {
    setQueue((prevQueue) => [track, ...prevQueue]);
  }, []);

  const clearQueue = useCallback(() => {
    setQueue([]);
  }, []);

  const removeTrackFromQueue = useCallback((index: number) => {
    setQueue((prevQueue) => prevQueue.filter((_, i) => i !== index));
  }, []);

  const reorderQueue = useCallback((oldIndex: number, newIndex: number) => {
    setQueue((prevQueue) => {
      const newQueue = [...prevQueue];
      const [movedItem] = newQueue.splice(oldIndex, 1);
      newQueue.splice(newIndex, 0, movedItem);
      return newQueue;
    });
  }, []);

  const playNextTrack = useCallback(() => {
    // Clear saved timestamp when changing tracks
    localStorage.removeItem('navidrome-current-track-time');
    
    if (queue.length > 0) {
      // Always pick the first track from the queue
      // If shuffle is enabled, the queue will already be shuffled
      const nextTrack = queue[0];
      setQueue((prevQueue) => prevQueue.slice(1));
      playTrack(nextTrack, true); // Auto-play next track
    }
  }, [queue, playTrack]);

  const playPreviousTrack = useCallback(() => {
    // Clear saved timestamp when changing tracks  
    localStorage.removeItem('navidrome-current-track-time');
    
    if (playedTracks.length > 0) {
      const previousTrack = playedTracks[playedTracks.length - 1];
      setPlayedTracks((prevPlayedTracks) => prevPlayedTracks.slice(0, -1));
      
      // Add current track back to beginning of queue
      if (currentTrack) {
        setQueue((prevQueue) => [currentTrack, ...prevQueue]);
      }
      
      playTrack(previousTrack, true); // Auto-play previous track
    }
  }, [playedTracks, currentTrack, playTrack]);

  const addAlbumToQueue = useCallback(async (albumId: string) => {
    if (!api) {
      toast({
        variant: "destructive",
        title: "Configuration Required",
        description: "Please configure Navidrome connection in settings",
      });
      return;
    }

    setIsLoading(true);
    try {
      const { album, songs } = await api.getAlbum(albumId);
      const tracks = songs.map(songToTrack);
      
      setQueue((prevQueue) => {
        if (shuffle && prevQueue.length > 0) {
          // If shuffle is enabled, shuffle the new tracks and insert them randomly
          const shuffledTracks = [...tracks];
          // Fisher-Yates shuffle algorithm
          for (let i = shuffledTracks.length - 1; i > 0; i--) {
            const j = Math.floor(Math.random() * (i + 1));
            [shuffledTracks[i], shuffledTracks[j]] = [shuffledTracks[j], shuffledTracks[i]];
          }
          
          // Insert each track at a random position
          const newQueue = [...prevQueue];
          shuffledTracks.forEach(track => {
            const randomIndex = Math.floor(Math.random() * (newQueue.length + 1));
            newQueue.splice(randomIndex, 0, track);
          });
          return newQueue;
        } else {
          // Normal behavior: add to the end
          return [...prevQueue, ...tracks];
        }
      });
      
      toast({
        title: "Album Added",
        description: `Added "${album.name}" to queue`,
      });
    } catch (error) {
      console.error('Failed to add album to queue:', error);
      toast({
        variant: "destructive",
        title: "Error",
        description: "Failed to add album to queue",
      });
    } finally {
      setIsLoading(false);
    }
  }, [api, songToTrack, toast, shuffle]);

  const addArtistToQueue = useCallback(async (artistId: string) => {
    if (!api) {
      toast({
        variant: "destructive",
        title: "Configuration Required",
        description: "Please configure Navidrome connection in settings",
      });
      return;
    }

    setIsLoading(true);
    try {
      const { artist, albums } = await api.getArtist(artistId);
      let allTracks: Track[] = [];
      
      // Collect all tracks from all albums
      for (const album of albums) {
        const { songs } = await api.getAlbum(album.id);
        const tracks = songs.map(songToTrack);
        allTracks = allTracks.concat(tracks);
      }
      
      setQueue((prevQueue) => {
        if (shuffle && prevQueue.length > 0) {
          // If shuffle is enabled, shuffle the new tracks and insert them randomly
          const shuffledTracks = [...allTracks];
          // Fisher-Yates shuffle algorithm
          for (let i = shuffledTracks.length - 1; i > 0; i--) {
            const j = Math.floor(Math.random() * (i + 1));
            [shuffledTracks[i], shuffledTracks[j]] = [shuffledTracks[j], shuffledTracks[i]];
          }
          
          // Insert each track at a random position
          const newQueue = [...prevQueue];
          shuffledTracks.forEach(track => {
            const randomIndex = Math.floor(Math.random() * (newQueue.length + 1));
            newQueue.splice(randomIndex, 0, track);
          });
          return newQueue;
        } else {
          // Normal behavior: add to the end
          return [...prevQueue, ...allTracks];
        }
      });
      
      toast({
        title: "Artist Added",
        description: `Added all albums by "${artist.name}" to queue`,
      });
    } catch (error) {
      console.error('Failed to add artist to queue:', error);
      toast({
        variant: "destructive",
        title: "Error",
        description: "Failed to add artist to queue",
      });
    } finally {
      setIsLoading(false);
    }
  }, [api, songToTrack, toast, shuffle]);
  const playAlbum = useCallback(async (albumId: string) => {
    if (!api) {
      toast({
        variant: "destructive",
        title: "Configuration Required",
        description: "Please configure Navidrome connection in settings",
      });
      return;
    }

    setIsLoading(true);
    try {
      const { album, songs } = await api.getAlbum(albumId);
      const tracks = songs.map(songToTrack);
      
      if (tracks.length > 0) {
        if (shuffle) {
          // If shuffle is enabled, shuffle the tracks
          const shuffledTracks = [...tracks];
          // Fisher-Yates shuffle algorithm
          for (let i = shuffledTracks.length - 1; i > 0; i--) {
            const j = Math.floor(Math.random() * (i + 1));
            [shuffledTracks[i], shuffledTracks[j]] = [shuffledTracks[j], shuffledTracks[i]];
          }
          
          // Play the first shuffled track and set the rest as queue
          playTrack(shuffledTracks[0], true); // Enable autoplay
          setQueue(shuffledTracks.slice(1));
        } else {
          // Normal order: play first track and set the rest as queue
          playTrack(tracks[0], true); // Enable autoplay
          setQueue(tracks.slice(1));
        }
      }
      
      toast({
        title: "Playing Album",
        description: `Now playing "${album.name}"${shuffle ? ' (shuffled)' : ''}`,
      });
    } catch (error) {
      console.error('Failed to play album:', error);
      toast({
        variant: "destructive",
        title: "Error",
        description: "Failed to play album",
      });
    } finally {
      setIsLoading(false);
    }
  }, [api, playTrack, songToTrack, toast, shuffle]);

  const playAlbumFromTrack = useCallback(async (albumId: string, startingSongId: string) => {
    if (!api) {
      toast({
        variant: "destructive",
        title: "Configuration Required",
        description: "Please configure Navidrome connection in settings",
      });
      return;
    }

    setIsLoading(true);
    try {
      const { album, songs } = await api.getAlbum(albumId);
      const tracks = songs.map(songToTrack);
      
      // Find the starting track index
      const startingIndex = tracks.findIndex(track => track.id === startingSongId);
      
      if (startingIndex === -1) {
        throw new Error('Starting song not found in album');
      }
      
      if (shuffle) {
        // If shuffle is enabled, create a shuffled queue but start with the selected track
        const remainingTracks = [...tracks];
        remainingTracks.splice(startingIndex, 1); // Remove the starting track
        
        // Shuffle the remaining tracks
        for (let i = remainingTracks.length - 1; i > 0; i--) {
          const j = Math.floor(Math.random() * (i + 1));
          [remainingTracks[i], remainingTracks[j]] = [remainingTracks[j], remainingTracks[i]];
        }
        
        setQueue(remainingTracks);
        playTrack(tracks[startingIndex], true); // Enable autoplay
      } else {
        // Normal order: set the remaining tracks after the starting track as queue
        setQueue(tracks.slice(startingIndex + 1));
        playTrack(tracks[startingIndex], true); // Enable autoplay
      }
      
      toast({
        title: "Playing Album",
        description: `Playing "${album.name}" from "${tracks[startingIndex].name}"${shuffle ? ' (shuffled)' : ''}`,
      });
    } catch (error) {
      console.error('Failed to play album from track:', error);
      toast({
        variant: "destructive",
        title: "Error",
        description: "Failed to play album from selected track",
      });
    } finally {
      setIsLoading(false);
    }
  }, [api, playTrack, songToTrack, toast, shuffle]);

  const skipToTrackInQueue = useCallback((index: number) => {
    if (index >= 0 && index < queue.length) {
      const targetTrack = queue[index];
      // Remove all tracks before the target track (including the target track)
      setQueue((prevQueue) => prevQueue.slice(index + 1));
      // Play the target track with autoplay enabled
      playTrack(targetTrack, true);
    }
  }, [queue, playTrack]);

  const toggleShuffle = useCallback(() => {
    setShuffle(prev => {
      const newShuffleState = !prev;
      
      // If turning shuffle ON, shuffle the current queue
      if (newShuffleState && queue.length > 0) {
        setQueue(prevQueue => {
          const shuffledQueue = [...prevQueue];
          // Fisher-Yates shuffle algorithm
          for (let i = shuffledQueue.length - 1; i > 0; i--) {
            const j = Math.floor(Math.random() * (i + 1));
            [shuffledQueue[i], shuffledQueue[j]] = [shuffledQueue[j], shuffledQueue[i]];
          }
          return shuffledQueue;
        });
      }
      
      return newShuffleState;
    });
  }, [queue.length]);

  const shuffleAllAlbums = useCallback(async () => {
    if (!api) {
      toast({
        variant: "destructive",
        title: "Configuration Required",
        description: "Please configure Navidrome connection in settings",
      });
      return;
    }

    setIsLoading(true);
    try {
      const albums = await api.getAlbums('alphabeticalByName', 500, 0);
      let allTracks: Track[] = [];
      
      // Concatenate all tracks from each album into a single array
      for (const album of albums) {
        const { songs } = await api.getAlbum(album.id);
        const tracks = songs.map(songToTrack);
        allTracks = allTracks.concat(tracks);
      }
      
      // Shuffle the combined tracks array
      allTracks.sort(() => Math.random() - 0.5);
      
      // Set the shuffled tracks as the new queue
      setQueue(allTracks);
      
      toast({
        title: "Shuffle All Albums",
        description: `Shuffled ${allTracks.length} tracks from all albums`,
      });
    } catch (error) {
      console.error('Failed to shuffle all albums:', error);
      toast({
        variant: "destructive",
        title: "Error",
        description: "Failed to shuffle all albums",
      });
    } finally {
      setIsLoading(false);
    }
  }, [api, songToTrack, toast]);

  const playArtist = useCallback(async (artistId: string) => {
    if (!api) {
      toast({
        variant: "destructive",
        title: "Configuration Required",
        description: "Please configure Navidrome connection in settings",
      });
      return;
    }

    setIsLoading(true);
    try {
      const { artist, albums } = await api.getArtist(artistId);
      let allTracks: Track[] = [];
      
      // Collect all tracks from all albums
      for (const album of albums) {
        const { songs } = await api.getAlbum(album.id);
        const tracks = songs.map(songToTrack);
        allTracks = allTracks.concat(tracks);
      }
      
      if (allTracks.length > 0) {
        if (shuffle) {
          // If shuffle is enabled, shuffle all tracks
          const shuffledTracks = [...allTracks];
          // Fisher-Yates shuffle algorithm
          for (let i = shuffledTracks.length - 1; i > 0; i--) {
            const j = Math.floor(Math.random() * (i + 1));
            [shuffledTracks[i], shuffledTracks[j]] = [shuffledTracks[j], shuffledTracks[i]];
          }
          
          // Play the first shuffled track and set the rest as queue
          playTrack(shuffledTracks[0], true); // Enable autoplay
          setQueue(shuffledTracks.slice(1));
        } else {
          // Normal order: play first track and set the rest as queue
          playTrack(allTracks[0], true); // Enable autoplay
          setQueue(allTracks.slice(1));
        }
      }
      
      toast({
        title: "Playing Artist",
        description: `Now playing all albums by "${artist.name}"${shuffle ? ' (shuffled)' : ''}`,
      });
    } catch (error) {
      console.error('Failed to play artist:', error);
      toast({
        variant: "destructive",
        title: "Error",
        description: "Failed to play artist albums",
      });
    } finally {
      setIsLoading(false);
    }
  }, [api, songToTrack, toast, shuffle, playTrack]);

  const clearHistory = useCallback(() => {
    setPlayedTracks([]);
    localStorage.removeItem('navidrome-playedTracks');
  }, []);

  // Persist played tracks to localStorage
  useEffect(() => {
    localStorage.setItem('navidrome-playedTracks', JSON.stringify(playedTracks));
  }, [playedTracks]);

  // Load played tracks from localStorage on mount
  useEffect(() => {
    const savedPlayedTracks = localStorage.getItem('navidrome-playedTracks');
    if (savedPlayedTracks) {
      try {
        setPlayedTracks(JSON.parse(savedPlayedTracks));
      } catch (error) {
        console.error('Failed to parse saved played tracks:', error);
      }
    }
  }, []);
  // Track playback state
  const [isPlaying, setIsPlaying] = useState(false);

  // Shared playback control function
  const togglePlayPause = useCallback(async () => {
    const audioElement = audioRef.current;
    if (!audioElement || !currentTrack) return;

    try {
      if (isPlaying) {
        audioElement.pause();
        setIsPlaying(false);
      } else {
        await audioElement.play();
        setIsPlaying(true);
      }
    } catch (error) {
      console.error('Failed to toggle playback:', error);
      toast({
        variant: "destructive",
        title: "Playback Error",
        description: "Failed to control playback. Please try again.",
      });
    }
  }, [currentTrack, isPlaying, toast]);

  const contextValue = useMemo(() => ({
    currentTrack, 
    playTrack, 
    queue, 
    addToQueue, 
    insertAtBeginningOfQueue,
    playNextTrack, 
    clearQueue, 
    addAlbumToQueue, 
    removeTrackFromQueue, 
    reorderQueue,
    addArtistToQueue, 
    playPreviousTrack,
    isLoading,
    playAlbum,
    playAlbumFromTrack,
    skipToTrackInQueue,
    shuffle,
    toggleShuffle,
    shuffleAllAlbums,
    playArtist,
    playedTracks,
    clearHistory,
    // Audio settings
    audioSettings,
    updateAudioSettings,
    equalizerPreset,
    setEqualizerPreset,
    audioEffects,
    // Playback state
    isPlaying,
    togglePlayPause,
    toggleCurrentTrackStar: async () => {
      if (!currentTrack || !api) {
        toast({
          variant: "destructive",
          title: "Error",
          description: "No track currently playing or API not configured",
        });
        return;
      }
      
      const newStarredStatus = !currentTrack.starred;
      
      try {
        if (newStarredStatus) {
          await api.star(currentTrack.id, 'song');
        } else {
          await api.unstar(currentTrack.id, 'song');
        }
        
        // Update the current track state
        setCurrentTrack((prev) => prev ? { ...prev, starred: newStarredStatus } : null);
        
       
      } catch (error) {
        console.error('Failed to update track starred status:', error);
        toast({
          variant: "destructive",
          title: "Error",
          description: "Failed to update track favorite status",
        });
      }
    },
    updateTrackStarred: async (trackId: string, starred: boolean) => {
      if (!api) {
        toast({
          variant: "destructive",
          title: "Configuration Required",
          description: "Please configure Navidrome connection in settings",
        });
        return;
      }
  
      try {
        if (starred) {
          await api.star(trackId, 'song');
        } else {
          await api.unstar(trackId, 'song');
        }
        
        // Update the current track state if it matches the updated track
        if (currentTrack?.id === trackId) {
          setCurrentTrack((prev) => prev ? { ...prev, starred } : null);
        }
        
        // Also update queue if the track is in there
        setQueue((prev) => prev.map(track => 
          track.id === trackId ? { ...track, starred } : track
        ));
        
      } catch (error) {
        console.error('Failed to update track starred status:', error);
        toast({
          variant: "destructive",
          title: "Error",
          description: "Failed to update track favorite status",
        });
      }
    }
  }), [
    currentTrack, 
    queue, 
    isLoading, 
    playTrack, 
    addToQueue, 
    insertAtBeginningOfQueue,
    playNextTrack, 
    clearQueue, 
    addAlbumToQueue, 
    removeTrackFromQueue, 
    reorderQueue,
    addArtistToQueue, 
    playPreviousTrack,
    playAlbum,
    playAlbumFromTrack,
    skipToTrackInQueue,
    shuffle,
    toggleShuffle,
    shuffleAllAlbums,
    playArtist,
    playedTracks,
    clearHistory,
    api,
    toast,
    audioEffects,
    audioSettings,
    equalizerPreset,
    updateAudioSettings,
    setEqualizerPreset,
    isPlaying,
    togglePlayPause
  ]);

  return (
    <AudioPlayerContext.Provider value={contextValue}>
      {children}
    </AudioPlayerContext.Provider>
  );
};

export const useAudioPlayer = () => {
  const context = useContext(AudioPlayerContext);
  if (!context) {
    throw new Error('useAudioPlayer must be used within an AudioPlayerProvider');
  }
  return context;
};