import React, { useState, useEffect, useCallback, useMemo } from "react";
import {
  Stack,
  Text,
  Group,
  ActionIcon,
  Button,
  NumberInput,
  LoadingOverlay,
} from "@mantine/core";
import { DragDropContext, Droppable, Draggable } from "@hello-pangea/dnd";
import { DotsNineIcon } from "@phosphor-icons/react";
import { useServerMutation } from "@/lib/tanstack-query/hooks/use-server-mutation";
import { generateTournamentBracket } from "../../matches/server";
import { TeamInfo } from "@/features/teams/types";
import TeamAvatar from "@/components/team-avatar";
import { useBracketPreview } from "@/features/bracket/queries";
import { BracketData } from "@/features/bracket/types";
import BracketView from "@/features/bracket/components/bracket-view";
import { useQueryClient } from "@tanstack/react-query";
import { tournamentKeys } from "../queries";
import { Trans, Plural, useLingui } from "@lingui/react/macro";

interface SeedTournamentProps {
  tournamentId: string;
  teams: TeamInfo[];
  isRegional?: boolean;
}

const SeedTournament: React.FC<SeedTournamentProps> = ({
  tournamentId,
  teams,
  isRegional,
}) => {
  const { t } = useLingui();
  const [orderedTeams, setOrderedTeams] = useState<TeamInfo[]>(teams);
  const { data: bracketPreview } = useBracketPreview(teams.length);
  const queryClient = useQueryClient();

  const bracket: BracketData = useMemo(
    () => ({
      winners: bracketPreview.winners.map((round) =>
        round.map((match) => ({
          ...match,
          away:
            match.away_seed !== undefined
              ? orderedTeams[match.away_seed - 1]
              : undefined,
          home:
            match.home_seed !== undefined
              ? orderedTeams[match.home_seed - 1]
              : undefined,
        }))
      ),
      losers: bracketPreview.losers,
    }),
    [bracketPreview, orderedTeams]
  );

  const generateBracket = useServerMutation({
    mutationFn: generateTournamentBracket,
    successMessage: t`Tournament bracket generated successfully!`,
    onSuccess: () => {
      queryClient.invalidateQueries({
        queryKey: tournamentKeys.details(tournamentId),
      });
    },
  });

  const handleDragEnd = (result: any) => {
    if (!result.destination) return;

    const items = Array.from(orderedTeams);
    const [reorderedItem] = items.splice(result.source.index, 1);
    items.splice(result.destination.index, 0, reorderedItem);

    setOrderedTeams(items);
  };

  const handleSeedChange = (teamId: string, newSeed: number) => {
    if (newSeed < 1 || newSeed > orderedTeams.length) return;

    const currentIndex = orderedTeams.findIndex((t) => t.id === teamId);
    if (currentIndex === -1) return;

    const targetIndex = newSeed - 1;
    const items = Array.from(orderedTeams);
    const [movedTeam] = items.splice(currentIndex, 1);
    items.splice(targetIndex, 0, movedTeam);

    setOrderedTeams(items);
  };

  const handleGenerateBracket = () => {
    const orderedTeamIds = orderedTeams.map((team) => team.id);

    generateBracket.mutate({
      data: {
        tournamentId,
        orderedTeamIds,
      },
    });
  };

  return (
    <div style={{ display: "flex", gap: "2rem", alignItems: "flex-start" }}>
      <Stack gap="lg" style={{ flexShrink: 0 }}>
        <Stack gap={0} pos="relative" w={400}>
          <LoadingOverlay visible={generateBracket.isPending} />

          <Group gap="xs" p="md" pb="sm" align="center">
            <Text fw={600} size="lg">
              <Trans>Team Seeding</Trans>
            </Text>
            <Text size="sm" c="dimmed" ml="auto">
              <Plural
                value={orderedTeams.length}
                one="# team"
                other="# teams"
              />
            </Text>
          </Group>

          <Button
            size="sm"
            w={400}
            onClick={handleGenerateBracket}
            loading={generateBracket.isPending}
            disabled={orderedTeams.length === 0}
          >
            <Trans>Confirm Seeding</Trans>
          </Button>

          <DragDropContext onDragEnd={handleDragEnd}>
            <Droppable droppableId="teams">
              {(provided) => (
                <div {...provided.droppableProps} ref={provided.innerRef}>
                  {orderedTeams.map((team, index) => (
                    <Draggable
                      key={team.id}
                      draggableId={team.id}
                      index={index}
                    >
                      {(provided) => (
                        <div
                          ref={provided.innerRef}
                          {...provided.draggableProps}
                          style={{
                            ...provided.draggableProps.style,
                            borderBottom:
                              "1px solid var(--mantine-color-dimmed)",
                          }}
                        >
                          <Group align="center" gap="sm" p="sm" px="md">
                            <ActionIcon
                              {...provided.dragHandleProps}
                              variant="subtle"
                              color="gray"
                              size="xs"
                            >
                              <DotsNineIcon size={14} />
                            </ActionIcon>

                            <NumberInput
                              value={index + 1}
                              onChange={(value) =>
                                handleSeedChange(team.id, Number(value) || 1)
                              }
                              min={1}
                              max={orderedTeams.length}
                              size="xs"
                              w={50}
                              styles={{
                                input: {
                                  textAlign: "center",
                                  fontWeight: 600,
                                  height: 28,
                                },
                              }}
                            />

                            <TeamAvatar
                              team={team}
                              size={24}
                              radius="sm"
                              isRegional={isRegional}
                            />

                            <Text fw={500} size="sm" style={{ flex: 1 }}>
                              {team.name}
                            </Text>
                          </Group>
                        </div>
                      )}
                    </Draggable>
                  ))}
                  {provided.placeholder}
                </div>
              )}
            </Droppable>
          </DragDropContext>
        </Stack>
        <Button
          size="sm"
          w={400}
          onClick={handleGenerateBracket}
          loading={generateBracket.isPending}
          disabled={orderedTeams.length === 0}
        >
          <Trans>Confirm Seeding</Trans>
        </Button>
      </Stack>

      <div style={{ flex: 1, overflow: "auto" }}>
        <BracketView bracket={bracket} />
      </div>
    </div>
  );
};

export default SeedTournament;
