import React, { useState, useEffect } from 'react';
import {
  Box,
  VStack,
  HStack,
  Text,
  Heading,
  Button,
  Card,
  CardBody,
  CardHeader,
  Badge,
  Progress,
  useToast,
  Modal,
  ModalOverlay,
  ModalContent,
  ModalHeader,
  ModalBody,
  ModalFooter,
  ModalCloseButton,
  useDisclosure,
  SimpleGrid,
  Stat,
  StatLabel,
  StatNumber,
  StatHelpText,
  IconButton,
  Tooltip,
  Spinner,
} from '@chakra-ui/react';
import { FiPlay, FiLink, FiSearch, FiZap } from 'react-icons/fi';

interface MatchResult {
  song: any;
  musicFile: any;
  confidence: number;
  matchType: 'exact' | 'fuzzy' | 'partial' | 'none';
  matchReason: string;
}

interface MatchingStats {
  totalSongs: number;
  totalMusicFiles: number;
  matchedMusicFiles: number;
  unmatchedMusicFiles: number;
  songsWithoutMusicFiles: number;
  songsWithMusicFiles: number;
  matchRate: string;
}

export const SongMatching: React.FC = () => {
  const [stats, setStats] = useState<MatchingStats | null>(null);
  const [unmatchedMusicFiles, setUnmatchedMusicFiles] = useState<any[]>([]);
  // Removed matched and songs-with-files lists to reduce load
  const [isLoading, setIsLoading] = useState(false);
  const [autoLinking, setAutoLinking] = useState(false);
  const [selectedMusicFile, setSelectedMusicFile] = useState<any>(null);
  const [suggestions, setSuggestions] = useState<MatchResult[]>([]);
  const [loadingSuggestions, setLoadingSuggestions] = useState(false);
  
  const { isOpen, onOpen, onClose } = useDisclosure();
  const toast = useToast();

  useEffect(() => {
    loadData();
  }, []);

  const loadData = async () => {
    setIsLoading(true);
    try {
      const [statsRes, unmatchedRes] = await Promise.all([
        fetch('/api/matching/stats'),
        fetch('/api/matching/unmatched-music-files?limit=200')
      ]);

      if (statsRes.ok) {
        const statsData = await statsRes.json();
        setStats(statsData.stats);
      }

      if (unmatchedRes.ok) {
        const unmatchedData = await unmatchedRes.json();
        setUnmatchedMusicFiles(unmatchedData.musicFiles);
      }

      // Matched and songs-with-files lists are omitted
    } catch (error) {
      console.error('Error loading data:', error);
      toast({
        title: 'Error',
        description: 'Failed to load matching data',
        status: 'error',
        duration: 3000,
        isClosable: true,
      });
    } finally {
      setIsLoading(false);
    }
  };

  const handleAutoLink = async () => {
    setAutoLinking(true);
    try {
      const response = await fetch('/api/matching/auto-link', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          minConfidence: 0.7,
          enableFuzzyMatching: true,
          enablePartialMatching: false
        }),
      });

      if (!response.ok) {
        const errText = await response.text();
        throw new Error(errText || 'Auto-linking failed');
      }

      const result = await response.json();
      toast({
        title: 'Auto-linking Started',
        description: `Job ${result.jobId} started.`,
        status: 'info',
        duration: 4000,
        isClosable: true,
      });
      // Do not call loadData immediately; background job UI will refresh stats as it completes
    } catch (error) {
      console.error('Error during auto-linking:', error);
      toast({
        title: 'Error',
        description: error instanceof Error ? error.message : 'Failed to auto-link music files',
        status: 'error',
        duration: 3000,
        isClosable: true,
      });
    } finally {
      setAutoLinking(false);
    }
  };

  const handleGetSuggestions = async (musicFile: any) => {
    setSelectedMusicFile(musicFile);
    setLoadingSuggestions(true);
    try {
      const response = await fetch(`/api/matching/music-file/${musicFile._id}/suggestions`);
      if (response.ok) {
        const data = await response.json();
        setSuggestions(data.matches);
        onOpen();
      } else {
        throw new Error('Failed to get suggestions');
      }
    } catch (error) {
      console.error('Error getting suggestions:', error);
      toast({
        title: 'Error',
        description: 'Failed to get matching suggestions',
        status: 'error',
        duration: 3000,
        isClosable: true,
      });
    } finally {
      setLoadingSuggestions(false);
    }
  };

  const handleLinkMusicFile = async (musicFileId: string, songId: string) => {
    try {
      const response = await fetch(`/api/matching/link/${musicFileId}/${songId}`, {
        method: 'POST',
      });

      if (response.ok) {
        toast({
          title: 'Success',
          description: 'Music file linked to song successfully',
          status: 'success',
          duration: 3000,
          isClosable: true,
        });
        onClose();
        loadData(); // Refresh data
      } else {
        throw new Error('Failed to link music file');
      }
    } catch (error) {
      console.error('Error linking music file:', error);
      toast({
        title: 'Error',
        description: 'Failed to link music file to song',
        status: 'error',
        duration: 3000,
        isClosable: true,
      });
    }
  };

  // Unlink handler removed with matched/songs-with-files lists

  const getConfidenceColor = (confidence: number) => {
    if (confidence >= 0.9) return 'green';
    if (confidence >= 0.7) return 'blue';
    if (confidence >= 0.5) return 'yellow';
    return 'red';
  };

  const canAutoLink = !!stats && stats.unmatchedMusicFiles > 0;

  if (isLoading) {
    return (
      <Box p={6}>
        <Progress size="xs" isIndeterminate />
        <Text mt={4} textAlign="center">Loading matching data...</Text>
      </Box>
    );
  }

  return (
    <VStack spacing={6} align="stretch">
      {/* Statistics */}
      {stats && (
        <Card bg="gray.800" borderColor="gray.700" borderWidth="1px">
          <CardHeader>
            <Heading size="md" color="white">Matching Statistics</Heading>
          </CardHeader>
          <CardBody>
            <SimpleGrid columns={{ base: 2, md: 4 }} spacing={4}>
              <Stat>
                <StatLabel color="gray.400">Total Songs</StatLabel>
                <StatNumber color="white">{stats.totalSongs}</StatNumber>
              </Stat>
              <Stat>
                <StatLabel color="gray.400">Music Files</StatLabel>
                <StatNumber color="white">{stats.totalMusicFiles}</StatNumber>
              </Stat>
              <Stat>
                <StatLabel color="gray.400">Match Rate</StatLabel>
                <StatNumber color="green.400">{stats.matchRate}</StatNumber>
                <StatHelpText color="gray.500">
                  {stats.matchedMusicFiles} of {stats.totalMusicFiles} files matched
                </StatHelpText>
              </Stat>
              <Stat>
                <StatLabel color="gray.400">Unmatched</StatLabel>
                <StatNumber color="orange.400">{stats.unmatchedMusicFiles}</StatNumber>
                <StatHelpText color="gray.500">
                  {stats.songsWithoutMusicFiles} songs without files
                </StatHelpText>
              </Stat>
            </SimpleGrid>
          </CardBody>
        </Card>
      )}

      {/* Auto-Link Button */}
      <Card bg="gray.800" borderColor="gray.700" borderWidth="1px">
        <CardBody>
          <VStack spacing={4}>
            <Text color="gray.300" textAlign="center">
              Try linking any remaining unmatched files. The main S3 sync already performs matching; use this for leftovers.
            </Text>
            <Button
              leftIcon={<FiZap />}
              colorScheme="blue"
              size="lg"
              onClick={handleAutoLink}
              isLoading={autoLinking}
              loadingText="Auto-Linking..."
              _hover={{ bg: "blue.700" }}
              isDisabled={autoLinking || !canAutoLink}
            >
              Auto-Link Remaining Files
            </Button>
          </VStack>
        </CardBody>
      </Card>

      {/* Unmatched Music Files */}
      <Card bg="gray.800" borderColor="gray.700" borderWidth="1px">
        <CardHeader>
          <Heading size="md" color="white">Unmatched Music Files ({unmatchedMusicFiles.length})</Heading>
        </CardHeader>
        <CardBody>
          {unmatchedMusicFiles.length === 0 ? (
            <Text color="gray.500" textAlign="center">
              All music files are matched! 🎉
            </Text>
          ) : (
            <VStack spacing={3} align="stretch">
              {unmatchedMusicFiles.slice(0, 10).map((file) => (
                <Box
                  key={file._id}
                  p={3}
                  border="1px"
                  borderColor="gray.700"
                  borderRadius="md"
                  bg="gray.900"
                >
                  <HStack justify="space-between">
                    <VStack align="start" spacing={1} flex={1}>
                      <Text fontWeight="bold" fontSize="sm" color="white">
                        {file.title || file.originalName}
                      </Text>
                      <Text fontSize="xs" color="gray.400">
                        {file.artist}
                      </Text>
                      <Text fontSize="xs" color="gray.500">
                        {file.album}
                      </Text>
                    </VStack>
                    <HStack spacing={2}>
                      <Tooltip label="Get matching suggestions">
                        <IconButton
                          aria-label="Get suggestions"
                          icon={<FiSearch />}
                          size="sm"
                          variant="ghost"
                          colorScheme="blue"
                          onClick={() => handleGetSuggestions(file)}
                          _hover={{ bg: "blue.900" }}
                        />
                      </Tooltip>
                      <Tooltip label="Play music file">
                        <IconButton
                          aria-label="Play"
                          icon={<FiPlay />}
                          size="sm"
                          variant="ghost"
                          colorScheme="green"
                          _hover={{ bg: "green.900" }}
                        />
                      </Tooltip>
                    </HStack>
                  </HStack>
                </Box>
              ))}
              {unmatchedMusicFiles.length > 10 && (
                <Text fontSize="sm" color="gray.500" textAlign="center">
                  Showing first 10 of {unmatchedMusicFiles.length} unmatched files
                </Text>
              )}
            </VStack>
          )}
        </CardBody>
      </Card>

      {/* Removed Matched Music Files and Songs with Music Files lists to streamline UI */}

      {/* Suggestions Modal */}
      <Modal isOpen={isOpen} onClose={onClose} size="xl">
        <ModalOverlay />
        <ModalContent bg="gray.800" borderColor="gray.700" borderWidth="1px">
          <ModalHeader color="white">
            Matching Suggestions for "{selectedMusicFile?.title || selectedMusicFile?.originalName}"
          </ModalHeader>
          <ModalCloseButton color="gray.400" />
          <ModalBody>
            {loadingSuggestions ? (
              <VStack spacing={4}>
                <Spinner size="lg" color="blue.400" />
                <Text color="gray.400">Finding matching songs...</Text>
              </VStack>
            ) : suggestions.length === 0 ? (
              <Text color="gray.500" textAlign="center">
                No matching songs found. You can manually link this file later.
              </Text>
            ) : (
              <VStack spacing={3} align="stretch">
                {suggestions.map((suggestion, index) => (
                  <Box
                    key={index}
                    p={3}
                    border="1px"
                    borderColor="gray.700"
                    borderRadius="md"
                    bg="gray.900"
                  >
                    <HStack justify="space-between">
                      <VStack align="start" spacing={1} flex={1}>
                        <HStack spacing={2}>
                          <Text fontWeight="bold" fontSize="sm" color="white">
                            {suggestion.song.title}
                          </Text>
                          <Badge
                            colorScheme={getConfidenceColor(suggestion.confidence)}
                            size="sm"
                            bg={`${getConfidenceColor(suggestion.confidence)}.900`}
                            color={`${getConfidenceColor(suggestion.confidence)}.200`}
                          >
                            {Math.round(suggestion.confidence * 100)}%
                          </Badge>
                        </HStack>
                        <Text fontSize="xs" color="gray.400">
                          {suggestion.song.artist}
                        </Text>
                        {suggestion.song.location && (
                          <Text fontSize="xs" color="gray.500">
                            📁 {suggestion.song.location}
                          </Text>
                        )}
                        <Text fontSize="xs" color="blue.400">
                          {suggestion.matchReason}
                        </Text>
                      </VStack>
                      <Tooltip label="Link this song">
                        <IconButton
                          aria-label="Link"
                          icon={<FiLink />}
                          size="sm"
                          variant="ghost"
                          colorScheme="blue"
                          onClick={() => {
                            handleLinkMusicFile(selectedMusicFile._id, suggestion.song._id);
                            onClose();
                          }}
                          _hover={{ bg: "blue.900" }}
                        />
                      </Tooltip>
                    </HStack>
                  </Box>
                ))}
              </VStack>
            )}
          </ModalBody>
          <ModalFooter>
            <Button variant="ghost" onClick={onClose} color="gray.400" _hover={{ bg: "gray.700" }}>
              Close
            </Button>
          </ModalFooter>
        </ModalContent>
      </Modal>
    </VStack>
  );
}; 