import { ChevronLeft, ChevronRight } from "lucide-react";
import { Button } from "~/components/ui/button";
import { useRoundTransition } from "~/hooks/useRoundTransition";
import {
  TreeColumns,
  BracketMatchSlot,
  SLOT_WIDTH,
  LABEL_HEIGHT,
  DESIRED_CARD_HEIGHT,
  CARD_GAP,
  MAX_CARD_HEIGHT,
  type BracketMatch,
  type BracketOwnership,
} from "./BracketTreeView";

interface BracketTreePaginatedProps {
  rounds: string[];
  matchesByRound: Map<string, BracketMatch[]>;
  ownershipMap: Map<string, BracketOwnership>;
  userParticipantIds: Set<string>;
  /** Index of the first scoring round — default page starts here */
  firstScoringRoundIdx?: number;
  thirdPlaceRound?: string;
}

export function BracketTreePaginated({
  rounds,
  matchesByRound,
  ownershipMap,
  userParticipantIds,
  firstScoringRoundIdx,
  thirdPlaceRound,
}: BracketTreePaginatedProps) {
  const mainRounds = thirdPlaceRound ? rounds.filter((r) => r !== thirdPlaceRound) : rounds;
  const thirdPlaceMatch = thirdPlaceRound ? (matchesByRound.get(thirdPlaceRound) ?? [])[0] : undefined;

  const defaultPage = Math.max(
    0,
    Math.min(
      firstScoringRoundIdx !== undefined
        ? Math.max(0, firstScoringRoundIdx - 1)
        : mainRounds.length - 2,
      mainRounds.length - 2,
    ),
  );

  const { page, anim, stripRef, navigate, handleTransitionEnd } = useRoundTransition(
    mainRounds.length - 2,
    defaultPage,
  );

  const targetPage = anim ? anim.toPage : page;
  const labelRounds = mainRounds.slice(targetPage, targetPage + 2);
  const label = labelRounds[1] ? `${labelRounds[0]} → ${labelRounds[1]}` : labelRounds[0];

  const calcHeight = (p: number) => {
    const rs = mainRounds.slice(p, p + 2);
    const max = Math.max(...rs.map((r) => matchesByRound.get(r)?.length ?? 0), 1);
    return max * (DESIRED_CARD_HEIGHT + CARD_GAP);
  };

  const pageHeight = calcHeight(page);
  const animFromHeight = anim ? calcHeight(anim.fromPage) : pageHeight;
  const animToHeight = anim ? calcHeight(anim.toPage) : pageHeight;

  const visibleRounds = mainRounds.slice(page, page + 2);
  const fromRounds = anim ? mainRounds.slice(anim.fromPage, anim.fromPage + 2) : visibleRounds;
  const toRounds = anim ? mainRounds.slice(anim.toPage, anim.toPage + 2) : visibleRounds;

  let leftRounds: string[];
  let rightRounds: string[] = [];
  let leftHeight: number;
  let rightHeight = 0;
  let settlingTransition = false;
  if (anim?.phase === "sliding") {
    leftRounds = anim.dir === "right" ? fromRounds : toRounds;
    rightRounds = anim.dir === "right" ? toRounds : fromRounds;
    leftHeight = anim.dir === "right" ? animFromHeight : animToHeight;
    rightHeight = anim.dir === "right" ? animToHeight : animFromHeight;
  } else if (anim?.phase === "settling") {
    leftRounds = toRounds;
    leftHeight = animToHeight;
    settlingTransition = true;
  } else {
    leftRounds = visibleRounds;
    leftHeight = pageHeight;
  }

  const containerMinHeight = anim?.phase === "settling" ? animToHeight : animFromHeight;
  const initialX = anim?.phase === "sliding" && anim.dir === "left" ? -SLOT_WIDTH : 0;

  return (
    <div>
      <div className="flex items-center gap-2 mb-3">
        <Button
          variant="ghost"
          size="icon"
          onClick={() => navigate(page - 1)}
          disabled={page === 0 || !!anim}
          className="h-7 w-7 shrink-0"
          aria-label="Previous rounds"
        >
          <ChevronLeft className="h-4 w-4" />
        </Button>
        <span className="flex-1 text-center text-xs font-medium text-muted-foreground uppercase tracking-wide truncate">
          {label}
        </span>
        <Button
          variant="ghost"
          size="icon"
          onClick={() => navigate(page + 1)}
          disabled={page + 2 >= mainRounds.length || !!anim}
          className="h-7 w-7 shrink-0"
          aria-label="Next rounds"
        >
          <ChevronRight className="h-4 w-4" />
        </Button>
      </div>

      <div style={{ width: SLOT_WIDTH, overflow: "hidden", minHeight: containerMinHeight + LABEL_HEIGHT + 2, transition: settlingTransition ? "min-height 500ms ease" : undefined }}>
        <div
          ref={anim?.phase === "sliding" ? stripRef : undefined}
          style={{
            display: "flex",
            width: anim?.phase === "sliding" ? SLOT_WIDTH * 2 : SLOT_WIDTH,
            transform: anim?.phase === "sliding" ? `translateX(${initialX}px)` : undefined,
          }}
          onTransitionEnd={handleTransitionEnd}
        >
          <div style={{ width: SLOT_WIDTH, flexShrink: 0 }}>
            <TreeColumns
              visibleRounds={leftRounds}
              matchesByRound={matchesByRound}
              ownershipMap={ownershipMap}
              userParticipantIds={userParticipantIds}
              bracketHeight={leftHeight}
              transitionDuration={settlingTransition ? 500 : undefined}
            />
          </div>
          {anim?.phase === "sliding" && (
            <div style={{ width: SLOT_WIDTH, flexShrink: 0 }}>
              <TreeColumns
                visibleRounds={rightRounds}
                matchesByRound={matchesByRound}
                ownershipMap={ownershipMap}
                userParticipantIds={userParticipantIds}
                bracketHeight={rightHeight}
              />
            </div>
          )}
        </div>
      </div>

      {thirdPlaceMatch && (
        <div style={{ marginTop: 20, width: SLOT_WIDTH }}>
          <div
            className="text-[10px] font-semibold uppercase tracking-wider text-muted-foreground text-center"
            style={{ height: LABEL_HEIGHT, display: "flex", alignItems: "center", justifyContent: "center" }}
          >
            3rd Place
          </div>
          <BracketMatchSlot
            match={thirdPlaceMatch}
            slotHeight={Math.min(DESIRED_CARD_HEIGHT, MAX_CARD_HEIGHT)}
            ownershipMap={ownershipMap}
            userParticipantIds={userParticipantIds}
          />
        </div>
      )}
    </div>
  );
}
