import React, { ChangeEvent } from 'react';
import {
  Box,
  Flex,
  Text,
  Button,
  IconButton,
  HStack,
  Menu,
  MenuButton,
  MenuList,
  MenuItem,
  MenuDivider,
  Checkbox
} from '@chakra-ui/react';
import { Input, InputGroup, InputLeftElement } from "@chakra-ui/input";
import { Search2Icon, ChevronDownIcon } from "@chakra-ui/icons";
import type { Song, PlaylistNode } from "../types/interfaces";
import { useState, useCallback, useMemo } from "react";
import type { MouseEvent } from 'react';
import { v4 as uuidv4 } from 'uuid';
import { formatDuration, formatTotalDuration } from '../utils/formatters';

interface SongListProps {
  songs: Song[];
  onAddToPlaylist: (songIds: string[], playlistName: string) => void;
  onRemoveFromPlaylist?: (songIds: string[]) => void;
  playlists: PlaylistNode[];
  onSongSelect: (song: Song) => void;
  selectedSongId: string | null;
  currentPlaylist: string | null;
  depth?: number;
}

export const SongList: React.FC<SongListProps> = ({ 
  songs, 
  onAddToPlaylist, 
  onRemoveFromPlaylist,
  playlists,
  onSongSelect,
  selectedSongId,
  currentPlaylist,
  depth = 0
}) => {
  const [selectedSongs, setSelectedSongs] = useState<Set<string>>(new Set());
  const [searchQuery, setSearchQuery] = useState("");

  // Helper function to get all playlists (excluding folders) from the playlist tree
  const getAllPlaylists = useCallback((nodes: PlaylistNode[]): PlaylistNode[] => {
    let result: PlaylistNode[] = [];
    for (const node of nodes) {
      if (node.type === 'playlist') {
        result.push(node);
      } else if (node.type === 'folder' && node.children) {
        result = result.concat(getAllPlaylists(node.children));
      }
    }
    return result;
  }, []);

  // Get flattened list of all playlists
  const allPlaylists = useMemo(() => getAllPlaylists(playlists), [playlists, getAllPlaylists]);

  const filteredSongs = useMemo(() => {
    if (!searchQuery) return songs;
    const query = searchQuery.toLowerCase();
    return songs.filter(
      song => 
        song.title.toLowerCase().includes(query) || 
        song.artist.toLowerCase().includes(query)
    );
  }, [songs, searchQuery]);

  const toggleSelection = useCallback((songId: string) => {
    setSelectedSongs(prev => {
      const newSelection = new Set(prev);
      if (newSelection.has(songId)) {
        newSelection.delete(songId);
      } else {
        newSelection.add(songId);
      }
      return newSelection;
    });
  }, []);

  const toggleSelectAll = useCallback(() => {
    setSelectedSongs(prev => 
      prev.size === songs.length ? new Set() : new Set(songs.map(s => s.id))
    );
  }, [songs]);

  const handleBulkAddToPlaylist = (playlistName: string) => {
    if (selectedSongs.size > 0) {
      onAddToPlaylist(Array.from(selectedSongs), playlistName);
      setSelectedSongs(new Set()); // Clear selection after action
    }
  };

  // Calculate total duration
  const totalDuration = useMemo(() => {
    return filteredSongs.reduce((total, song) => {
      if (!song.totalTime) return total;
      // Convert to seconds, handling milliseconds if present
      const seconds = Math.floor(Number(song.totalTime) / (song.totalTime.length > 4 ? 1000 : 1));
      return total + seconds;
    }, 0);
  }, [filteredSongs]);

  return (
    <Flex direction="column" height="100%">
      {/* Sticky Header */}
      <Box
        position="sticky"
        top={0}
        bg="gray.900"
        zIndex={1}
        pb={4}
      >
        {/* Search Bar */}
        <InputGroup mb={4}>
          <InputLeftElement pointerEvents="none">
            <Search2Icon color="gray.300" />
          </InputLeftElement>
          <Input
            placeholder="Search songs by title or artist..."
            value={searchQuery}
            onChange={(e: ChangeEvent<HTMLInputElement>) => setSearchQuery(e.target.value)}
            bg="gray.800"
            borderColor="gray.600"
            _hover={{ borderColor: "gray.500" }}
            _focus={{ borderColor: "blue.300", boxShadow: "0 0 0 1px var(--chakra-colors-blue-300)" }}
          />
        </InputGroup>

        {/* Bulk Actions Toolbar */}
        <Flex justify="space-between" align="center" p={2} bg="gray.800" borderRadius="md">
          <HStack spacing={4}>
            <Checkbox
              isChecked={selectedSongs.size === filteredSongs.length}
              isIndeterminate={selectedSongs.size > 0 && selectedSongs.size < filteredSongs.length}
              onChange={toggleSelectAll}
              colorScheme="blue"
              sx={{
                '& > span:first-of-type': {
                  opacity: 1,
                  border: '2px solid',
                  borderColor: 'gray.500'
                }
              }}
            >
              {selectedSongs.size === 0 
                ? "Select All" 
                : `Selected ${selectedSongs.size} song${selectedSongs.size === 1 ? '' : 's'}`}
            </Checkbox>
            <Text color="gray.400" fontSize="sm">
              {filteredSongs.length} song{filteredSongs.length === 1 ? '' : 's'} • {formatTotalDuration(totalDuration)}
            </Text>
          </HStack>
          
          {selectedSongs.size > 0 && (
            <Menu>
              <MenuButton
                as={Button}
                rightIcon={<ChevronDownIcon />}
                size="sm"
                colorScheme="blue"
              >
                Actions
              </MenuButton>
              <MenuList>
                {allPlaylists.map((playlist) => (
                  <MenuItem
                    key={playlist.id}
                    onClick={() => {
                      handleBulkAddToPlaylist(playlist.name);
                    }}
                  >
                    Add to {playlist.name}
                  </MenuItem>
                ))}
                {currentPlaylist !== "All Songs" && onRemoveFromPlaylist && (
                  <>
                    <MenuDivider />
                    <MenuItem
                      color="red.300"
                      onClick={() => {
                        onRemoveFromPlaylist(Array.from(selectedSongs));
                        setSelectedSongs(new Set());
                      }}
                    >
                      Remove from {currentPlaylist}
                    </MenuItem>
                  </>
                )}
              </MenuList>
            </Menu>
          )}
        </Flex>
      </Box>

      {/* Scrollable Song List */}
      <Box flex={1} overflowY="auto" mt={2}>
        <Flex direction="column" gap={2}>
          {filteredSongs.map((song) => (
            <Flex 
              key={song.id}
              alignItems="center" 
              p={2} 
              pl={depth > 0 ? 4 + (depth * 4) : 2}
              borderBottom="1px" 
              borderColor="gray.700"
              bg={selectedSongId === song.id ? "gray.700" : "transparent"}
              _hover={{ bg: "gray.800", cursor: "pointer" }}
              onClick={() => onSongSelect(song)}
            >
              <Checkbox
                isChecked={selectedSongs.has(song.id)}
                onChange={(e: ChangeEvent<HTMLInputElement>) => {
                  e.stopPropagation();
                  toggleSelection(song.id);
                }}
                mr={4}
                onClick={(e) => e.stopPropagation()}
                size={depth > 0 ? "sm" : "md"}
              />
              <Box flex="1">
                <Text 
                  fontWeight="bold" 
                  color={selectedSongId === song.id ? "white" : "gray.100"}
                  fontSize={depth > 0 ? "sm" : "md"}
                >
                  {song.title}
                </Text>
                <Text 
                  fontSize={depth > 0 ? "xs" : "sm"} 
                  color={selectedSongId === song.id ? "gray.300" : "gray.500"}
                >
                  {song.artist} • {formatDuration(song.totalTime)}
                </Text>
              </Box>
              <Menu>
                <MenuButton 
                  as={IconButton} 
                  aria-label="Options" 
                  icon={<ChevronDownIcon />} 
                  variant="ghost"
                  onClick={(e) => e.stopPropagation()}
                  size={depth > 0 ? "xs" : "sm"}
                  ml="auto"
                />
                <MenuList>
                  {allPlaylists.map((playlist) => (
                    <MenuItem
                      key={playlist.id}
                      onClick={(e) => {
                        e.stopPropagation();
                        onAddToPlaylist([song.id], playlist.name);
                      }}
                    >
                      Add to {playlist.name}
                    </MenuItem>
                  ))}
                  {currentPlaylist !== "All Songs" && onRemoveFromPlaylist && (
                    <>
                      <MenuDivider />
                      <MenuItem
                        color="red.300"
                        onClick={(e) => {
                          e.stopPropagation();
                          onRemoveFromPlaylist([song.id]);
                        }}
                      >
                        Remove from {currentPlaylist}
                      </MenuItem>
                    </>
                  )}
                </MenuList>
              </Menu>
            </Flex>
          ))}
        </Flex>
      </Box>
    </Flex>
  );
}; 