"use client";

import React, {
  createContext,
  ReactNode,
  useContext,
  useRef,
  useState,
} from "react";

export interface Song {
  id: string;
  title: string;
  display_name: string;
  handle?: string;
  audio_url: string;
  image_url?: string;
  metadata?: {
    duration?: number;
    prompt?: string;
  };
}

interface AudioContextType {
  currentSong: Song | null;
  isPlaying: boolean;
  audioRef: React.RefObject<HTMLAudioElement | null>;
  playSong: (song: Song, startTime?: number) => void;
  pauseSong: () => void;
  togglePlayPause: () => void;
}

const AudioContext = createContext<AudioContextType | undefined>(undefined);

export function AudioProvider({ children }: { children: ReactNode }) {
  const [currentSong, setCurrentSong] = useState<Song | null>(null);
  const [isPlaying, setIsPlaying] = useState(false);
  const audioRef = useRef<HTMLAudioElement>(null);

  const playSong = (song: Song, startTime: number = 0) => {
    if (!audioRef.current) return;

    // If it's the same song, just toggle play/pause
    if (currentSong?.id === song.id) {
      togglePlayPause();
      return;
    }

    // Stop current audio and set new song
    audioRef.current.pause();
    audioRef.current.currentTime = 0;

    setCurrentSong(song);
    audioRef.current.src = song.audio_url;
    audioRef.current.load();

    // Set up event listener to seek to start time once metadata is loaded
    const handleLoadedMetadata = () => {
      if (audioRef.current) {
        audioRef.current.currentTime = startTime;
        audioRef.current
          .play()
          .then(() => {
            setIsPlaying(true);
          })
          .catch((error) => {
            console.error("Error playing audio:", error);
            setIsPlaying(false);
          });
      }
      audioRef.current?.removeEventListener(
        "loadedmetadata",
        handleLoadedMetadata
      );
    };

    audioRef.current.addEventListener("loadedmetadata", handleLoadedMetadata);

    // Fallback if metadata is already loaded
    if (audioRef.current.readyState >= 1) {
      handleLoadedMetadata();
    }
  };

  const pauseSong = () => {
    if (!audioRef.current) return;
    audioRef.current.pause();
    setIsPlaying(false);
  };

  const togglePlayPause = () => {
    if (!audioRef.current || !currentSong) return;

    if (isPlaying) {
      pauseSong();
    } else {
      audioRef.current
        .play()
        .then(() => {
          setIsPlaying(true);
        })
        .catch((error) => {
          console.error("Error playing audio:", error);
          setIsPlaying(false);
        });
    }
  };

  return (
    <AudioContext.Provider
      value={{
        currentSong,
        isPlaying,
        audioRef,
        playSong,
        pauseSong,
        togglePlayPause,
      }}
    >
      {children}
      <audio
        ref={audioRef}
        onEnded={() => setIsPlaying(false)}
        onPause={() => setIsPlaying(false)}
        onPlay={() => setIsPlaying(true)}
        preload="none"
      />
    </AudioContext.Provider>
  );
}

export function useAudio() {
  const context = useContext(AudioContext);
  if (context === undefined) {
    throw new Error("useAudio must be used within an AudioProvider");
  }
  return context;
}
