import { useEffect, useRef, useState } from "react";
import { Link, useSearchParams } from "react-router";
import { toast } from "sonner";
import type { Route } from "./+types/$leagueId";

import { Link2, TriangleAlert } from "lucide-react";
import { Button } from "~/components/ui/button";
import { GradientIcon } from "~/components/ui/GradientIcon";
import { CommissionersPanel } from "~/components/league/CommissionersPanel";
import { TeamsPanel } from "~/components/league/TeamsPanel";
import { DraftInfoCard } from "~/components/league/DraftInfoCard";
import { SportsSeasonsSummary } from "~/components/league/SportsSeasonsSummary";
import { UpcomingEventsCard } from "~/components/sport-season/UpcomingEventsCard";
import { buildTiedRankChecker, getDisplayRank } from "~/lib/standings-display";
import { StandingsPreview, type StandingsPreviewEntry } from "~/components/league/StandingsPreview";
import { TimezonePromptBanner } from "~/components/league/TimezonePromptBanner";


export function meta({ data }: Route.MetaArgs): Route.MetaDescriptors {
  return [{ title: `${data?.league?.name ?? "League"} - Brackt` }];
}

export { loader } from "./$leagueId.server";

export default function LeagueHome({ loaderData }: Route.ComponentProps) {
  const {
    league,
    season,
    teams,
    commissioners,
    currentUserId,
    currentUserTimezone,
    isUserCommissioner,
    ownerMap,
    ownerAvatarDataByUserId,
    commissionerMap,
    availableTeamCount,
    sportsCount,
    isDraftOrderSet,
    draftSlots,
    sportsSeasons,
    standings,
    origin,
    upcomingCalendarEvents,
    recentActivity,
    showTimezoneBanner,
  } = loaderData;

  const myTeam = teams.find((t) => t.ownerId === currentUserId);
  // 1-based pick position; undefined if myTeam isn't in the slots (order not yet set, or no team)
  const userDraftPosition = myTeam
    ? draftSlots.findIndex((s) => s.team.id === myTeam.id) + 1 || undefined
    : undefined;
  const [searchParams, setSearchParams] = useSearchParams();
  const [copied, setCopied] = useState(false);

  // Guard against double-firing toasts (e.g. React Strict Mode double-invoke)
  const processedParamsRef = useRef<string | null>(null);
  useEffect(() => {
    const paramString = searchParams.toString();
    if (!paramString || paramString === processedParamsRef.current) return;

    if (searchParams.get("updated") === "true") {
      processedParamsRef.current = paramString;
      toast.success("Team updated successfully");
      setSearchParams({});
    } else if (searchParams.get("joined") === "true") {
      processedParamsRef.current = paramString;
      toast.success("Welcome to the league! You've been assigned a team.");
      setSearchParams({});
    } else if (searchParams.get("left") === "true") {
      processedParamsRef.current = paramString;
      toast.success("You have left the league. Your team is now available.");
      setSearchParams({});
    }
  }, [searchParams, setSearchParams]);

  const handleCopyInviteLink = async () => {
    if (!season?.inviteCode) return;

    const inviteUrl = `${origin}/i/${season.inviteCode}`;
    try {
      await navigator.clipboard.writeText(inviteUrl);
      setCopied(true);
      toast.success("Invite link copied to clipboard!");
      setTimeout(() => setCopied(false), 2000);
    } catch {
      toast.error("Failed to copy invite link");
    }
  };

  // Pre-compute standings map to avoid O(n²) lookups in render
  const standingsMap = new Map(standings.map((s) => [s.teamId, s]));

  const isTiedRank = buildTiedRankChecker(standings.map((s) => s.currentRank));

  // Pre-compute sorted standings list
  const sortedTeams = [...teams].toSorted((a, b) => {
    const rankA = standingsMap.get(a.id)?.currentRank ?? Infinity;
    const rankB = standingsMap.get(b.id)?.currentRank ?? Infinity;
    return rankA - rankB;
  });

  const standingsEntries: StandingsPreviewEntry[] = sortedTeams.map((team) => {
    const standing = standingsMap.get(team.id);
    const ownerAvatarData = team.ownerId ? (ownerAvatarDataByUserId[team.ownerId] ?? null) : null;
    return {
      teamId: team.id,
      teamName: team.name,
      ownerName: team.ownerId ? ownerMap[team.ownerId] : null,
      logoUrl: team.logoUrl,
      flagConfig: team.flagConfig,
      avatarType: team.avatarType,
      ownerAvatarData,
      displayRank: getDisplayRank(standing, standings.length, standing ? isTiedRank(standing.currentRank) : false),
      currentRank: standing?.currentRank,
      points: standing ? (standing.actualPoints ?? standing.totalPoints) : 0,
      href: season ? `/leagues/${league.id}/standings/${season.id}/teams/${team.id}` : undefined,
      rankChange: standing?.rankChange,
      pointChange: standing?.sevenDayPointChange,
    };
  });

  // Pre-compute sorted sports seasons: active → upcoming → completed,
  // season_standings last within active, then alphabetical by sport name
  const sortedSportsSeasons = [...sportsSeasons].toSorted((a, b) => {
    const statusOrder = { active: 0, upcoming: 1, completed: 2 } as const;
    const statusDiff = statusOrder[a.status] - statusOrder[b.status];
    if (statusDiff !== 0) return statusDiff;
    if (a.status === "active") {
      const aSeasonLong = a.scoringPattern === "season_standings" ? 1 : 0;
      const bSeasonLong = b.scoringPattern === "season_standings" ? 1 : 0;
      if (aSeasonLong !== bSeasonLong) return aSeasonLong - bSeasonLong;
    }
    return a.sport.name.localeCompare(b.sport.name);
  });

  const isDraftOrPreDraft = season?.status === "pre_draft" || season?.status === "draft";
  const isActiveOrCompleted = season?.status === "active" || season?.status === "completed";

  return (
    <div className="container mx-auto py-8 px-4">
      {showTimezoneBanner && <TimezonePromptBanner />}
      <div className="mb-8">
        <div className="flex flex-col sm:flex-row sm:items-start sm:justify-between gap-3">
          <div>
            <h1 className="text-4xl font-bold mb-2">{league.name}</h1>
            {season && (
              <p className="text-muted-foreground">
                {season.year} Season •{" "}
                <span className="capitalize">
                  {season.status.replace("_", " ")}
                </span>
              </p>
            )}
          </div>
          <div className="flex gap-2 shrink-0">
            {myTeam && (
              <Button variant="outline" size="sm" asChild>
                <Link to={`/teams/${myTeam.id}/settings`}>
                  Team Settings
                </Link>
              </Button>
            )}
            {isUserCommissioner && (
              <Button variant="outline" size="sm" asChild>
                <Link to={`/leagues/${league.id}/settings`}>
                  League Settings
                </Link>
              </Button>
            )}
          </div>
        </div>
      </div>

      {isUserCommissioner &&
        season?.status === "pre_draft" &&
        season.autoStartDraft &&
        !isDraftOrderSet &&
        season.draftDateTime &&
        new Date(season.draftDateTime).getTime() - Date.now() < 60 * 60 * 1000 && (
        <div className="mb-6 flex items-center justify-between gap-4 rounded-lg border border-orange-500/50 bg-orange-500/10 px-4 py-3 text-orange-700 dark:text-orange-400">
          <div className="flex items-center gap-2">
            <TriangleAlert className="h-4 w-4 shrink-0" />
            <span className="font-medium">Draft order not set.</span>
            <span className="hidden text-sm sm:inline">
              The draft is scheduled to auto-start soon but no draft order has been configured.
            </span>
          </div>
          <Button asChild size="sm" variant="outline" className="shrink-0 border-orange-500/60 text-orange-700 hover:bg-orange-500/20 dark:text-orange-400">
            <Link to={`/leagues/${league.id}/settings#draft-order`}>
              Set Draft Order
            </Link>
          </Button>
        </div>
      )}

      {season?.status === "draft" && (
        <div className="mb-6 flex items-center justify-between gap-4 rounded-lg border border-yellow-500/50 bg-yellow-500/10 px-4 py-3 text-yellow-700 dark:text-yellow-400">
          <div className="flex items-center gap-2">
            <span className="relative flex h-2.5 w-2.5 shrink-0">
              <span className="absolute inline-flex h-full w-full animate-ping rounded-full bg-yellow-500 opacity-75" />
              <span className="relative inline-flex h-2.5 w-2.5 rounded-full bg-yellow-500" />
            </span>
            <span className="font-medium">Draft is live!</span>
            <span className="hidden text-sm sm:inline">
              Your league draft is currently in progress.
            </span>
          </div>
          <Button asChild size="sm" variant="outline" className="shrink-0 border-yellow-500/60 text-yellow-700 hover:bg-yellow-500/20 dark:text-yellow-400">
            <Link to={`/leagues/${league.id}/draft/${season.id}`}>
              Enter Draft Room
            </Link>
          </Button>
        </div>
      )}

      <div className="grid gap-6 md:grid-cols-3">
        {/* Left Column - 2/3 width on desktop */}
        <div className="md:col-span-2 space-y-6">
          {/* Draft Info card - pre_draft/draft only */}
          {season && isDraftOrPreDraft && (
            <DraftInfoCard
              draftRounds={season.draftRounds}
              draftTimerMode={season.draftTimerMode}
              draftInitialTime={season.draftInitialTime}
              draftIncrementTime={season.draftIncrementTime}
              sportsCount={sportsCount}
              isDraftOrderSet={isDraftOrderSet}
              isDraftOrPreDraft={isDraftOrPreDraft}
              draftDateTime={season.draftDateTime}
              draftTimezone={currentUserTimezone ?? season.overnightPauseTimezone}
              draftBoardHref={`/leagues/${league.id}/draft-board/${season.id}`}
              draftRoomHref={`/leagues/${league.id}/draft/${season.id}`}
              queueBuilderHref={
                myTeam && season.status === "pre_draft"
                  ? `/leagues/${league.id}/draft-queue/${season.id}`
                  : undefined
              }
              userDraftPosition={userDraftPosition}
              overnightPauseMode={season.overnightPauseMode}
              overnightPauseStart={season.overnightPauseStart}
              overnightPauseEnd={season.overnightPauseEnd}
              overnightPauseTimezone={season.overnightPauseTimezone}
            />
          )}

          {/* Standings Panel - active/completed seasons */}
          {season && isActiveOrCompleted && (
            <StandingsPreview
              entries={standingsEntries}
              description={season.status === "completed" ? "Final standings" : undefined}
              fullStandingsHref={`/leagues/${league.id}/standings/${season.id}`}
            />
          )}

          {/* Sports Seasons Section */}
          {season && sortedSportsSeasons.length > 0 && (
            <SportsSeasonsSummary
              leagueId={league.id}
              sportsSeasons={sortedSportsSeasons.map((ss) => ({
                id: ss.id,
                sportName: ss.sport.name,
                sportIconUrl: ss.sport.iconUrl,
                seasonName: ss.name,
                status: ss.status,
                scoringPattern: ss.scoringPattern,
                upcomingParticipantEvents: ss.upcomingParticipantEvents,
                draftedParticipants: ss.draftedParticipantsWithPoints,
              }))}
            />
          )}

        </div>

        {/* Right Column - 1/3 width on desktop */}
        <div className="space-y-14">
          {/* Teams - shown above invite link when league is full */}
          {season && isDraftOrPreDraft && availableTeamCount === 0 && (
            <TeamsPanel teams={teams} currentUserId={currentUserId} ownerMap={ownerMap} draftSlots={draftSlots} />
          )}

          {/* Invite Link - bare, pre_draft commissioner only */}
          {isUserCommissioner && season?.status === "pre_draft" && availableTeamCount > 0 && (
            <div>
              <div className="flex items-center gap-2 mb-4">
                <GradientIcon icon={Link2} className="h-5 w-5 shrink-0" />
                <span className="text-xl font-bold leading-none tracking-tight">Invite Link</span>
              </div>
              <div className="space-y-2">
                <p className="text-sm text-muted-foreground">
                  {availableTeamCount} spot{availableTeamCount !== 1 ? "s" : ""} remaining
                </p>
                <div className="flex items-center gap-2">
                  <input
                    type="text"
                    readOnly
                    value={`${origin}/i/${season.inviteCode}`}
                    className="flex-1 px-3 py-2 text-sm border rounded-md bg-muted"
                    onClick={(e) => e.currentTarget.select()}
                  />
                  <Button
                    onClick={handleCopyInviteLink}
                    variant={copied ? "default" : "outline"}
                    size="sm"
                  >
                    {copied ? "Copied!" : "Copy"}
                  </Button>
                </div>
                <p className="text-xs text-muted-foreground">
                  Anyone with this link can join your league
                </p>
              </div>
            </div>
          )}

          {/* Teams - shown below invite link when league is not full */}
          {season && isDraftOrPreDraft && availableTeamCount > 0 && (
            <TeamsPanel teams={teams} currentUserId={currentUserId} ownerMap={ownerMap} draftSlots={draftSlots} />
          )}

          {upcomingCalendarEvents.length > 0 && (
            <UpcomingEventsCard
              events={upcomingCalendarEvents}
              title="Upcoming Events"
              limit={6}
              viewAllUrl={`/leagues/${league.id}/upcoming-events`}
              showLeagueAvatar={false}
            />
          )}

          {/* Draft historical view - active/completed/draft */}
          {season && (isActiveOrCompleted || season.status === "draft") && (
            <DraftInfoCard
              draftRounds={season.draftRounds}
              draftTimerMode={season.draftTimerMode}
              draftInitialTime={season.draftInitialTime}
              draftIncrementTime={season.draftIncrementTime}
              sportsCount={sportsCount}
              isDraftOrderSet={isDraftOrderSet}
              isDraftOrPreDraft={false}
              draftDateTime={season.draftDateTime}
              draftTimezone={currentUserTimezone ?? season.overnightPauseTimezone}
              draftBoardHref={`/leagues/${league.id}/draft-board/${season.id}`}
              draftRoomHref={`/leagues/${league.id}/draft/${season.id}`}
            />
          )}

          <CommissionersPanel
            commissioners={commissioners}
            commissionerMap={commissionerMap}
            currentUserId={currentUserId}
            teams={teams}
            activityEntries={recentActivity.entries}
            auditLogUrl={`/leagues/${league.id}/audit-log`}
          />
        </div>
      </div>
    </div>
  );
}
