import {
  Stack,
  ActionIcon,
  Text,
  Group,
  Loader,
} from "@mantine/core";
import { TrashIcon } from "@phosphor-icons/react";
import { useCallback, memo } from "react";
import { useFreeAgents } from "../queries";
import PlayerAvatar from "@/components/player-avatar";
import { PlayerInfo, Player } from "@/features/players/types";
import Typeahead, { TypeaheadOption } from "@/components/typeahead";
import { usePlayers } from "@/features/players/queries";
import useAdminEnrollPlayer from "../hooks/use-admin-enroll-player";
import useAdminUnenrollPlayer from "../hooks/use-admin-unenroll-player";

interface EditEnrolledPlayersProps {
  tournamentId: string;
}

interface PlayerItemProps {
  player: PlayerInfo;
  onRemove: (playerId: string) => void;
  disabled: boolean;
}

const PlayerItem = memo(({ player, onRemove, disabled }: PlayerItemProps) => {
  return (
    <Group py="xs" px="sm" w="100%" gap="sm" align="center">
      <PlayerAvatar
        name={`${player.first_name} ${player.last_name}`}
        size={32}
      />
      <Stack gap={0} style={{ flex: 1, minWidth: 0 }}>
        <Text fw={500} truncate>
          {player.first_name} {player.last_name}
        </Text>
      </Stack>
      <ActionIcon
        variant="subtle"
        color="red"
        onClick={() => onRemove(player.id)}
        disabled={disabled}
        size="sm"
      >
        <TrashIcon size={14} />
      </ActionIcon>
    </Group>
  );
});

const EditEnrolledPlayers = ({ tournamentId }: EditEnrolledPlayersProps) => {
  const { data: freeAgents = [], isLoading } = useFreeAgents(tournamentId);
  const { data: allPlayers = [] } = usePlayers();

  const { mutate: removeFreeAgent, isPending: isRemoving } = useAdminUnenrollPlayer();
  const { mutate: enrollPlayer, isPending: isEnrolling } = useAdminEnrollPlayer();

  const handleRemovePlayer = useCallback(
    (playerId: string) => {
      removeFreeAgent({ tournamentId, playerId });
    },
    [removeFreeAgent, tournamentId]
  );

  const handleEnrollPlayer = useCallback(
    (option: TypeaheadOption<Player>) => {
      enrollPlayer({ tournamentId, playerId: option.data.id });
    },
    [enrollPlayer, tournamentId]
  );

  const enrolledPlayers = freeAgents.map(agent => agent.player).filter((p): p is PlayerInfo => p !== undefined);
  const enrolledPlayerIds = new Set(enrolledPlayers.map(p => p.id));
  const hasEnrolledPlayers = enrolledPlayers.length > 0;

  const searchPlayers = async (query: string): Promise<TypeaheadOption<Player>[]> => {
    if (!query.trim()) return [];

    const filtered = allPlayers.filter((player: Player) => {
      const fullName = `${player.first_name} ${player.last_name}`.toLowerCase();
      return fullName.includes(query.toLowerCase()) && !enrolledPlayerIds.has(player.id);
    });

    return filtered.map((player: Player) => ({
      id: player.id,
      data: player
    }));
  };

  const renderPlayerOption = (option: TypeaheadOption<Player>) => {
    const player = option.data;
    return (
      <Group py="xs" px="sm" gap="sm" align="center">
        <PlayerAvatar
          name={`${player.first_name} ${player.last_name}`}
          size={32}
        />
        <Text fw={500} truncate>
          {player.first_name} {player.last_name}
        </Text>
      </Group>
    );
  };

  const formatPlayer = (option: TypeaheadOption<Player>) => {
    return `${option.data.first_name} ${option.data.last_name}`;
  };

  return (
    <Stack gap="lg" w="100%">
      <Stack gap="xs">
        <Text fw={600} size="sm">
          Add Player
        </Text>
        <Typeahead
          placeholder="Search for players to enroll..."
          onSelect={handleEnrollPlayer}
          searchFn={searchPlayers}
          renderOption={renderPlayerOption}
          format={formatPlayer}
          disabled={isEnrolling}
        />
      </Stack>

      <Stack gap="xs">
        <Group justify="space-between">
          <Text fw={600} size="sm">
            Enrolled Players
          </Text>
          <Text size="xs" c="dimmed">
            {enrolledPlayers.length} players
          </Text>
        </Group>

        {isLoading ? (
          <Group justify="center" py="md">
            <Loader size="sm" />
          </Group>
        ) : !hasEnrolledPlayers ? (
          <Text size="sm" c="dimmed" ta="center" py="lg">
            No players enrolled yet
          </Text>
        ) : (
          <Stack gap="xs" w="100%">
            {enrolledPlayers.map((player) => (
              <PlayerItem
                key={player.id}
                player={player}
                onRemove={handleRemovePlayer}
                disabled={isRemoving}
              />
            ))}
          </Stack>
        )}
      </Stack>
    </Stack>
  );
};

export default EditEnrolledPlayers;
