import { 
  Box, 
  Heading, 
  VStack, 
  Text, 
  Button, 
  OrderedList, 
  ListItem, 
  useDisclosure, 
  Modal, 
  ModalOverlay, 
  ModalContent, 
  ModalHeader, 
  ModalBody, 
  ModalFooter, 
  useToast, 
  IconButton, 
  Flex,
  Tabs,
  TabList,
  TabPanels,
  Tab,
  TabPanel,
  Icon,
  HStack,
  Badge,
  Spinner,
} from "@chakra-ui/react";
import { ChevronLeftIcon } from "@chakra-ui/icons";
import { FiDatabase, FiSettings, FiUpload, FiMusic, FiLink, FiRefreshCw, FiTrash2 } from 'react-icons/fi';
import { useNavigate } from "react-router-dom";
import { useXmlParser } from "../hooks/useXmlParser";
import { StyledFileInput } from "../components/StyledFileInput";
import { S3Configuration } from "./S3Configuration";
import { MusicUpload } from "../components/MusicUpload";
import { SongMatching } from "../components/SongMatching";
import { api } from "../services/api";
import { DuplicatesViewer } from "../components/DuplicatesViewer";
import { useState, useEffect, useMemo } from "react";

interface MusicFile {
  _id: string;
  originalName: string;
  title?: string;
  artist?: string;
  album?: string;
  duration?: number;
  size: number;
  format?: string;
  uploadedAt: string;
  songId?: any; // Reference to linked song
}

export function Configuration() {
  const { resetLibrary } = useXmlParser();
  const { isOpen, onOpen, onClose } = useDisclosure();
  const toast = useToast();
  const navigate = useNavigate();

  // Music storage state
  const [musicFiles, setMusicFiles] = useState<MusicFile[]>([]);
  const [isLoading, setIsLoading] = useState(false);
  const [isSyncing, setIsSyncing] = useState(false);
  const [hasS3Config, setHasS3Config] = useState<boolean>(false);
  const [musicLoaded, setMusicLoaded] = useState<boolean>(false);

  // Tabs: remember active tab across refreshes
  const initialTabIndex = useMemo(() => {
    const stored = localStorage.getItem('configTabIndex');
    return stored ? parseInt(stored, 10) : 0;
  }, []);
  const [tabIndex, setTabIndex] = useState<number>(initialTabIndex);

  // Tab indices (keep in sync with Tab order below)
  const TAB_INDEX = {
    LIBRARY: 0,
    UPLOAD: 1,
    MUSIC_LIBRARY: 2,
    MATCHING: 3,
    DUPLICATES: 4,
    S3_CONFIG: 5,
  } as const;

  // Fetch S3 config (small and safe to do on mount)
  useEffect(() => {
    const fetchS3Config = async () => {
      try {
        const res = await fetch('/api/config/s3');
        if (res.ok) {
          const data = await res.json();
          const cfg = data?.config || {};
          const required = ['endpoint', 'region', 'accessKeyId', 'secretAccessKey', 'bucketName'];
          const present = required.every((k) => typeof cfg[k] === 'string' && cfg[k]);
          setHasS3Config(present);
        } else {
          setHasS3Config(false);
        }
      } catch {
        setHasS3Config(false);
      }
    };
    fetchS3Config();
  }, []);

  // Lazy-load: only load music files when Music Library tab becomes active
  useEffect(() => {
    if (tabIndex === TAB_INDEX.MUSIC_LIBRARY && !musicLoaded) {
      loadMusicFiles().then(() => setMusicLoaded(true));
    }
  }, [tabIndex]);

  const loadMusicFiles = async () => {
    setIsLoading(true);
    try {
      const response = await fetch('/api/music/files');
      if (response.ok) {
        const data = await response.json();
        setMusicFiles(data.musicFiles || []);
      } else {
        throw new Error('Failed to load music files');
      }
    } catch (error) {
      console.error('Error loading music files:', error);
      toast({
        title: 'Error',
        description: 'Failed to load music files',
        status: 'error',
        duration: 3000,
        isClosable: true,
      });
    } finally {
      setIsLoading(false);
    }
  };

  const handleSyncS3 = async () => {
    setIsSyncing(true);
    try {
      const response = await fetch('/api/music/sync-s3', {
        method: 'POST',
      });

      if (response.ok) {
        const data = await response.json();
        toast({
          title: 'S3 Sync Complete',
          description: `Found ${data.results.total} files, synced ${data.results.newFiles} new files`,
          status: 'success',
          duration: 5000,
          isClosable: true,
        });
        
        // Reload music files to show the new ones if user is on Music Library tab
        if (tabIndex === TAB_INDEX.MUSIC_LIBRARY) {
          await loadMusicFiles();
        } else {
          // Mark as not loaded so that when user opens the tab, it fetches fresh
          setMusicLoaded(false);
        }
      } else {
        throw new Error('Failed to sync S3');
      }
    } catch (error) {
      console.error('Error syncing S3:', error);
      toast({
        title: 'Error',
        description: 'Failed to sync S3 files',
        status: 'error',
        duration: 3000,
        isClosable: true,
      });
    } finally {
      setIsSyncing(false);
    }
  };

  const handleUploadComplete = (files: MusicFile[]) => {
    setMusicFiles(prev => [...files, ...prev]);
    toast({
      title: 'Upload Complete',
      description: `${files.length} file${files.length !== 1 ? 's' : ''} uploaded successfully`,
      status: 'success',
      duration: 3000,
      isClosable: true,
    });
  };

  const handleDeleteFile = async (fileId: string) => {
    try {
      const response = await fetch(`/api/music/${fileId}`, {
        method: 'DELETE',
      });

      if (response.ok) {
        setMusicFiles(prev => prev.filter(file => file._id !== fileId));
        toast({
          title: 'File Deleted',
          description: 'Music file deleted successfully',
          status: 'success',
          duration: 3000,
          isClosable: true,
        });
      } else {
        throw new Error('Failed to delete file');
      }
    } catch (error) {
      console.error('Error deleting file:', error);
      toast({
        title: 'Error',
        description: 'Failed to delete music file',
        status: 'error',
        duration: 3000,
        isClosable: true,
      });
    }
  };

  const formatFileSize = (bytes: number): string => {
    const sizes = ['Bytes', 'KB', 'MB', 'GB'];
    if (bytes === 0) return '0 Bytes';
    
    const i = Math.floor(Math.log(bytes) / Math.log(1024));
    return Math.round(bytes / Math.pow(1024, i) * 100) / 100 + ' ' + sizes[i];
  };

  const formatDuration = (seconds: number): string => {
    if (!seconds || isNaN(seconds)) return '00:00';
    
    const minutes = Math.floor(seconds / 60);
    const remainingSeconds = Math.floor(seconds % 60);
    
    return `${minutes.toString().padStart(2, '0')}:${remainingSeconds.toString().padStart(2, '0')}`;
  };


  const handleResetDatabase = async () => {
    try {
      await api.resetDatabase();
      await resetLibrary();
      onClose();
      toast({
        title: "Database reset successful",
        description: "Your library has been cleared.",
        status: "success",
        duration: 5000,
        isClosable: true,
      });
      // Navigate to homepage to show welcome modal and start fresh
      navigate('/');
    } catch (error) {
      toast({
        title: "Failed to reset database",
        description: "An error occurred while resetting the database.",
        status: "error",
        duration: 5000,
        isClosable: true,
      });
    }
  };

  return (
    <Box 
      h="100%" 
      bg="gray.900" 
      p={8}
      overflowY="auto"
      sx={{
        '&::-webkit-scrollbar': {
          width: '8px',
          borderRadius: '8px',
          backgroundColor: 'gray.900',
        },
        '&::-webkit-scrollbar-thumb': {
          backgroundColor: 'gray.700',
          borderRadius: '8px',
        },
      }}
    >
      <VStack spacing={8} align="stretch" maxW="4xl" mx="auto">
        <Flex align="center" gap={4}>
          <IconButton
            icon={<ChevronLeftIcon boxSize={6} />}
            aria-label="Go back"
            variant="ghost"
            onClick={() => navigate('/')}
            color="gray.300"
            _hover={{ color: "white", bg: "whiteAlpha.200" }}
          />
          <Heading size="lg">Configuration</Heading>
        </Flex>
        
        <Tabs
          variant="enclosed"
          colorScheme="blue"
          isLazy
          index={tabIndex}
          onChange={(index) => {
            setTabIndex(index);
            localStorage.setItem('configTabIndex', String(index));
          }}
        >
          <TabList bg="gray.800" borderColor="gray.700">
            <Tab color="gray.300" _selected={{ bg: "gray.700", color: "white", borderColor: "gray.600" }}>
              <HStack spacing={2}>
                <Icon as={FiDatabase} />
                <Text>Library Management</Text>
              </HStack>
            </Tab>
            <Tab color="gray.300" _selected={{ bg: "gray.700", color: "white", borderColor: "gray.600" }}>
              <HStack spacing={2}>
                <Icon as={FiUpload} />
                <Text>Upload Music</Text>
              </HStack>
            </Tab>
            <Tab color="gray.300" _selected={{ bg: "gray.700", color: "white", borderColor: "gray.600" }}>
              <HStack spacing={2}>
                <Icon as={FiMusic} />
                <Text>Music Library</Text>
              </HStack>
            </Tab>
            <Tab color="gray.300" _selected={{ bg: "gray.700", color: "white", borderColor: "gray.600" }}>
              <HStack spacing={2}>
                <Icon as={FiLink} />
                <Text>Song Matching</Text>
              </HStack>
            </Tab>
            <Tab color="gray.300" _selected={{ bg: "gray.700", color: "white", borderColor: "gray.600" }}>
              <HStack spacing={2}>
                <Icon as={FiDatabase} />
                <Text>Duplicates</Text>
              </HStack>
            </Tab>
            <Tab color="gray.300" _selected={{ bg: "gray.700", color: "white", borderColor: "gray.600" }}>
              <HStack spacing={2}>
                <Icon as={FiSettings} />
                <Text>S3 Configuration</Text>
              </HStack>
            </Tab>
          </TabList>

          <TabPanels>
            {/* Library Management Tab */}
            <TabPanel bg="gray.800" p={6} borderRadius="lg" borderWidth="1px" borderColor="gray.700">
              <VStack spacing={6} align="stretch">
                <Box>
                  <Text color="gray.400" mb={4}>
                    To get started with Rekordbox Reader, you'll need to export your library from Rekordbox and import it here.
                  </Text>
                  
                  <OrderedList spacing={3} color="gray.400" mb={6}>
                    <ListItem>
                      Open Rekordbox and go to <Text as="span" color="gray.300" fontWeight="medium">File → Export Collection in xml format</Text>
                    </ListItem>
                    <ListItem>
                      Choose a location to save your XML file
                    </ListItem>
                    <ListItem>
                      Click the button below to import your Rekordbox XML file
                    </ListItem>
                  </OrderedList>
                </Box>

                <Box>
                  <Text fontWeight="medium" mb={2}>Import Library</Text>
                  <StyledFileInput />
                </Box>

                <Box borderTopWidth="1px" borderColor="gray.700" pt={6} mt={4}>
                  <Text fontWeight="medium" mb={2}>Reset Database</Text>
                  <Text color="gray.400" mb={4}>
                    Clear all songs and playlists from the database. This action cannot be undone.
                  </Text>
                  <Button 
                    onClick={onOpen}
                    width="full"
                    colorScheme="red"
                    variant="outline"
                  >
                    Reset Database
                  </Button>
                </Box>
              </VStack>
            </TabPanel>

            {/* Upload Music Tab */}
            <TabPanel bg="gray.800" p={6} borderRadius="lg" borderWidth="1px" borderColor="gray.700">
              <VStack spacing={6} align="stretch">
                <Box>
                  <Heading size="md" mb={4} color="white">
                    Upload Music Files
                  </Heading>
                  <Text color="gray.400" mb={4}>
                    Drag and drop your music files here or click to select. Files will be uploaded to S3 storage
                    and metadata will be automatically extracted.
                  </Text>
                </Box>
                <MusicUpload onUploadComplete={handleUploadComplete} />
              </VStack>
            </TabPanel>

            {/* Music Library Tab */}
            <TabPanel bg="gray.800" p={6} borderRadius="lg" borderWidth="1px" borderColor="gray.700">
              <VStack spacing={4} align="stretch">
                <HStack justify="space-between">
                  <Heading size="md" color="white">Music Library</Heading>
                  <HStack spacing={2}>
                    <Text color="gray.400">
                      {musicFiles.length} file{musicFiles.length !== 1 ? 's' : ''}
                    </Text>
                    <Button
                      leftIcon={isSyncing ? <Spinner size="sm" /> : <FiRefreshCw />}
                      size="sm"
                      variant="outline"
                      colorScheme="blue"
                      onClick={handleSyncS3}
                      isLoading={isSyncing}
                      isDisabled={!hasS3Config || isSyncing}
                      loadingText="Syncing..."
                      _hover={{ bg: "blue.900", borderColor: "blue.400" }}
                    >
                      Sync S3
                    </Button>
                  </HStack>
                </HStack>

                {tabIndex === TAB_INDEX.MUSIC_LIBRARY && isLoading ? (
                  <Text textAlign="center" color="gray.500">
                    Loading music files...
                  </Text>
                ) : tabIndex === TAB_INDEX.MUSIC_LIBRARY && musicFiles.length === 0 ? (
                  <VStack spacing={4} textAlign="center" color="gray.500">
                    <Text>No music files found in the database.</Text>
                    <Text fontSize="sm">
                      Try uploading files in the Upload tab, or click "Sync S3" to find files already in your S3 bucket.
                    </Text>
                    <Button
                      leftIcon={<FiRefreshCw />}
                      onClick={handleSyncS3}
                      isLoading={isSyncing}
                      isDisabled={!hasS3Config || isSyncing}
                      loadingText="Syncing..."
                      colorScheme="blue"
                      _hover={{ bg: "blue.700" }}
                    >
                      Sync S3 Bucket
                    </Button>
                    {!hasS3Config && (
                      <Text fontSize="xs" color="orange.300">
                        Configure your S3 connection in the S3 Configuration tab first.
                      </Text>
                    )}
                  </VStack>
                ) : (
                  <VStack spacing={2} align="stretch">
                    {musicFiles.map((file) => (
                      <Box
                        key={file._id}
                        p={4}
                        border="1px"
                        borderColor="gray.700"
                        borderRadius="md"
                        bg="gray.800"
                        _hover={{ bg: "gray.750" }}
                      >
                        <HStack justify="space-between" align="start">
                          <VStack align="start" spacing={1} flex={1}>
                            <HStack spacing={2} align="center">
                              <Text fontWeight="bold" fontSize="md" color="white" noOfLines={1}>
                                {file.title || file.originalName}
                              </Text>
                              <Badge colorScheme="blue" variant="subtle" bg="blue.900" color="blue.200">
                                {file.format?.toUpperCase() || 'AUDIO'}
                              </Badge>
                              {file.songId && (
                                <Badge colorScheme="green" size="sm" bg="green.900" color="green.200">
                                  Linked to Rekordbox
                                </Badge>
                              )}
                            </HStack>
                            {file.artist && (
                              <Text fontSize="sm" color="gray.400" noOfLines={1}>
                                {file.artist}
                              </Text>
                            )}
                            {file.album && (
                              <Text fontSize="sm" color="gray.500" noOfLines={1}>
                                {file.album}
                              </Text>
                            )}
                            <HStack spacing={4} fontSize="xs" color="gray.500">
                              <Text>{formatDuration(file.duration || 0)}</Text>
                              <Text>{formatFileSize(file.size)}</Text>
                              <Text>{file.format?.toUpperCase()}</Text>
                            </HStack>
                          </VStack>
                          <HStack spacing={2}>
                            <IconButton
                              aria-label="Delete file"
                              icon={<FiTrash2 />}
                              size="sm"
                              variant="ghost"
                              colorScheme="red"
                              onClick={() => handleDeleteFile(file._id)}
                              _hover={{ bg: "red.900" }}
                            />
                          </HStack>
                        </HStack>
                      </Box>
                    ))}
                  </VStack>
                )}
              </VStack>
            </TabPanel>

            {/* Song Matching Tab */}
            <TabPanel bg="gray.800" p={6} borderRadius="lg" borderWidth="1px" borderColor="gray.700">
              <SongMatching />
            </TabPanel>

            {/* Duplicates Tab */}
            <TabPanel bg="gray.800" p={6} borderRadius="lg" borderWidth="1px" borderColor="gray.700">
              <DuplicatesViewer />
            </TabPanel>

            {/* S3 Configuration Tab */}
            <TabPanel bg="gray.800" p={0}>
              <Box p={6}>
                <S3Configuration />
              </Box>
            </TabPanel>
          </TabPanels>
        </Tabs>
      </VStack>

      {/* Reset Database Confirmation Modal */}
      <Modal isOpen={isOpen} onClose={onClose} isCentered>
        <ModalOverlay />
        <ModalContent bg="gray.800">
          <ModalHeader color="white">Confirm Database Reset</ModalHeader>
          <ModalBody>
            <VStack spacing={4} align="stretch">
              <Text color="gray.300">
                Are you sure you want to reset the database? This will:
              </Text>
              <OrderedList spacing={2} color="gray.400" pl={4}>
                <ListItem>Delete all imported songs</ListItem>
                <ListItem>Remove all playlists</ListItem>
                <ListItem>Clear all custom configurations</ListItem>
              </OrderedList>
              <Text color="red.300" fontWeight="medium">
                This action cannot be undone.
              </Text>
            </VStack>
          </ModalBody>
          <ModalFooter gap={3}>
            <Button 
              variant="outline" 
              onClick={onClose}
              color="gray.300"
              _hover={{
                bg: "whiteAlpha.200",
                color: "white"
              }}
            >
              Cancel
            </Button>
            <Button colorScheme="red" onClick={handleResetDatabase}>
              Reset Database
            </Button>
          </ModalFooter>
        </ModalContent>
      </Modal>
    </Box>
  );
} 