import { createFileRoute, redirect } from "@tanstack/react-router";
import {
  tournamentQueries,
  useTournament,
} from "@/features/tournaments/queries";
import { ensureServerQueryData } from "@/lib/tanstack-query/utils/ensure";
import { Container } from "@mantine/core";
import { useMemo } from "react";
import { BracketData } from "@/features/bracket/types";
import { Match } from "@/features/matches/types";
import BracketView from "@/features/bracket/components/bracket-view";

export const Route = createFileRoute("/_authed/tournaments/$id/bracket")({
  beforeLoad: async ({ context, params }) => {
    const { queryClient } = context;
    const tournament = await ensureServerQueryData(
      queryClient,
      tournamentQueries.details(params.id)
    );
    if (!tournament) throw redirect({ to: "/tournaments" });
    return {
      tournament,
    };
  },
  loader: ({ context }) => ({
    fullWidth: true,
    withPadding: false,
    header: {
      withBackButton: true,
      title: `${context.tournament.name} - Bracket`,
    },
  }),
  component: RouteComponent,
});

function RouteComponent() {
  const { id } = Route.useParams();
  const { data: tournament } = useTournament(id);

  const bracket: BracketData = useMemo(() => {
    if (!tournament.matches || tournament.matches.length === 0) {
      return { winners: [], losers: [] };
    }

    const winnersMap = new Map<number, Match[]>();
    const losersMap = new Map<number, Match[]>();

    tournament.matches
      .filter((match) => match.round !== -1)
      .sort((a, b) => a.lid - b.lid)
      .forEach((match) => {
        if (!match.is_losers_bracket) {
          if (!winnersMap.has(match.round)) {
            winnersMap.set(match.round, []);
          }
          winnersMap.get(match.round)!.push(match);
        } else {
          if (!losersMap.has(match.round)) {
            losersMap.set(match.round, []);
          }
          losersMap.get(match.round)!.push(match);
        }
      });

    const winners = Array.from(winnersMap.entries())
      .sort(([a], [b]) => a - b)
      .map(([, matches]) => matches);

    const losers = Array.from(losersMap.entries())
      .sort(([a], [b]) => a - b)
      .map(([, matches]) => matches);
    return { winners, losers };
  }, [tournament.matches]);

  return (
    <Container size="md" px={0}>
      <BracketView bracket={bracket} groupConfig={tournament.group_config} />
    </Container>
  );
}
