import React, { useState, useRef, useEffect } from 'react';
import {
  Box,
  HStack,
  VStack,
  Text,
  IconButton,
  Slider,
  SliderTrack,
  SliderFilledTrack,
  SliderThumb,
  Icon,
  useToast,
} from '@chakra-ui/react';
import {
  FiPlay,
  FiPause,
  FiSkipBack,
  FiSkipForward,
  FiVolume2,
  FiVolumeX,
  FiX,
} from 'react-icons/fi';
import type { Song } from '../types/interfaces';
import { formatDuration } from '../utils/formatters';

interface PersistentMusicPlayerProps {
  currentSong: Song | null;
  onClose: () => void;
}

export const PersistentMusicPlayer: React.FC<PersistentMusicPlayerProps> = ({
  currentSong,
  onClose,
}) => {
  const [isPlaying, setIsPlaying] = useState(false);
  const [currentTime, setCurrentTime] = useState(0);
  const [duration, setDuration] = useState(0);
  const [volume, setVolume] = useState(1);
  const [isMuted, setIsMuted] = useState(false);
  const [streamingUrl, setStreamingUrl] = useState<string | null>(null);
  const [isLoading, setIsLoading] = useState(false);
  
  const audioRef = useRef<HTMLAudioElement>(null);
  const toast = useToast();

  // Format time in MM:SS
  const formatTime = (seconds: number): string => {
    if (!seconds || isNaN(seconds)) return '00:00';
    const mins = Math.floor(seconds / 60);
    const secs = Math.floor(seconds % 60);
    return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
  };

  // Load streaming URL when current song changes
  useEffect(() => {
    if (currentSong && currentSong.s3File?.hasS3File) {
      loadStreamingUrl();
    } else {
      setStreamingUrl(null);
      setIsPlaying(false);
    }
  }, [currentSong]);

  const loadStreamingUrl = async () => {
    if (!currentSong?.s3File?.musicFileId) return;
    
    // Handle both string ID and populated object
    const musicFileId = typeof currentSong.s3File.musicFileId === 'string' 
      ? currentSong.s3File.musicFileId 
      : currentSong.s3File.musicFileId._id;
    
    if (!musicFileId) return;
    
    setIsLoading(true);
    try {
      const response = await fetch(`/api/music/${musicFileId}/stream`);
      if (response.ok) {
        const data = await response.json();
        setStreamingUrl(data.streamingUrl);
        // Auto-play when URL is loaded
        setTimeout(() => {
          if (audioRef.current) {
            audioRef.current.play().then(() => {
              setIsPlaying(true);
            }).catch(error => {
              console.error('Error auto-playing:', error);
            });
          }
        }, 100);
      } else {
        throw new Error('Failed to get streaming URL');
      }
    } catch (error) {
      console.error('Error loading streaming URL:', error);
      toast({
        title: 'Error',
        description: 'Failed to load music file',
        status: 'error',
        duration: 3000,
        isClosable: true,
      });
    } finally {
      setIsLoading(false);
    }
  };

  const handlePlay = () => {
    if (audioRef.current) {
      audioRef.current.play().then(() => {
        setIsPlaying(true);
      }).catch(error => {
        console.error('Error playing:', error);
      });
    }
  };

  const handlePause = () => {
    if (audioRef.current) {
      audioRef.current.pause();
      setIsPlaying(false);
    }
  };

  const handleTimeUpdate = () => {
    if (audioRef.current) {
      setCurrentTime(audioRef.current.currentTime);
    }
  };

  const handleLoadedMetadata = () => {
    if (audioRef.current) {
      setDuration(audioRef.current.duration);
    }
  };

  const handleEnded = () => {
    setIsPlaying(false);
    setCurrentTime(0);
  };

  const handleSeek = (value: number) => {
    if (audioRef.current) {
      audioRef.current.currentTime = value;
      setCurrentTime(value);
    }
  };

  const handleVolumeChange = (value: number) => {
    setVolume(value);
    if (audioRef.current) {
      audioRef.current.volume = value;
    }
    if (value === 0) {
      setIsMuted(true);
    } else if (isMuted) {
      setIsMuted(false);
    }
  };

  const toggleMute = () => {
    if (audioRef.current) {
      if (isMuted) {
        audioRef.current.volume = volume;
        setIsMuted(false);
      } else {
        audioRef.current.volume = 0;
        setIsMuted(true);
      }
    }
  };

  const skipBackward = () => {
    if (audioRef.current) {
      audioRef.current.currentTime = Math.max(0, audioRef.current.currentTime - 10);
    }
  };

  const skipForward = () => {
    if (audioRef.current) {
      audioRef.current.currentTime = Math.min(
        audioRef.current.duration,
        audioRef.current.currentTime + 10
      );
    }
  };

  if (!currentSong || !currentSong.s3File?.hasS3File) {
    return null;
  }

  return (
    <Box
      position="fixed"
      bottom={0}
      left={0}
      right={0}
      bg="gray.900"
      borderTop="1px"
      borderColor="gray.700"
      p={4}
      zIndex={1000}
      boxShadow="lg"
    >
      {/* Hidden audio element */}
      <audio
        ref={audioRef}
        src={streamingUrl || undefined}
        onTimeUpdate={handleTimeUpdate}
        onLoadedMetadata={handleLoadedMetadata}
        onEnded={handleEnded}
        onError={(e) => {
          console.error('Audio error:', e);
          toast({
            title: 'Playback Error',
            description: 'Failed to play audio file. The file may be corrupted or the streaming URL may have expired.',
            status: 'error',
            duration: 5000,
            isClosable: true,
          });
        }}
        onLoadStart={() => setIsLoading(true)}
        onCanPlay={() => setIsLoading(false)}
      />

      <HStack spacing={4} align="center">
        {/* Song Info */}
        <VStack align="start" spacing={1} flex={1} minW={0}>
          <Text fontWeight="bold" fontSize="md" color="white" noOfLines={1}>
            {currentSong.title}
          </Text>
          <Text fontSize="sm" color="gray.400" noOfLines={1}>
            {currentSong.artist}
          </Text>
        </VStack>

        {/* Controls */}
        <HStack spacing={2}>
          <IconButton
            aria-label="Skip backward"
            icon={<FiSkipBack />}
            onClick={skipBackward}
            size="sm"
            variant="ghost"
            color="gray.400"
            _hover={{ bg: "gray.700" }}
          />
          
          <IconButton
            aria-label={isPlaying ? 'Pause' : 'Play'}
            icon={<Icon as={isPlaying ? FiPause : FiPlay} />}
            onClick={isPlaying ? handlePause : handlePlay}
            size="md"
            colorScheme="blue"
            isLoading={isLoading}
            _hover={{ bg: "blue.700" }}
          />
          
          <IconButton
            aria-label="Skip forward"
            icon={<FiSkipForward />}
            onClick={skipForward}
            size="sm"
            variant="ghost"
            color="gray.400"
            _hover={{ bg: "gray.700" }}
          />
        </HStack>

        {/* Progress */}
        <VStack spacing={1} flex={2} minW={0}>
          <Slider
            value={currentTime}
            max={duration}
            onChange={handleSeek}
            isDisabled={isLoading}
            size="sm"
            colorScheme="blue"
          >
            <SliderTrack bg="gray.700">
              <SliderFilledTrack bg="blue.400" />
            </SliderTrack>
            <SliderThumb bg="blue.400" />
          </Slider>
          <HStack justify="space-between" w="full" fontSize="xs" color="gray.400">
            <Text>{formatTime(currentTime)}</Text>
            <Text>{formatTime(duration)}</Text>
          </HStack>
        </VStack>

        {/* Volume Control */}
        <HStack spacing={2}>
          <IconButton
            aria-label={isMuted ? 'Unmute' : 'Mute'}
            icon={<Icon as={isMuted ? FiVolumeX : FiVolume2} />}
            onClick={toggleMute}
            size="sm"
            variant="ghost"
            color="gray.400"
            _hover={{ bg: "gray.700" }}
          />
          <Slider
            value={isMuted ? 0 : volume}
            onChange={handleVolumeChange}
            min={0}
            max={1}
            step={0.1}
            size="sm"
            w="80px"
            colorScheme="blue"
          >
            <SliderTrack bg="gray.700">
              <SliderFilledTrack bg="blue.400" />
            </SliderTrack>
            <SliderThumb bg="blue.400" />
          </Slider>
        </HStack>

        {/* Close Button */}
        <IconButton
          aria-label="Close player"
          icon={<FiX />}
          onClick={onClose}
          size="sm"
          variant="ghost"
          color="gray.400"
          _hover={{ bg: "gray.700" }}
        />
      </HStack>
    </Box>
  );
}; 