import { Box, Button, Flex, Heading, Input, Spinner, Text, useStyleConfig, useBreakpointValue, IconButton, Drawer, DrawerBody, DrawerHeader, DrawerOverlay, DrawerContent, DrawerCloseButton, useDisclosure, Container, Menu, MenuButton, MenuList, MenuItem, useToken } from "@chakra-ui/react";
import { ChevronLeftIcon, ChevronRightIcon, HamburgerIcon, ViewIcon, SettingsIcon, DragHandleIcon } from "@chakra-ui/icons";
import { useState, useRef, useEffect } from "react";
import { useNavigate, useLocation } from "react-router-dom";
import { SongList } from "./components/SongList";
import { PlaylistManager } from "./components/PlaylistManager";
import { SongDetails } from "./components/SongDetails";
import { useXmlParser } from "./hooks/useXmlParser";
import { exportToXml } from "./services/xmlService";
import { api } from "./services/api";
import type { Song, PlaylistNode } from "./types/interfaces";
import { v4 as uuidv4 } from "uuid";
import "./App.css";

const StyledFileInput = ({ isMobile = false }) => {
  const { handleFileUpload } = useXmlParser();
  const inputRef = useRef<HTMLInputElement>(null);

  const handleClick = () => {
    inputRef.current?.click();
  };

  return (
    <Box
      position="relative"
      width="auto"
      maxW={isMobile ? "100%" : "300px"}
    >
      <Input
        type="file"
        accept=".xml"
        onChange={handleFileUpload}
        height="40px"
        padding="8px 12px"
        opacity="0"
        position="absolute"
        top="0"
        left="0"
        width="100%"
        cursor="pointer"
        ref={inputRef}
        style={{ display: 'none' }}
      />
      <Button
        width="100%"
        height="40px"
        bg="gray.700"
        color="gray.300"
        border="2px dashed"
        borderColor="gray.600"
        _hover={{
          bg: "gray.600",
          borderColor: "gray.500"
        }}
        _active={{
          bg: "gray.500"
        }}
        onClick={handleClick}
        size={isMobile ? "sm" : "md"}
      >
        Choose XML File
      </Button>
    </Box>
  );
};

const ResizeHandle = ({ onMouseDown }: { onMouseDown: (e: React.MouseEvent) => void }) => (
  <Box
    position="absolute"
    right="-4px"
    top={0}
    bottom={0}
    width="8px"
    cursor="col-resize"
    zIndex={1}
    _hover={{
      '&::after': {
        bg: 'blue.500',
      }
    }}
    onMouseDown={onMouseDown}
  >
    <Box
      position="absolute"
      left="3px"
      top={0}
      bottom={0}
      width="2px"
      bg="gray.600"
      transition="background-color 0.2s"
      _hover={{ bg: 'blue.500' }}
    />
  </Box>
);

const findPlaylistByName = (playlists: PlaylistNode[], name: string): PlaylistNode | null => {
  for (const playlist of playlists) {
    if (playlist.name === name) return playlist;
    if (playlist.type === 'folder' && playlist.children) {
      const found = findPlaylistByName(playlist.children, name);
      if (found) return found;
    }
  }
  return null;
};

const getAllPlaylistTracks = (node: PlaylistNode): string[] => {
  if (!node.type || node.type === 'playlist') {  // Handle both old and new playlist formats
    return node.tracks || [];
  }
  if (node.type === 'folder' && node.children) {
    return node.children.flatMap(child => getAllPlaylistTracks(child));
  }
  return [];
};

export default function RekordboxReader() {
  const { songs, playlists, setPlaylists, loading } = useXmlParser();
  const [selectedSong, setSelectedSong] = useState<Song | null>(null);
  const navigate = useNavigate();
  const location = useLocation();
  const initialLoadDone = useRef(false);
  const mobileFileInputRef = useRef<HTMLInputElement>(null);
  const { isOpen, onOpen, onClose } = useDisclosure();
  
  const isMobile = useBreakpointValue({ base: true, md: false });
  const [sidebarWidth, setSidebarWidth] = useState(400);
  const [isResizing, setIsResizing] = useState(false);
  const resizeRef = useRef<{ startX: number; startWidth: number } | null>(null);

  // Get the current playlist from URL or default to "All Songs"
  const currentPlaylist = location.pathname === "/" 
    ? "All Songs" 
    : decodeURIComponent(location.pathname.slice(1));

  useEffect(() => {
    // Only run this check after the initial data load
    if (!loading && playlists.length > 0) {
      initialLoadDone.current = true;
    }

    // If we've loaded the data and the playlist doesn't exist
    if (initialLoadDone.current && 
        currentPlaylist !== "All Songs" && 
        !findPlaylistByName(playlists, currentPlaylist)) {
      navigate("/", { replace: true });
    }
  }, [currentPlaylist, playlists, navigate, loading]);

  const handlePlaylistSelect = (name: string) => {
    setSelectedSong(null); // Clear selected song when changing playlists
    if (name === "All Songs") {
      navigate("/");
    } else {
      // Use encodeURIComponent to properly handle spaces and special characters
      const encodedName = encodeURIComponent(name);
      navigate(`/${encodedName}`);
    }
  };

  const handleCreatePlaylist = async (name: string) => {
    const newPlaylist: PlaylistNode = {
      id: uuidv4(),
      name,
      type: 'playlist',
      tracks: [],
      children: undefined
    };
    const updatedPlaylists = [...playlists, newPlaylist];
    const savedPlaylists = await api.savePlaylists(updatedPlaylists);
    setPlaylists(savedPlaylists);
    handlePlaylistSelect(name); // Navigate to the new playlist
  };

  const handleAddSongsToPlaylist = async (songIds: string[], playlistName: string) => {
    const updatedPlaylists = playlists.map(node => {
      if (node.name === playlistName && node.type === 'playlist') {
        return {
          ...node,
          tracks: [...new Set([...(node.tracks || []), ...songIds])]
        };
      }
      if (node.type === 'folder' && node.children) {
        return {
          ...node,
          children: node.children.map(child => {
            if (child.name === playlistName && child.type === 'playlist') {
              return {
                ...child,
                tracks: [...new Set([...(child.tracks || []), ...songIds])]
              };
            }
            return child;
          })
        };
      }
      return node;
    });
    const savedPlaylists = await api.savePlaylists(updatedPlaylists);
    setPlaylists(savedPlaylists);
  };

  const handleRemoveFromPlaylist = async (songIds: string[]) => {
    if (currentPlaylist === "All Songs") return;

    const updatedPlaylists = playlists.map(node => {
      if (node.name === currentPlaylist && node.type === 'playlist') {
        return {
          ...node,
          tracks: (node.tracks || []).filter(id => !songIds.includes(id))
        };
      }
      if (node.type === 'folder' && node.children) {
        return {
          ...node,
          children: node.children.map(child => {
            if (child.name === currentPlaylist && child.type === 'playlist') {
              return {
                ...child,
                tracks: (child.tracks || []).filter(id => !songIds.includes(id))
              };
            }
            return child;
          })
        };
      }
      return node;
    });
    const savedPlaylists = await api.savePlaylists(updatedPlaylists);
    setPlaylists(savedPlaylists);
  };

  const handleExport = () => {
    const xmlContent = exportToXml(songs, playlists);
    const blob = new Blob([xmlContent], { type: "application/xml" });
    const url = URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = url;
    a.download = "rekordbox_playlists.xml";
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
  };

  const handlePlaylistDelete = async (name: string) => {
    const updatedPlaylists = playlists.filter(p => p.name !== name);
    const savedPlaylists = await api.savePlaylists(updatedPlaylists);
    setPlaylists(savedPlaylists);
    if (currentPlaylist === name) {
      navigate("/"); // Navigate back to All Songs if the current playlist is deleted
    }
  };

  const displayedSongs = currentPlaylist === "All Songs"
    ? songs
    : songs.filter((song: Song) => {
        // Try to find the playlist either in nested structure or at root level
        const playlist = findPlaylistByName(playlists, currentPlaylist) || 
                        playlists.find(p => p.name === currentPlaylist);
        
        if (!playlist) return false;
        
        // Use getAllPlaylistTracks for both nested and root playlists
        const playlistTracks = getAllPlaylistTracks(playlist);
        return playlistTracks.includes(song.id);
      });

  const handleResizeStart = (e: React.MouseEvent) => {
    e.preventDefault();
    setIsResizing(true);
    resizeRef.current = {
      startX: e.pageX,
      startWidth: sidebarWidth,
    };
  };

  const handleResizeMove = (e: MouseEvent) => {
    if (!isResizing || !resizeRef.current) return;

    const delta = e.pageX - resizeRef.current.startX;
    const newWidth = Math.max(300, Math.min(800, resizeRef.current.startWidth + delta));
    setSidebarWidth(newWidth);
  };

  const handleResizeEnd = () => {
    setIsResizing(false);
    resizeRef.current = null;
  };

  useEffect(() => {
    if (isResizing) {
      window.addEventListener('mousemove', handleResizeMove);
      window.addEventListener('mouseup', handleResizeEnd);
    }
    return () => {
      window.removeEventListener('mousemove', handleResizeMove);
      window.removeEventListener('mouseup', handleResizeEnd);
    };
  }, [isResizing]);

  if (loading) {
    return (
      <Flex height="100vh" align="center" justify="center" direction="column" gap={4}>
        <Spinner size="xl" />
        <Text>Loading your library...</Text>
        {currentPlaylist !== "All Songs" && (
          <Text fontSize="sm" color="gray.500">
            Navigating to playlist: {currentPlaylist}
          </Text>
        )}
      </Flex>
    );
  }

  const playlistManager = (
    <PlaylistManager
      playlists={playlists}
      selectedItem={currentPlaylist}
      onPlaylistCreate={handleCreatePlaylist}
      onPlaylistSelect={(name) => {
        handlePlaylistSelect(name || "All Songs");
        if (isMobile) onClose();
      }}
      onPlaylistDelete={handlePlaylistDelete}
    />
  );

  return (
    <Box 
      position="fixed"
      top={0}
      left={0}
      right={0}
      bottom={0}
      overflow="hidden"
      margin={0}
      padding={0}
      userSelect={isResizing ? 'none' : 'auto'}
    >
      <Flex direction="column" h="100%" w="100%">
        {/* Header */}
        <Flex 
          px={isMobile ? 2 : 4} 
          py={2}
          bg="gray.800" 
          borderBottom="1px" 
          borderColor="gray.700" 
          align="center" 
          gap={2}
          w="full"
        >
          {isMobile && (
            <IconButton
              aria-label="Open menu"
              icon={<ChevronRightIcon />}
              onClick={onOpen}
              variant="solid"
              colorScheme="blue"
              size="md"
              fontSize="20px"
            />
          )}
          <Heading size={isMobile ? "sm" : "md"}>Rekordbox Reader</Heading>
          
          {/* Desktop Actions */}
          {!isMobile && (
            <Flex gap={2} align="center" ml="auto">
              <StyledFileInput />
              {songs.length > 0 && (
                <Button onClick={handleExport} size="sm" width="auto">
                  Export XML
                </Button>
              )}
            </Flex>
          )}

          {/* Mobile Actions */}
          {isMobile && (
            <Menu>
              <MenuButton
                as={IconButton}
                icon={<SettingsIcon />}
                variant="ghost"
                ml="auto"
                size="md"
                color="gray.300"
                _hover={{ color: "white", bg: "whiteAlpha.200" }}
              />
              <MenuList bg="gray.800" borderColor="gray.700">
                <MenuItem 
                  bg="gray.800" 
                  _hover={{ bg: "gray.700" }}
                >
                  <StyledFileInput isMobile />
                </MenuItem>
                {songs.length > 0 && (
                  <MenuItem
                    bg="gray.800"
                    _hover={{ bg: "gray.700" }}
                    onClick={handleExport}
                    color="gray.100"
                  >
                    Export XML
                  </MenuItem>
                )}
              </MenuList>
            </Menu>
          )}
        </Flex>

        {/* Main Content */}
        <Flex flex={1} overflow="hidden" w="full">
          {/* Sidebar - Desktop */}
          {!isMobile && (
            <Box
              position="relative"
              w={`${sidebarWidth}px`}
              minW={`${sidebarWidth}px`}
              p={4}
              borderRight="1px"
              borderColor="gray.700"
              overflowY="auto"
              bg="gray.900"
            >
              {playlistManager}
              <ResizeHandle onMouseDown={handleResizeStart} />
            </Box>
          )}

          {/* Sidebar - Mobile */}
          <Drawer 
            isOpen={isOpen} 
            placement="left" 
            onClose={onClose}
            size="full"
          >
            <DrawerOverlay />
            <DrawerContent bg="gray.900" p={0}>
              <DrawerHeader 
                borderBottomWidth="1px" 
                bg="gray.800" 
                display="flex" 
                alignItems="center"
                px={2}
                py={2}
              >
                <Text>Playlists</Text>
                <IconButton
                  aria-label="Close menu"
                  icon={<ChevronLeftIcon />}
                  onClick={onClose}
                  variant="ghost"
                  ml="auto"
                  color="blue.400"
                  _hover={{ color: "blue.300", bg: "whiteAlpha.200" }}
                />
              </DrawerHeader>
              <DrawerBody p={2}>
                {playlistManager}
              </DrawerBody>
            </DrawerContent>
          </Drawer>

          {/* Main Content Area */}
          <Flex 
            flex={1} 
            gap={4} 
            p={isMobile ? 2 : 4} 
            overflowY="hidden" 
            w="full"
          >
            {/* Song List */}
            <Box flex={1} overflowY="auto" w="full">
              <SongList
                songs={displayedSongs}
                onAddToPlaylist={handleAddSongsToPlaylist}
                onRemoveFromPlaylist={handleRemoveFromPlaylist}
                playlists={playlists}
                onSongSelect={setSelectedSong}
                selectedSongId={selectedSong?.id || null}
                currentPlaylist={currentPlaylist}
              />
            </Box>

            {/* Details Panel */}
            {!isMobile && (
              <Box
                w="350px"
                minW="350px"
                p={4}
                borderLeft="1px"
                borderColor="gray.700"
                overflowY="auto"
                bg="gray.900"
                sx={{
                  '&::-webkit-scrollbar': {
                    width: '8px',
                    borderRadius: '8px',
                    backgroundColor: 'gray.900',
                  },
                  '&::-webkit-scrollbar-thumb': {
                    backgroundColor: 'gray.700',
                    borderRadius: '8px',
                  },
                  overflowY: 'auto',
                  overflowX: 'hidden',
                }}
              >
                <SongDetails song={selectedSong} />
              </Box>
            )}
          </Flex>
        </Flex>
      </Flex>
    </Box>
  );
}
