import React, { useMemo, useState } from "react";
import { Stack, Text, Card, Group as MantineGroup, Box, SimpleGrid, Tabs, Collapse, ActionIcon, Button, Alert } from "@mantine/core";
import { CaretCircleDownIcon, CaretCircleUpIcon } from "@phosphor-icons/react";
import { Match } from "@/features/matches/types";
import { Group } from "../types";
import GroupMatchCard from "./group-match-card";
import TeamAvatar from "@/components/team-avatar";
import { useServerMutation } from "@/lib/tanstack-query/hooks/use-server-mutation";
import { populateKnockoutBracket } from "@/features/matches/server";
import { useQueryClient } from "@tanstack/react-query";
import { tournamentKeys } from "../queries";

interface GroupStageViewProps {
  groups: Group[];
  matches: Match[];
  showControls?: boolean;
  tournamentId?: string;
  hasKnockoutBracket?: boolean;
}

interface TeamStanding {
  teamId: string;
  teamName: string;
  team: any;
  wins: number;
  losses: number;
  cupsFor: number;
  cupsAgainst: number;
  cupDifference: number;
}

const GroupStageView: React.FC<GroupStageViewProps> = ({
  groups,
  matches,
  showControls,
  tournamentId,
  hasKnockoutBracket,
}) => {
  const queryClient = useQueryClient();
  const [expandedTeams, setExpandedTeams] = useState<Record<string, boolean>>({});

  const populateKnockoutMutation = useServerMutation({
    mutationFn: populateKnockoutBracket,
    successMessage: "Knockout bracket populated successfully!",
    onSuccess: () => {
      if (tournamentId) {
        queryClient.invalidateQueries({ queryKey: tournamentKeys.details(tournamentId) });
      }
    },
  });

  const allGroupMatchesCompleted = useMemo(() => {
    const groupMatches = matches.filter((match) => match.round === -1);
    if (groupMatches.length === 0) return false;
    return groupMatches.every((match) => match.status === "ended");
  }, [matches]);

  const handlePopulateKnockout = () => {
    if (!tournamentId) return;
    populateKnockoutMutation.mutate({ data: { tournamentId } });
  };

  const orderMatchesWithSpacing = (matches: Match[]): Match[] => {
    if (matches.length <= 1) return matches;

    const ordered: Match[] = [];
    const remaining = [...matches];

    ordered.push(remaining.shift()!);

    while (remaining.length > 0) {
      const lastMatch = ordered[ordered.length - 1];
      const lastTeams = new Set([lastMatch.home?.id, lastMatch.away?.id].filter(Boolean));

      let bestMatchIndex = remaining.findIndex((match) => {
        const currentTeams = new Set([match.home?.id, match.away?.id].filter(Boolean));
        for (const teamId of currentTeams) {
          if (lastTeams.has(teamId)) return false;
        }
        return true;
      });

      if (bestMatchIndex === -1) {
        bestMatchIndex = 0;
      }

      ordered.push(remaining.splice(bestMatchIndex, 1)[0]);
    }

    return ordered;
  };

  const matchesByGroup = useMemo(() => {
    const map = new Map<string, Match[]>();

    matches
      .filter((match) => match.round === -1 && match.group)
      .forEach((match) => {
        if (!map.has(match.group!)) {
          map.set(match.group!, []);
        }
        map.get(match.group!)!.push(match);
      });

    map.forEach((groupMatches, groupId) => {
      map.set(groupId, orderMatchesWithSpacing(groupMatches));
    });

    return map;
  }, [matches]);

  const sortedGroups = useMemo(() => {
    return [...groups].sort((a, b) => a.order - b.order);
  }, [groups]);

  const toggleTeams = (groupId: string) => {
    setExpandedTeams((prev) => ({
      ...prev,
      [groupId]: !prev[groupId],
    }));
  };

  const getTeamStandings = (groupId: string, teams: any[]): TeamStanding[] => {
    const groupMatches = matchesByGroup.get(groupId) || [];
    const standings: Map<string, TeamStanding> = new Map();

    teams.forEach((team) => {
      standings.set(team.id, {
        teamId: team.id,
        teamName: team.name,
        team: team,
        wins: 0,
        losses: 0,
        cupsFor: 0,
        cupsAgainst: 0,
        cupDifference: 0,
      });
    });

    groupMatches
      .filter((match) => match.status === "ended")
      .forEach((match) => {
        const homeId = match.home?.id;
        const awayId = match.away?.id;

        if (!homeId || !awayId) return;

        const homeStanding = standings.get(homeId);
        const awayStanding = standings.get(awayId);

        if (!homeStanding || !awayStanding) return;

        const homeCups = match.home_cups || 0;
        const awayCups = match.away_cups || 0;

        homeStanding.cupsFor += homeCups;
        homeStanding.cupsAgainst += awayCups;
        awayStanding.cupsFor += awayCups;
        awayStanding.cupsAgainst += homeCups;

        homeStanding.cupDifference += homeCups - awayCups;
        awayStanding.cupDifference += awayCups - homeCups;

        if (homeCups > awayCups) {
          homeStanding.wins++;
          awayStanding.losses++;
        } else if (awayCups > homeCups) {
          awayStanding.wins++;
          homeStanding.losses++;
        }
      });

    return Array.from(standings.values()).sort((a, b) => {
      if (b.wins !== a.wins) return b.wins - a.wins;
      if (b.cupDifference !== a.cupDifference) return b.cupDifference - a.cupDifference;
      return b.cupsFor - a.cupsFor;
    });
  };

  if (sortedGroups.length === 0) {
    return (
      <Box p="md">
        <Text size="sm" c="dimmed" ta="center">
          No groups have been created yet
        </Text>
      </Box>
    );
  }

  const showGenerateKnockoutButton = showControls && tournamentId && !hasKnockoutBracket && allGroupMatchesCompleted;

  return (
    <Box p="md">
      <Stack gap="md">
        {showGenerateKnockoutButton && (
          <Alert color="blue" title="Group Stage Complete" icon={<CaretCircleUpIcon size={20} />}>
            <Stack gap="xs">
              <Text size="sm">All group matches are finished! Populate the knockout bracket to advance qualified teams.</Text>
              <Button
                onClick={handlePopulateKnockout}
                loading={populateKnockoutMutation.isPending}
                size="sm"
              >
                Populate Knockout Bracket
              </Button>
            </Stack>
          </Alert>
        )}
        <Tabs defaultValue={sortedGroups[0]?.id}>
        <Tabs.List mb="md" grow>
          {sortedGroups.map((group) => {
            const groupMatches = matchesByGroup.get(group.id) || [];
            const completedMatches = groupMatches.filter((m) => m.status === "ended").length;
            const totalMatches = groupMatches.length;

            return (
              <Tabs.Tab
                key={group.id}
                value={group.id}
                style={{
                  padding: '12px 20px',
                }}
              >
                <MantineGroup gap="xs" justify="center" wrap="nowrap">
                  <Text fw={600} size="sm">Group {group.name}</Text>
                  <Text size="xs" c="dimmed" style={{ opacity: 0.7 }}>
                    ({completedMatches}/{totalMatches})
                  </Text>
                </MantineGroup>
              </Tabs.Tab>
            );
          })}
        </Tabs.List>

        {sortedGroups.map((group) => {
          const groupMatches = matchesByGroup.get(group.id) || [];
          const standings = getTeamStandings(group.id, group.teams || []);

          return (
            <Tabs.Panel key={group.id} value={group.id}>
              <Stack gap="md">
                <Card withBorder radius="md" p={0}>
                  <MantineGroup
                    justify="space-between"
                    p="sm"
                    style={{
                      cursor: 'pointer',
                      backgroundColor: 'var(--mantine-color-default-hover)',
                    }}
                    onClick={() => toggleTeams(group.id)}
                  >
                    <Text fw={600} size="sm">
                      Standings ({standings.length})
                    </Text>
                    <ActionIcon variant="subtle" size="sm">
                      {expandedTeams[group.id] ? <CaretCircleUpIcon size={16} /> : <CaretCircleDownIcon size={16} />}
                    </ActionIcon>
                  </MantineGroup>
                  <Collapse in={expandedTeams[group.id]}>
                    <Stack gap={0}>
                      {standings.length > 0 ? (
                        standings.map((standing, index) => (
                          <MantineGroup
                            key={standing.teamId}
                            gap="sm"
                            align="center"
                            wrap="nowrap"
                            px="md"
                            py="xs"
                            style={{
                              borderTop: index > 0 ? '1px solid var(--mantine-color-default-border)' : 'none',
                            }}
                          >
                            <Text size="sm" fw={700} c="dimmed" w={24} ta="center">
                              {index + 1}
                            </Text>
                            <TeamAvatar team={standing.team} size={28} radius="sm" />
                            <Text size="sm" fw={500} style={{ flex: 1 }} lineClamp={1}>
                              {standing.teamName}
                            </Text>
                            <MantineGroup gap="xs" wrap="nowrap">
                              <Text size="xs" c="dimmed" fw={500} miw={35} ta="center">
                                {standing.wins}-{standing.losses}
                              </Text>
                              <Text
                                size="xs"
                                c={standing.cupDifference > 0 ? "green" : standing.cupDifference < 0 ? "red" : "dimmed"}
                                fw={600}
                                miw={30}
                                ta="center"
                              >
                                {standing.cupDifference > 0 ? '+' : ''}{standing.cupDifference}
                              </Text>
                              <Text size="xs" c="dimmed" fw={400} miw={40} ta="center">
                                {standing.cupsFor}/{standing.cupsAgainst}
                              </Text>
                            </MantineGroup>
                          </MantineGroup>
                        ))
                      ) : (
                        <Text size="sm" c="dimmed" ta="center" py="md">
                          No teams assigned
                        </Text>
                      )}
                    </Stack>
                  </Collapse>
                </Card>

                {groupMatches.length === 0 ? (
                  <Card withBorder radius="md" p="xl">
                    <Text size="sm" c="dimmed" ta="center">
                      No matches scheduled
                    </Text>
                  </Card>
                ) : (
                  <SimpleGrid
                    cols={{ base: 1, sm: 2, lg: 3 }}
                    spacing="md"
                  >
                    {groupMatches.map((match) => (
                      <GroupMatchCard
                        key={match.id}
                        match={match}
                        showControls={showControls}
                      />
                    ))}
                  </SimpleGrid>
                )}
              </Stack>
            </Tabs.Panel>
          );
        })}
      </Tabs>
      </Stack>
    </Box>
  );
};

export default GroupStageView;
