import { useEffect } from "react";
import { Link, useSearchParams } from "react-router";
import { toast } from "sonner";
import { getAuth } from "@clerk/react-router/server";
import { addDays } from "date-fns";

import type { Route } from "./+types/home";
import { findLeaguesWithActiveSeasonsByUserId } from "~/models/league";
import { findSeasonById, findCurrentSeasonWithSports } from "~/models/season";
import { findTeamByOwnerAndSeason } from "~/models/team";
import { getDraftedParticipantsBySportsSeason } from "~/models/draft-pick";
import { getUpcomingEventsForDraftedParticipants } from "~/models/scoring-event";
import type { CalendarPanelEvent } from "~/components/sport-season/UpcomingCalendarPanel";
import { UpcomingCalendarPanel } from "~/components/sport-season/UpcomingCalendarPanel";
import { Button } from "~/components/ui/button";
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "~/components/ui/card";

export function meta() {
  return [
    { title: "Brackt - Fantasy All of the Sports!" },
    {
      name: "description",
      content: "Play multi-sport fantasy leagues with your friends!",
    },
  ];
}

export async function loader(args: Route.LoaderArgs) {
  const { userId } = await getAuth(args);

  if (!userId) {
    return { leagues: [], isLoggedIn: false, upcomingCalendarEvents: [] };
  }

  // Fetch leagues where user has a team in the current season
  const leagues = await findLeaguesWithActiveSeasonsByUserId(userId);

  const today = new Date();
  const calendarDateFrom = today;
  const calendarDateTo = addDays(today, 30);

  // Fetch season details and calendar events in parallel per league
  const leaguesWithData = await Promise.all(
    leagues.map(async (league) => {
      const [season, seasonWithSports] = await Promise.all([
        league.currentSeasonId ? findSeasonById(league.currentSeasonId) : null,
        findCurrentSeasonWithSports(league.id),
      ]);

      // Build calendar events for this league
      const calendarEvents: CalendarPanelEvent[] = [];

      if (league.currentSeasonId && seasonWithSports?.seasonSports) {
        const myTeam = await findTeamByOwnerAndSeason(userId, league.currentSeasonId);
        if (myTeam) {
          const participantsBySportsSeason = await getDraftedParticipantsBySportsSeason(
            myTeam.id,
            league.currentSeasonId
          );

          const perSeasonEvents = await Promise.all(
            seasonWithSports.seasonSports.map(async ({ sportsSeason: ss }) => {
              const draftedParticipants = participantsBySportsSeason.get(ss.id) ?? [];
              if (draftedParticipants.length === 0) return [];

              const events = await getUpcomingEventsForDraftedParticipants(
                ss.id,
                ss.scoringPattern ?? "",
                draftedParticipants,
                calendarDateFrom,
                calendarDateTo
              );

              return events.map((event) => ({
                ...event,
                sportName: ss.sport.name,
                sportSeasonName: ss.name,
                leagueName: league.name,
                leagueId: league.id,
                sportsSeasonPageUrl: `/leagues/${league.id}/sports-seasons/${ss.id}`,
              }));
            })
          );

          calendarEvents.push(...perSeasonEvents.flat());
        }
      }

      return {
        ...league,
        currentSeason: season,
        calendarEvents,
      };
    })
  );

  const upcomingCalendarEvents = leaguesWithData
    .flatMap((l) => l.calendarEvents)
    .sort((a, b) => {
      const dateA = a.eventDate ?? (a.earliestGameTime ? a.earliestGameTime.split("T")[0] : "");
      const dateB = b.eventDate ?? (b.earliestGameTime ? b.earliestGameTime.split("T")[0] : "");
      return dateA.localeCompare(dateB);
    });

  return {
    leagues: leaguesWithData,
    isLoggedIn: true,
    upcomingCalendarEvents,
  };
}

export default function Home({ loaderData }: Route.ComponentProps) {
  const { leagues, isLoggedIn, upcomingCalendarEvents } = loaderData;
  const [searchParams, setSearchParams] = useSearchParams();

  useEffect(() => {
    if (searchParams.get("deleted") === "true") {
      toast.success("League deleted successfully");
      setSearchParams({});
    }
    if (searchParams.get("left") === "true") {
      toast.success("You have left the league. Your team is now available.");
      setSearchParams({});
    }
  }, [searchParams, setSearchParams]);

  if (!isLoggedIn) {
    return (
      <div className="container mx-auto py-16 px-4 text-center">
        <h1 className="text-4xl font-bold mb-4">Welcome to Brackt</h1>
        <p className="text-xl text-muted-foreground mb-8">
          Please sign in to view your leagues
        </p>
      </div>
    );
  }

  return (
    <div className="container mx-auto py-8 px-4">
      <div className="flex items-center justify-between mb-8">
        <h1 className="text-4xl font-bold">My Leagues</h1>
        <Button asChild>
          <Link to="/leagues/new">Create New League</Link>
        </Button>
      </div>

      {upcomingCalendarEvents.length > 0 && (
        <div className="mb-8">
          <UpcomingCalendarPanel events={upcomingCalendarEvents} showLeague={true} />
        </div>
      )}

      {leagues.length === 0 ? (
        <Card>
          <CardHeader>
            <CardTitle>No Leagues</CardTitle>
            <CardDescription>
              You aren't a member of any leagues yet
            </CardDescription>
          </CardHeader>
          <CardContent>
            <Button asChild>
              <Link to="/leagues/new">Create a New League</Link>
            </Button>
          </CardContent>
        </Card>
      ) : (
        <div className="grid gap-6 md:grid-cols-2 lg:grid-cols-3">
          {leagues.map((league) => (
            <Link key={league.id} to={`/leagues/${league.id}`}>
              <Card className="hover:border-primary transition-colors cursor-pointer h-full">
                <CardHeader>
                  <CardTitle>{league.name}</CardTitle>
                  <CardDescription>
                    Created {new Date(league.createdAt).toLocaleDateString()}
                  </CardDescription>
                </CardHeader>
                <CardContent>
                  {league.currentSeason ? (
                    <div className="space-y-2">
                      <div>
                        <p className="text-sm text-muted-foreground">
                          Current Season
                        </p>
                        <p className="font-medium">
                          {league.currentSeason.year}
                        </p>
                      </div>
                      <div>
                        <p className="text-sm text-muted-foreground">Status</p>
                        <p className="font-medium capitalize">
                          {league.currentSeason.status.replace("_", " ")}
                        </p>
                      </div>
                    </div>
                  ) : (
                    <p className="text-sm text-muted-foreground">
                      No active season
                    </p>
                  )}
                </CardContent>
              </Card>
            </Link>
          ))}
        </div>
      )}
    </div>
  );
}
