import { Link } from "react-router";
import { ArrowRight, Trophy } from "lucide-react";

import type { Route } from "./+types/sports";
import { Button } from "~/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "~/components/ui/card";
import { SportIcon } from "~/components/SportIcon";
import {
  findPublicSportsWithCurrentSeasons,
  type PublicSportWithCurrentSeasons,
} from "~/models/sport";

export function meta(): Route.MetaDescriptors {
  return [
    { title: "Sports - Brackt" },
    {
      name: "description",
      content: "Explore the sports currently supported on Brackt.",
    },
  ];
}

export async function loader() {
  const sports = await findPublicSportsWithCurrentSeasons();
  return { sports };
}

function pluralize(count: number, singular: string, plural = `${singular}s`) {
  return `${count} ${count === 1 ? singular : plural}`;
}

type SportGroupKey = "playoffs" | "standings" | "majors";

const SPORT_GROUPS: Array<{
  key: SportGroupKey;
  title: string;
  description: string;
}> = [
  {
    key: "playoffs",
    title: "Playoffs",
    description: "Bracket and postseason formats where advancement drives scoring.",
  },
  {
    key: "standings",
    title: "Season-Long Standings",
    description: "Full-season tables, races, and standings-based competitions.",
  },
  {
    key: "majors",
    title: "Majors",
    description: "Major tournaments and qualifying-points formats.",
  },
];

function seasonGroupKey(
  season: PublicSportWithCurrentSeasons["currentSeasons"][number]
): SportGroupKey {
  if (season.scoringPattern === "season_standings" || season.scoringType === "regular_season") {
    return "standings";
  }
  if (season.scoringPattern === "qualifying_points" || season.scoringType === "majors") {
    return "majors";
  }
  return "playoffs";
}

function sportGroupKey(sport: PublicSportWithCurrentSeasons): SportGroupKey {
  const keys = sport.currentSeasons.map(seasonGroupKey);
  return SPORT_GROUPS.find((group) => keys.includes(group.key))?.key ?? "playoffs";
}

function SportCard({ sport }: { sport: PublicSportWithCurrentSeasons }) {
  const fallbackDescription = "Available for Brackt leagues.";

  return (
    <Card className="h-full gap-3 transition-colors hover:bg-card/80">
      <CardHeader className="pb-0">
        <div className="flex items-start gap-4">
          <div className="flex h-14 w-14 shrink-0 items-center justify-center rounded-md border border-border/70 bg-background/60">
            <SportIcon
              sportName={sport.name}
              iconUrl={sport.iconUrl}
              size="lg"
              className="h-10 w-10"
            />
          </div>
          <div className="min-w-0 flex-1">
            <CardTitle className="truncate text-xl">{sport.name}</CardTitle>
            <p className="mt-1 text-sm capitalize text-muted-foreground">
              {sport.type} sport · {pluralize(sport.currentSeasons.length, "current season")}
            </p>
          </div>
        </div>
      </CardHeader>
      <CardContent>
        <p className="text-sm leading-6 text-muted-foreground">
          {sport.description || fallbackDescription}
        </p>
      </CardContent>
    </Card>
  );
}

function SportSection({
  title,
  description,
  sports,
}: {
  title: string;
  description: string;
  sports: PublicSportWithCurrentSeasons[];
}) {
  if (sports.length === 0) return null;

  return (
    <section className="space-y-4">
      <div>
        <h2 className="text-2xl font-bold">{title}</h2>
        <p className="mt-1 text-sm text-muted-foreground">
          {description} {pluralize(sports.length, "sport")} available.
        </p>
      </div>
      <div className="grid gap-4 md:grid-cols-2 xl:grid-cols-3">
        {sports.map((sport) => (
          <SportCard key={sport.id} sport={sport} />
        ))}
      </div>
    </section>
  );
}

export default function Sports({ loaderData }: Route.ComponentProps) {
  const { sports } = loaderData;
  const groupedSports = new Map<SportGroupKey, PublicSportWithCurrentSeasons[]>();
  for (const group of SPORT_GROUPS) groupedSports.set(group.key, []);
  for (const sport of sports) {
    groupedSports.get(sportGroupKey(sport))?.push(sport);
  }

  return (
    <div className="container mx-auto max-w-6xl px-4 py-10">
      <div className="mb-10 max-w-3xl">
        <h1 className="text-4xl font-extrabold tracking-tight sm:text-5xl">Sports</h1>
        <p className="mt-4 text-lg leading-8 text-muted-foreground">
          Brackt currently supports {pluralize(sports.length, "sport")} with active
          or upcoming seasons, and we&apos;re adding more.
        </p>
      </div>

      {sports.length === 0 ? (
        <div className="rounded-md border border-border/70 p-10 text-center">
          <Trophy className="mx-auto h-12 w-12 text-muted-foreground" />
          <h2 className="mt-4 text-xl font-semibold">No sports are listed yet</h2>
          <p className="mx-auto mt-2 max-w-md text-muted-foreground">
            Active and upcoming sports will appear here once they are available.
          </p>
        </div>
      ) : (
        <div className="space-y-12">
          {SPORT_GROUPS.map((group) => (
            <SportSection
              key={group.key}
              title={group.title}
              description={group.description}
              sports={groupedSports.get(group.key) ?? []}
            />
          ))}
        </div>
      )}

      <section className="mt-12 rounded-md border border-border/70 bg-card/40 p-5 sm:flex sm:items-center sm:justify-between sm:gap-6">
        <div>
          <h2 className="font-semibold">Want to see another sport on Brackt?</h2>
          <p className="mt-1 text-sm text-muted-foreground">
            Tell us what should be next and we&apos;ll take a look.
          </p>
        </div>
        <Button asChild variant="outline" className="mt-4 sm:mt-0">
          <Link to="/support">
            Contact support
            <ArrowRight className="ml-2 h-4 w-4" />
          </Link>
        </Button>
      </section>
    </div>
  );
}
