import { useState } from "react";
import { Link } from "react-router";
import { ArrowUp, ArrowDown, ArrowUpDown } from "lucide-react";
import { Button } from "~/components/ui/button";
import { Card, CardContent } from "~/components/ui/card";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "~/components/ui/select";
import { Table, TableHeader, TableRow, TableHead, TableBody, TableCell } from "~/components/ui/table";
import { Badge } from "~/components/ui/badge";

interface TeamScoreBreakdownProps {
  leagueId: string;
  seasonId: string;
  numTeams: number;
  breakdown: {
    team: {
      id: string;
      name: string;
    } | null;
    picks: Array<{
      pickNumber: number;
      round: number;
      participant: {
        id: string;
        name: string;
        sport: string;
        sportsSeasonId: string;
      };
      finalPosition: number | null;
      points: number;
      projectedPoints: number | null;
      isComplete: boolean;
      isPartialScore: boolean;
    }>;
    actualPoints: number;
    projectedPoints: number;
    completedCount: number;
    totalCount: number;
  };
  standing: {
    currentRank: number;
  } | null;
}

type SortColumn = "pick" | "points" | "sport" | "participant";
type SortDirection = "asc" | "desc";

function SortIndicator({ column, sortColumn, sortDirection }: { column: SortColumn; sortColumn: SortColumn; sortDirection: SortDirection }) {
  if (sortColumn !== column) return <ArrowUpDown className="ml-1 h-3 w-3 text-muted-foreground/40" />;
  return sortDirection === "asc"
    ? <ArrowUp className="ml-1 h-3 w-3" />
    : <ArrowDown className="ml-1 h-3 w-3" />;
}

function SortableHeader({ column, label, sortColumn, sortDirection, onSort, className }: {
  column: SortColumn;
  label: string;
  sortColumn: SortColumn;
  sortDirection: SortDirection;
  onSort: (column: SortColumn) => void;
  className?: string;
}) {
  return (
    <button
      onClick={() => onSort(column)}
      aria-sort={sortColumn === column ? (sortDirection === "asc" ? "ascending" : "descending") : "none"}
      className={`flex items-center hover:text-foreground cursor-pointer ${className ?? ""}`}
    >
      {label}<SortIndicator column={column} sortColumn={sortColumn} sortDirection={sortDirection} />
    </button>
  );
}

const cmp = (a: string, b: string) => a.localeCompare(b, undefined, { sensitivity: "base" });

function sortPicks(
  picks: TeamScoreBreakdownProps["breakdown"]["picks"],
  sortColumn: SortColumn,
  sortDirection: SortDirection,
) {
  const dir = sortDirection === "asc" ? 1 : -1;
  return picks.toSorted((a, b) => {
    if (sortColumn === "pick") {
      return (a.pickNumber - b.pickNumber) * dir;
    }
    if (sortColumn === "sport") {
      const sportCmp = cmp(a.participant.sport, b.participant.sport) * dir;
      if (sportCmp !== 0) return sportCmp;
      return cmp(a.participant.name, b.participant.name) * dir;
    }
    if (sortColumn === "participant") {
      return cmp(a.participant.name, b.participant.name) * dir;
    }
    // points: sort by actual first, then projected
    const pointsDiff = a.points - b.points;
    if (pointsDiff !== 0) return pointsDiff * dir;
    const aProjected = a.projectedPoints ?? 0;
    const bProjected = b.projectedPoints ?? 0;
    return (aProjected - bProjected) * dir;
  });
}

type Pick = TeamScoreBreakdownProps["breakdown"]["picks"][number];

const SORT_OPTIONS: Array<{ value: SortColumn; label: string }> = [
  { value: "pick", label: "Pick #" },
  { value: "sport", label: "Sport" },
  { value: "participant", label: "Participant" },
  { value: "points", label: "Points" },
];

function pickLabel(pick: Pick, numTeams: number): string {
  return numTeams > 0
    ? `${pick.round}.${String(pick.pickNumber - (pick.round - 1) * numTeams).padStart(2, "0")}`
    : `#${pick.pickNumber}`;
}

/** Position badge shared by the desktop table and the mobile cards. */
function PositionCell({ pick }: { pick: Pick }) {
  if (pick.isComplete && !pick.isPartialScore) {
    return (pick.finalPosition ?? 0) === 0 ? (
      <Badge variant="secondary">Did Not Score</Badge>
    ) : (
      <PlacementBadge position={pick.finalPosition ?? 0} />
    );
  }
  return <Badge variant="outline">Pending</Badge>;
}

/** Points value (actual, with projected underneath when incomplete). */
function PointsValue({ pick }: { pick: Pick }) {
  if (pick.isComplete && !pick.isPartialScore) {
    return (
      <span className="font-semibold">
        {pick.points > 0 ? pick.points.toFixed(2) : "0.00"}
      </span>
    );
  }
  return (
    <div className="flex flex-col items-end">
      <span className="font-semibold">{pick.points.toFixed(2)}</span>
      {pick.projectedPoints !== null && (
        <span className="text-xs text-muted-foreground">
          {pick.projectedPoints.toFixed(2)}
        </span>
      )}
    </div>
  );
}

/**
 * Display detailed team score breakdown with all drafted participants
 * Phase 4.3: Team breakdown pages
 */
export function TeamScoreBreakdown({
  leagueId,
  seasonId,
  numTeams,
  breakdown,
  standing,
}: TeamScoreBreakdownProps) {
  const [sortColumn, setSortColumn] = useState<SortColumn>("pick");
  const [sortDirection, setSortDirection] = useState<SortDirection>("asc");

  if (!breakdown.team) {
    return (
      <div className="text-center text-muted-foreground py-8">
        Team not found
      </div>
    );
  }

  const remaining = breakdown.totalCount - breakdown.completedCount;

  function handleSort(column: SortColumn) {
    if (sortColumn === column) {
      setSortDirection(sortDirection === "asc" ? "desc" : "asc");
    } else {
      setSortColumn(column);
      setSortDirection(column === "points" ? "desc" : "asc");
    }
  }

  // Mobile sort control: picking a column applies its default direction.
  function handleSortColumn(column: SortColumn) {
    setSortColumn(column);
    setSortDirection(column === "points" ? "desc" : "asc");
  }

  const allPicks = sortPicks(breakdown.picks, sortColumn, sortDirection);

  return (
    <div className="space-y-6">
      {/* Header */}
      <div className="flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between">
        <div>
          <h1 className="text-2xl sm:text-3xl font-bold">{breakdown.team.name}</h1>
          <p className="text-muted-foreground mt-1">Team Score Breakdown</p>
        </div>
        <div className="text-left sm:text-right">
          <div className="text-4xl font-bold text-primary">
            {breakdown.actualPoints.toFixed(2)}
          </div>
          <div className="text-sm text-muted-foreground">Actual Points</div>
          {breakdown.projectedPoints > breakdown.actualPoints && (
            <div className="text-xl font-semibold text-electric mt-1">
              {breakdown.projectedPoints.toFixed(2)}
              <span className="text-xs text-muted-foreground ml-1">projected</span>
            </div>
          )}
          {remaining > 0 && (
            <div className="text-sm text-muted-foreground mt-1">
              {remaining} participant{remaining !== 1 ? "s" : ""} remaining
            </div>
          )}
          {standing && (
            <Badge className="mt-2" variant={standing.currentRank <= 3 ? "default" : "outline"}>
              Rank #{standing.currentRank}
            </Badge>
          )}
        </div>
      </div>

      {/* All picks — desktop table */}
      <Card className="hidden md:block">
        <CardContent className="pt-4">
          <Table>
            <TableHeader>
              <TableRow>
                <TableHead className="min-w-[90px]">
                  <SortableHeader column="pick" label="Pick #" sortColumn={sortColumn} sortDirection={sortDirection} onSort={handleSort} />
                </TableHead>
                <TableHead>
                  <SortableHeader column="sport" label="Sport" sortColumn={sortColumn} sortDirection={sortDirection} onSort={handleSort} />
                </TableHead>
                <TableHead>
                  <SortableHeader column="participant" label="Participant" sortColumn={sortColumn} sortDirection={sortDirection} onSort={handleSort} />
                </TableHead>
                <TableHead className="text-center">Position</TableHead>
                <TableHead className="text-right">
                  <button
                    onClick={() => handleSort("points")}
                    aria-sort={sortColumn === "points" ? (sortDirection === "asc" ? "ascending" : "descending") : "none"}
                    className="flex flex-col items-end ml-auto hover:text-foreground cursor-pointer"
                  >
                    <div className="flex items-center">
                      Points<SortIndicator column="points" sortColumn={sortColumn} sortDirection={sortDirection} />
                    </div>
                    <div className="text-xs font-normal text-muted-foreground">actual / projected</div>
                  </button>
                </TableHead>
              </TableRow>
            </TableHeader>
            <TableBody>
              {allPicks.map((pick) => (
                <TableRow key={pick.pickNumber}>
                  <TableCell className="text-muted-foreground">
                    {pickLabel(pick, numTeams)}
                    <span className="text-xs ml-1">(#{pick.pickNumber})</span>
                  </TableCell>
                  <TableCell>
                    <Link
                      to={`/leagues/${leagueId}/sports-seasons/${pick.participant.sportsSeasonId}`}
                      className="text-sm font-medium hover:underline text-primary"
                    >
                      {pick.participant.sport}
                    </Link>
                  </TableCell>
                  <TableCell className="font-medium">
                    {pick.participant.name}
                  </TableCell>
                  <TableCell className="text-center">
                    <PositionCell pick={pick} />
                  </TableCell>
                  <TableCell className="text-right">
                    <PointsValue pick={pick} />
                  </TableCell>
                </TableRow>
              ))}
            </TableBody>
          </Table>
        </CardContent>
      </Card>

      {/* All picks — mobile cards (no horizontal scroll, all fields visible) */}
      <div className="md:hidden space-y-3" data-testid="picks-mobile">
        {/* Sort control */}
        <div className="flex items-center gap-2">
          <span id="picks-sort-label" className="text-sm text-muted-foreground shrink-0">
            Sort by
          </span>
          <Select
            value={sortColumn}
            onValueChange={(v) => handleSortColumn(v as SortColumn)}
          >
            <SelectTrigger className="flex-1" aria-labelledby="picks-sort-label">
              <SelectValue />
            </SelectTrigger>
            <SelectContent>
              {SORT_OPTIONS.map((opt) => (
                <SelectItem key={opt.value} value={opt.value}>
                  {opt.label}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
          <Button
            variant="outline"
            size="icon"
            onClick={() => setSortDirection(sortDirection === "asc" ? "desc" : "asc")}
            aria-label={`Sort ${sortDirection === "asc" ? "descending" : "ascending"}`}
          >
            {sortDirection === "asc" ? (
              <ArrowUp className="h-4 w-4" />
            ) : (
              <ArrowDown className="h-4 w-4" />
            )}
          </Button>
        </div>

        {allPicks.map((pick) => (
          <Card key={pick.pickNumber} className="py-0" data-testid="pick-card">
            <CardContent className="p-3 space-y-2">
              <div className="flex items-start justify-between gap-2">
                <div className="text-sm text-muted-foreground">
                  {pickLabel(pick, numTeams)}
                  <span className="text-xs ml-1">(#{pick.pickNumber})</span>
                </div>
                <PositionCell pick={pick} />
              </div>
              <div className="min-w-0">
                <div className="font-medium break-words">{pick.participant.name}</div>
                <Link
                  to={`/leagues/${leagueId}/sports-seasons/${pick.participant.sportsSeasonId}`}
                  className="text-sm font-medium hover:underline text-primary"
                >
                  {pick.participant.sport}
                </Link>
              </div>
              <div className="flex items-baseline justify-between border-t border-border/30 pt-2">
                <span className="text-sm text-muted-foreground">Points</span>
                <PointsValue pick={pick} />
              </div>
            </CardContent>
          </Card>
        ))}
      </div>

      {/* Navigation */}
      <div className="flex justify-between pt-4">
        <Link
          to={`/leagues/${leagueId}/standings/${seasonId}`}
          className="inline-flex items-center text-sm text-muted-foreground hover:text-foreground"
        >
          ← Back to Standings
        </Link>
      </div>
    </div>
  );
}

/**
 * Display placement badge with color coding
 */
function PlacementBadge({ position }: { position: number }) {
  const badges: Record<number, { label: string; className: string }> = {
    1: { label: "1st", className: "bg-amber-accent hover:bg-amber-accent/80 text-background" },
    2: { label: "2nd", className: "bg-muted hover:bg-muted/80 text-muted-foreground" },
    3: { label: "3rd", className: "bg-coral-accent hover:bg-coral-accent/80 text-background" },
    4: { label: "4th", className: "bg-electric/20 hover:bg-electric/30 text-electric" },
    5: { label: "5th", className: "bg-purple-500/20 hover:bg-purple-500/30 text-purple-400" },
    6: { label: "6th", className: "bg-emerald-500/20 hover:bg-emerald-500/30 text-emerald-400" },
    7: { label: "7th", className: "bg-pink-500/20 hover:bg-pink-500/30 text-pink-400" },
    8: { label: "8th", className: "bg-indigo-500/20 hover:bg-indigo-500/30 text-indigo-400" },
  };

  const badge = badges[position] || { label: `${position}th`, className: "" };

  return (
    <Badge className={badge.className}>
      {badge.label}
    </Badge>
  );
}
