import { cn } from "~/lib/utils";
import type { BracketPhase, ConferenceGroup } from "~/lib/bracket-templates";
import {
  TreeColumns,
  BracketTreePaginated,
  BracketMatchSlot,
  type BracketMatch,
  type BracketOwnership,
} from "./BracketTreeView";

interface TabbedBracketLayoutProps {
  rounds: string[];
  matchesByRound: Map<string, BracketMatch[]>;
  ownershipMap: Map<string, BracketOwnership>;
  userParticipantIds: Set<string>;
  phases: BracketPhase[];
  scoringRoundIdx: number;
}

const CARD_H = 112;
const CARD_GAP = 14;

function groupMatches(
  matchesByRound: Map<string, BracketMatch[]>,
  group: ConferenceGroup
): Map<string, BracketMatch[]> {
  const out = new Map<string, BracketMatch[]>();
  for (const [round, allowed] of Object.entries(group.roundMatchNumbers)) {
    const filtered = (matchesByRound.get(round) ?? []).filter((m) =>
      allowed.includes(m.matchNumber)
    );
    if (filtered.length > 0) out.set(round, filtered);
  }
  return out;
}

function phaseHeight(matchesByRound: Map<string, BracketMatch[]>, rounds: string[]): number {
  const max = Math.max(...rounds.map((r) => matchesByRound.get(r)?.length ?? 0), 1);
  return max * (CARD_H + CARD_GAP);
}

// ─── Play-In Layout ───────────────────────────────────────────────────────────

interface PlayInColumnProps {
  label: string;
  description: string;
  match: BracketMatch | undefined;
  ownershipMap: Map<string, BracketOwnership>;
  userParticipantIds: Set<string>;
}

function PlayInColumn({
  label,
  description,
  match,
  ownershipMap,
  userParticipantIds,
}: PlayInColumnProps) {
  return (
    <div>
      <p className="text-[10px] font-semibold uppercase tracking-wider text-muted-foreground text-center mb-2">
        {label}
      </p>
      {match ? (
        <BracketMatchSlot
          match={match}
          slotHeight={CARD_H}
          ownershipMap={ownershipMap}
          userParticipantIds={userParticipantIds}
        />
      ) : (
        <div style={{ height: CARD_H }} />
      )}
      <p className="text-[10px] text-muted-foreground text-center mt-2">{description}</p>
    </div>
  );
}

interface PlayInLayoutProps {
  matchesByRound: Map<string, BracketMatch[]>;
  ownershipMap: Map<string, BracketOwnership>;
  userParticipantIds: Set<string>;
}

function PlayInLayout({ matchesByRound, ownershipMap, userParticipantIds }: PlayInLayoutProps) {
  const pir1 = matchesByRound.get("Play-In Round 1") ?? [];
  const pir2 = matchesByRound.get("Play-In Round 2") ?? [];

  const conferences = [
    {
      name: "Eastern Conference",
      match78: pir1.find((m) => m.matchNumber === 1),
      match910: pir1.find((m) => m.matchNumber === 2),
      matchFor8: pir2.find((m) => m.matchNumber === 1),
    },
    {
      name: "Western Conference",
      match78: pir1.find((m) => m.matchNumber === 3),
      match910: pir1.find((m) => m.matchNumber === 4),
      matchFor8: pir2.find((m) => m.matchNumber === 2),
    },
  ];

  return (
    <div className="space-y-6">
      {conferences.map((conf) => (
        <div key={conf.name}>
          <p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground mb-3">
            {conf.name}
          </p>
          <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
            <PlayInColumn
              label="7 VS 8"
              description="Winner → 7 seed · Loser plays again"
              match={conf.match78}
              ownershipMap={ownershipMap}
              userParticipantIds={userParticipantIds}
            />
            <PlayInColumn
              label="9 VS 10"
              description="Winner plays again · Loser eliminated"
              match={conf.match910}
              ownershipMap={ownershipMap}
              userParticipantIds={userParticipantIds}
            />
            <PlayInColumn
              label="For 8 Seed"
              description="Winner → 8 seed · Loser eliminated"
              match={conf.matchFor8}
              ownershipMap={ownershipMap}
              userParticipantIds={userParticipantIds}
            />
          </div>
        </div>
      ))}
    </div>
  );
}

// ─── Main component ───────────────────────────────────────────────────────────

export function TabbedBracketLayout({
  rounds,
  matchesByRound,
  ownershipMap,
  userParticipantIds,
  phases,
  scoringRoundIdx,
}: TabbedBracketLayoutProps) {
  return (
    <div className="space-y-10">
      {phases.map((phase) => {
        const groupRounds = phase.groups
          ? rounds.filter((r) => phase.groups?.some((g) => g.roundMatchNumbers[r] !== undefined))
          : [];
        const sharedRounds = (phase.sharedRounds ?? []).filter((r) => rounds.includes(r));
        const simpleRounds = phase.groups ? [] : (phase.rounds ?? []).filter((r) => rounds.includes(r));

        const phaseRounds = phase.groups ? [...groupRounds, ...sharedRounds] : simpleRounds;
        const phaseMatchesByRound = new Map(phaseRounds.map((r) => [r, matchesByRound.get(r) ?? []]));
        const sharedMatchesByRound = new Map(sharedRounds.map((r) => [r, matchesByRound.get(r) ?? []]));

        const phaseFirstScoringIdx = phaseRounds.findIndex((r) => rounds.indexOf(r) >= scoringRoundIdx);

        return (
          <div key={phase.name}>
            <p className={cn(
              "text-sm font-semibold uppercase tracking-wider mb-4",
              phases.length > 1 ? "text-muted-foreground" : "hidden"
            )}>
              {phase.name}
            </p>

            {/* Desktop */}
            <div className="hidden md:block">
              {phase.layout === "play-in" ? (
                <PlayInLayout
                  matchesByRound={phaseMatchesByRound}
                  ownershipMap={ownershipMap}
                  userParticipantIds={userParticipantIds}
                />
              ) : phase.groups ? (
                <div className="space-y-8">
                  {phase.groups.map((group) => {
                    const gMatches = groupMatches(matchesByRound, group);
                    const gRounds = groupRounds.filter((r) => group.roundMatchNumbers[r] !== undefined);
                    return (
                      <div key={group.name}>
                        <p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground mb-2">
                          {group.name}
                        </p>
                        <TreeColumns
                          visibleRounds={gRounds}
                          matchesByRound={gMatches}
                          ownershipMap={ownershipMap}
                          userParticipantIds={userParticipantIds}
                          bracketHeight={phaseHeight(gMatches, gRounds)}
                        />
                      </div>
                    );
                  })}
                  {sharedRounds.length > 0 && (
                    <TreeColumns
                      visibleRounds={sharedRounds}
                      matchesByRound={sharedMatchesByRound}
                      ownershipMap={ownershipMap}
                      userParticipantIds={userParticipantIds}
                      bracketHeight={phaseHeight(sharedMatchesByRound, sharedRounds)}
                    />
                  )}
                </div>
              ) : (
                <TreeColumns
                  visibleRounds={phaseRounds}
                  matchesByRound={phaseMatchesByRound}
                  ownershipMap={ownershipMap}
                  userParticipantIds={userParticipantIds}
                  bracketHeight={phaseHeight(phaseMatchesByRound, phaseRounds)}
                />
              )}
            </div>

            {/* Mobile */}
            <div className="md:hidden">
              {phase.layout === "play-in" ? (
                <PlayInLayout
                  matchesByRound={phaseMatchesByRound}
                  ownershipMap={ownershipMap}
                  userParticipantIds={userParticipantIds}
                />
              ) : (
                <BracketTreePaginated
                  rounds={phaseRounds}
                  matchesByRound={phaseMatchesByRound}
                  ownershipMap={ownershipMap}
                  userParticipantIds={userParticipantIds}
                  firstScoringRoundIdx={phaseFirstScoringIdx >= 0 ? phaseFirstScoringIdx : undefined}
                />
              )}
            </div>
          </div>
        );
      })}
    </div>
  );
}
