import React, { useCallback, useState } from 'react';
import { useDropzone } from 'react-dropzone';
import {
  Box,
  Button,
  VStack,
  HStack,
  Text,
  Progress,
  Alert,
  AlertIcon,
  AlertTitle,
  AlertDescription,
  Icon,
  Input,
  Checkbox,
  Select,
  useToast,
} from '@chakra-ui/react';
import { FiUpload, FiMusic, FiCheck, FiX } from 'react-icons/fi';

interface UploadProgress {
  fileName: string;
  progress: number;
  status: 'uploading' | 'success' | 'error';
  error?: string;
}

interface MusicUploadProps {
  onUploadComplete?: (files: any[]) => void;
}

export const MusicUpload: React.FC<MusicUploadProps> = ({ onUploadComplete }) => {
  const [uploadProgress, setUploadProgress] = useState<UploadProgress[]>([]);
  const [isUploading, setIsUploading] = useState(false);
  const [targetFolder, setTargetFolder] = useState<string>('uploads');
  const [folders, setFolders] = useState<string[]>([]);
  const [markForScan, setMarkForScan] = useState<boolean>(true);
  const toast = useToast();

  const onDrop = useCallback(async (acceptedFiles: File[]) => {
    setIsUploading(true);
    const newProgress: UploadProgress[] = acceptedFiles.map(file => ({
      fileName: file.name,
      progress: 0,
      status: 'uploading',
    }));
    
    setUploadProgress(newProgress);

    const results = [];
    
      for (let i = 0; i < acceptedFiles.length; i++) {
      const file = acceptedFiles[i];
      
      try {
        const formData = new FormData();
        formData.append('file', file);
          formData.append('targetFolder', targetFolder);
          formData.append('markForScan', String(markForScan));

        const response = await fetch('/api/music/upload', {
          method: 'POST',
          body: formData,
        });

        if (response.ok) {
          const result = await response.json();
          results.push(result.musicFile);
          
          // Update progress
          setUploadProgress(prev => 
            prev.map((item, index) => 
              index === i 
                ? { ...item, progress: 100, status: 'success' as const }
                : item
            )
          );
        } else {
          const error = await response.json();
          throw new Error(error.error || 'Upload failed');
        }
      } catch (error) {
        console.error(`Error uploading ${file.name}:`, error);
        
        setUploadProgress(prev => 
          prev.map((item, index) => 
            index === i 
              ? { 
                  ...item, 
                  progress: 0, 
                  status: 'error' as const, 
                  error: error instanceof Error ? error.message : 'Upload failed'
                }
              : item
          )
        );
      }
    }

    setIsUploading(false);
    
    if (results.length > 0) {
      toast({
        title: 'Upload Complete',
        description: `Successfully uploaded ${results.length} file(s)`,
        status: 'success',
        duration: 5000,
        isClosable: true,
      });
      
      onUploadComplete?.(results);
    }
  }, [onUploadComplete, toast]);

  const { getRootProps, getInputProps, isDragActive } = useDropzone({
    onDrop,
    accept: {
      'audio/*': ['.mp3', '.wav', '.flac', '.aac', '.m4a', '.ogg', '.wma', '.opus'],
    },
    maxSize: 100 * 1024 * 1024, // 100MB
    multiple: true,
  });

  // Load folders for dropdown
  React.useEffect(() => {
    (async () => {
      try {
        const res = await fetch('/api/music/folders');
        if (!res.ok) throw new Error('Failed to load folders');
        const data = await res.json();
        const items = Array.isArray(data.folders) ? data.folders : [];
        setFolders(items);
        if (items.length > 0 && targetFolder === 'uploads') {
          // default target: root (empty) if available, else first item
          const defaultChoice = items.find((f: string) => f === '') || items[0];
          setTargetFolder(defaultChoice.replace(/^\/+/, ''));
        }
      } catch (e) {
        // ignore, keep text input fallback
      }
    })();
  }, []);

  const resetUploads = () => {
    setUploadProgress([]);
  };

  return (
    <VStack spacing={4} align="stretch" w="full">
      <HStack>
        <Box flex={1}>
          <Text color="gray.300" fontSize="sm" mb={1}>Target S3 folder</Text>
          {folders.length > 0 ? (
            <Select value={targetFolder} onChange={(e) => setTargetFolder(e.target.value)} bg="gray.800" borderColor="gray.700">
              {folders.map((f) => (
                <option key={f || 'ROOT'} value={f}>{f || '(root)'}</option>
              ))}
            </Select>
          ) : (
            <Input value={targetFolder} onChange={(e) => setTargetFolder(e.target.value)} placeholder="e.g. Prep/ToScan" bg="gray.800" borderColor="gray.700" />
          )}
        </Box>
        <Checkbox isChecked={markForScan} onChange={(e) => setMarkForScan(e.target.checked)} colorScheme="blue" alignSelf="end">
          Add to "To Be Scanned"
        </Checkbox>
      </HStack>
      <Box
        {...getRootProps()}
        border="2px dashed"
        borderColor={isDragActive ? 'blue.400' : 'gray.600'}
        borderRadius="lg"
        p={8}
        textAlign="center"
        cursor="pointer"
        transition="all 0.2s"
        _hover={{
          borderColor: 'blue.400',
          bg: 'blue.900',
        }}
        bg={isDragActive ? 'blue.900' : 'gray.800'}
      >
        <input {...getInputProps()} />
        <VStack spacing={3}>
          <Icon as={isDragActive ? FiUpload : FiMusic} w={8} h={8} color="blue.400" />
          <Text fontSize="lg" fontWeight="medium" color="white">
            {isDragActive
              ? 'Drop the music files here...'
              : 'Drag & drop music files here, or click to select'}
          </Text>
          <Text fontSize="sm" color="gray.400">
            Supports MP3, WAV, FLAC, AAC, OGG, WMA, Opus (max 100MB per file)
          </Text>
        </VStack>
      </Box>

      {uploadProgress.length > 0 && (
        <VStack spacing={3} align="stretch">
          <HStack justify="space-between">
            <Text fontWeight="medium" color="white">Upload Progress</Text>
            <Button size="sm" variant="ghost" onClick={resetUploads} color="gray.400" _hover={{ bg: "gray.700" }}>
              Clear
            </Button>
          </HStack>
          
          {uploadProgress.map((item, index) => (
            <Box key={index} p={3} border="1px" borderColor="gray.700" borderRadius="md" bg="gray.800">
              <HStack justify="space-between" mb={2}>
                <Text fontSize="sm" fontWeight="medium" noOfLines={1} color="white">
                  {item.fileName}
                </Text>
                <Icon
                  as={item.status === 'success' ? FiCheck : item.status === 'error' ? FiX : undefined}
                  color={item.status === 'success' ? 'green.400' : item.status === 'error' ? 'red.400' : 'gray.400'}
                />
              </HStack>
              
              {item.status === 'error' ? (
                <Alert status="error" size="sm" bg="red.900" borderColor="red.700" color="red.100">
                  <AlertIcon color="red.300" />
                  <Box>
                    <AlertTitle color="red.100">Upload failed</AlertTitle>
                    <AlertDescription color="red.200">{item.error}</AlertDescription>
                  </Box>
                </Alert>
              ) : (
                <Progress
                  value={item.progress}
                  colorScheme={item.status === 'success' ? 'green' : 'blue'}
                  size="sm"
                  bg="gray.700"
                />
              )}
            </Box>
          ))}
        </VStack>
      )}

      {isUploading && (
        <Alert status="info" bg="blue.900" borderColor="blue.700" color="blue.100">
          <AlertIcon color="blue.300" />
          <Box>
            <AlertTitle color="blue.100">Uploading files...</AlertTitle>
            <AlertDescription color="blue.200">
              Please wait while your music files are being uploaded and processed.
            </AlertDescription>
          </Box>
        </Alert>
      )}
    </VStack>
  );
}; 