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

interface MusicFile {
  _id: string;
  title?: string;
  artist?: string;
  album?: string;
  duration?: number;
  originalName: string;
}

interface MusicPlayerProps {
  musicFile?: MusicFile;
  onPlay?: () => void;
  onPause?: () => void;
  onEnded?: () => void;
}

export const MusicPlayer: React.FC<MusicPlayerProps> = ({
  musicFile,
  onPlay,
  onPause,
  onEnded,
}) => {
  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 music file changes
  useEffect(() => {
    if (musicFile) {
      loadStreamingUrl();
    } else {
      setStreamingUrl(null);
      setIsPlaying(false);
    }
  }, [musicFile]);

  const loadStreamingUrl = async () => {
    if (!musicFile) return;
    
    setIsLoading(true);
    try {
      const response = await fetch(`/api/music/${musicFile._id}/stream`);
      if (response.ok) {
        const data = await response.json();
        setStreamingUrl(data.streamingUrl);
      } 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);
    }
  };

  // Audio event handlers
  const handlePlay = () => {
    if (audioRef.current) {
      audioRef.current.play();
      setIsPlaying(true);
      onPlay?.();
    }
  };

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

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

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

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

  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, currentTime - 10);
    }
  };

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

  if (!musicFile) {
    return (
      <Box p={4} textAlign="center" color="gray.500">
        <Text>No music file selected</Text>
      </Box>
    );
  }

  return (
    <VStack spacing={4} align="stretch" w="full" p={4} bg="gray.800" borderRadius="lg" borderColor="gray.700" borderWidth="1px">
      {/* 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)}
      />

      {/* Track info */}
      <VStack spacing={1} align="center">
        <Text fontWeight="bold" fontSize="lg" noOfLines={1} color="white">
          {musicFile.title || musicFile.originalName}
        </Text>
        {musicFile.artist && (
          <Text fontSize="sm" color="gray.400" noOfLines={1}>
            {musicFile.artist}
          </Text>
        )}
        {musicFile.album && (
          <Text fontSize="xs" color="gray.500" noOfLines={1}>
            {musicFile.album}
          </Text>
        )}
      </VStack>

      {/* Progress bar */}
      <VStack spacing={2}>
        <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>

      {/* Controls */}
      <HStack justify="center" spacing={4}>
        <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="lg"
          colorScheme="blue"
          isLoading={isLoading}
          isDisabled={!streamingUrl}
          _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>

      {/* Volume control */}
      <HStack spacing={2} justify="center">
        <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="100px"
          colorScheme="blue"
        >
          <SliderTrack bg="gray.700">
            <SliderFilledTrack bg="blue.400" />
          </SliderTrack>
          <SliderThumb bg="blue.400" />
        </Slider>
      </HStack>

      {/* Loading indicator */}
      {isLoading && (
        <Text fontSize="sm" color="gray.500" textAlign="center">
          Loading audio...
        </Text>
      )}

      {/* Error state */}
      {!streamingUrl && (
        <Text fontSize="sm" color="red.400" textAlign="center">
          Unable to load audio file
        </Text>
      )}
    </VStack>
  );
}; 