import { create } from 'zustand';
import TrackPlayer, { Track as RNTrack, RepeatMode as TPRepeatMode } from 'react-native-track-player';
import { Track, RepeatMode } from '../types';

interface PlayerStore {
  // State
  isPlaying: boolean;
  currentTrack: Track | null;
  queue: Track[];
  shuffle: boolean;
  repeatMode: RepeatMode;
  position: number;
  duration: number;
  isReady: boolean;

  // Actions
  setIsPlaying: (playing: boolean) => void;
  setCurrentTrack: (track: Track | null) => void;
  setQueue: (queue: Track[]) => void;
  setShuffle: (shuffle: boolean) => void;
  setRepeatMode: (mode: RepeatMode) => void;
  setPosition: (position: number) => void;
  setDuration: (duration: number) => void;
  setIsReady: (ready: boolean) => void;

  // Player actions
  play: () => Promise<void>;
  pause: () => Promise<void>;
  playTrack: (track: Track) => Promise<void>;
  playQueue: (tracks: Track[], startIndex?: number) => Promise<void>;
  skipToNext: () => Promise<void>;
  skipToPrevious: () => Promise<void>;
  seekTo: (position: number) => Promise<void>;
  addToQueue: (track: Track) => Promise<void>;
  removeFromQueue: (index: number) => Promise<void>;
  clearQueue: () => Promise<void>;
  toggleShuffle: () => void;
  cycleRepeatMode: () => void;
}

// Convert our Track to react-native-track-player format
const toRNTrack = (track: Track): RNTrack => ({
  id: track.id,
  url: track.url,
  title: track.title,
  artist: track.artist || 'Unknown Artist',
  album: track.album,
  artwork: track.artwork,
  duration: track.duration,
});

// Convert repeat mode to track player format
const toTPRepeatMode = (mode: RepeatMode): TPRepeatMode => {
  switch (mode) {
    case 'off':
      return TPRepeatMode.Off;
    case 'track':
      return TPRepeatMode.Track;
    case 'queue':
      return TPRepeatMode.Queue;
  }
};

export const usePlayerStore = create<PlayerStore>((set, get) => ({
  // Initial state
  isPlaying: false,
  currentTrack: null,
  queue: [],
  shuffle: false,
  repeatMode: 'off',
  position: 0,
  duration: 0,
  isReady: false,

  // State setters
  setIsPlaying: (isPlaying) => set({ isPlaying }),
  setCurrentTrack: (currentTrack) => set({ currentTrack }),
  setQueue: (queue) => set({ queue }),
  setShuffle: (shuffle) => set({ shuffle }),
  setRepeatMode: (repeatMode) => set({ repeatMode }),
  setPosition: (position) => set({ position }),
  setDuration: (duration) => set({ duration }),
  setIsReady: (isReady) => set({ isReady }),

  // Player actions
  play: async () => {
    await TrackPlayer.play();
    set({ isPlaying: true });
  },

  pause: async () => {
    await TrackPlayer.pause();
    set({ isPlaying: false });
  },

  playTrack: async (track) => {
    await TrackPlayer.reset();
    await TrackPlayer.add(toRNTrack(track));
    await TrackPlayer.play();
    set({ currentTrack: track, queue: [track], isPlaying: true });
  },

  playQueue: async (tracks, startIndex = 0) => {
    await TrackPlayer.reset();
    await TrackPlayer.add(tracks.map(toRNTrack));
    if (startIndex > 0) {
      await TrackPlayer.skip(startIndex);
    }
    await TrackPlayer.play();
    set({ queue: tracks, currentTrack: tracks[startIndex], isPlaying: true });
  },

  skipToNext: async () => {
    try {
      await TrackPlayer.skipToNext();
    } catch (error) {
      // End of queue - handle based on repeat mode
      const { repeatMode, queue } = get();
      if (repeatMode === 'queue' && queue.length > 0) {
        await TrackPlayer.skip(0);
        await TrackPlayer.play();
      }
    }
  },

  skipToPrevious: async () => {
    const { position } = get();
    // If more than 3 seconds in, restart current track
    if (position > 3) {
      await TrackPlayer.seekTo(0);
    } else {
      try {
        await TrackPlayer.skipToPrevious();
      } catch (error) {
        // Beginning of queue
        await TrackPlayer.seekTo(0);
      }
    }
  },

  seekTo: async (position) => {
    await TrackPlayer.seekTo(position);
    set({ position });
  },

  addToQueue: async (track) => {
    await TrackPlayer.add(toRNTrack(track));
    set((state) => ({ queue: [...state.queue, track] }));
  },

  removeFromQueue: async (index) => {
    await TrackPlayer.remove(index);
    set((state) => ({
      queue: state.queue.filter((_, i) => i !== index),
    }));
  },

  clearQueue: async () => {
    await TrackPlayer.reset();
    set({ queue: [], currentTrack: null, isPlaying: false });
  },

  toggleShuffle: () => {
    set((state) => ({ shuffle: !state.shuffle }));
    // Note: shuffle logic is handled during queue playback
  },

  cycleRepeatMode: () => {
    set((state) => {
      const modes: RepeatMode[] = ['off', 'queue', 'track'];
      const currentIndex = modes.indexOf(state.repeatMode);
      const nextMode = modes[(currentIndex + 1) % modes.length];
      TrackPlayer.setRepeatMode(toTPRepeatMode(nextMode));
      return { repeatMode: nextMode };
    });
  },
}));
