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

interface NbaBracketLayoutProps {
  matches: Array<{ round: string; matchNumber: number }>;
  rounds: string[];
  matchesByRound: Map<string, BracketMatch[]>;
  ownershipMap: Map<string, BracketOwnership>;
  userParticipantIds: Set<string>;
  conferenceGroups: ConferenceGroup[];
  scoringRoundIdx: number;
}

const DESIRED_CARD_HEIGHT = 112;
const CARD_GAP = 14;

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

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

export function NbaBracketLayout({
  rounds,
  matchesByRound,
  ownershipMap,
  userParticipantIds,
  conferenceGroups,
  scoringRoundIdx,
}: NbaBracketLayoutProps) {
  // Rounds that belong to any conference group
  const conferenceRoundSet = new Set(
    conferenceGroups.flatMap((g) => Object.keys(g.roundMatchNumbers))
  );
  // Rounds not in any group are shared (e.g. NBA Finals)
  const sharedRounds = rounds.filter((r) => !conferenceRoundSet.has(r));

  // Per-conference round lists (preserving template order)
  const conferenceRounds = conferenceGroups.map((g) =>
    rounds.filter((r) => g.roundMatchNumbers[r] !== undefined)
  );

  // Shared rounds bracket height
  const sharedMatches = new Map(
    sharedRounds.map((r) => [r, matchesByRound.get(r) ?? []])
  );
  const sharedHeight = bracketHeight(sharedMatches, sharedRounds);

  return (
    <>
      {/* ── Desktop: two-conference stacked layout ── */}
      <div className="hidden md:flex md:flex-col md:gap-8">
        {conferenceGroups.map((group, gi) => {
          const confRounds = conferenceRounds[gi];
          const confMatches = splitMatchesByConference(matchesByRound, group);
          const height = bracketHeight(confMatches, confRounds);

          return (
            <div key={group.name}>
              <p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground mb-2">
                {group.name}
              </p>
              <TreeColumns
                visibleRounds={confRounds}
                matchesByRound={confMatches}
                ownershipMap={ownershipMap}
                userParticipantIds={userParticipantIds}
                bracketHeight={height}
              />
            </div>
          );
        })}

        {sharedRounds.length > 0 && (
          <div>
            <TreeColumns
              visibleRounds={sharedRounds}
              matchesByRound={sharedMatches}
              ownershipMap={ownershipMap}
              userParticipantIds={userParticipantIds}
              bracketHeight={sharedHeight}
            />
          </div>
        )}
      </div>

      {/* ── Mobile: paginated across all rounds ── */}
      <div className="md:hidden">
        <BracketTreePaginated
          rounds={rounds}
          matchesByRound={matchesByRound}
          ownershipMap={ownershipMap}
          userParticipantIds={userParticipantIds}
          firstScoringRoundIdx={scoringRoundIdx}
        />
      </div>
    </>
  );
}
