import { describe, it, expect } from "vitest";
import { render, screen } from "@testing-library/react";
import { BrowserRouter } from "react-router";
import { StandingsTable } from "../StandingsTable";
import { type TeamStanding } from "~/models/standings";

// Helper to wrap component with router context
function renderWithRouter(ui: React.ReactElement) {
  return render(<BrowserRouter>{ui}</BrowserRouter>);
}

/**
 * StandingsTable Component Tests
 * Phase 4.1: Test standings display with tiebreakers and placement breakdown
 * Phase 4.3: Added tests for clickable team links
 */
describe("StandingsTable", () => {
  const mockLeagueId = "league-123";
  const mockSeasonId = "season-456";

  const mockStandings: TeamStanding[] = [
    {
      teamId: "team1",
      teamName: "Champions United",
      totalPoints: 250.5,
      currentRank: 1,
      previousRank: 2,
      rankChange: 1, // Moved up
      placementCounts: {
        first: 2,
        second: 1,
        third: 0,
        fourth: 1,
        fifth: 0,
        sixth: 0,
        seventh: 0,
        eighth: 1,
      },
      participantsRemaining: 3,
      calculatedAt: new Date(),
    },
    {
      teamId: "team2",
      teamName: "Second Place Squad",
      totalPoints: 245.0,
      currentRank: 2,
      previousRank: 1,
      rankChange: -1, // Moved down
      placementCounts: {
        first: 1,
        second: 2,
        third: 1,
        fourth: 0,
        fifth: 1,
        sixth: 0,
        seventh: 0,
        eighth: 0,
      },
      participantsRemaining: 0,
      calculatedAt: new Date(),
    },
    {
      teamId: "team3",
      teamName: "Bronze Warriors",
      totalPoints: 200.0,
      currentRank: 3,
      previousRank: 3,
      rankChange: 0, // No change
      placementCounts: {
        first: 0,
        second: 1,
        third: 2,
        fourth: 1,
        fifth: 0,
        sixth: 0,
        seventh: 0,
        eighth: 0,
      },
      participantsRemaining: 5,
      calculatedAt: new Date(),
    },
  ];

  describe("Basic Rendering", () => {
    it("should render standings table with all teams", () => {
      renderWithRouter(<StandingsTable standings={mockStandings} leagueId={mockLeagueId} seasonId={mockSeasonId} />);

      expect(screen.getByText("Champions United")).toBeInTheDocument();
      expect(screen.getByText("Second Place Squad")).toBeInTheDocument();
      expect(screen.getByText("Bronze Warriors")).toBeInTheDocument();
    });

    it("should display total points for each team", () => {
      renderWithRouter(<StandingsTable standings={mockStandings} leagueId={mockLeagueId} seasonId={mockSeasonId} />);

      expect(screen.getByText("250.5")).toBeInTheDocument();
      expect(screen.getByText("245.0")).toBeInTheDocument();
      expect(screen.getByText("200.0")).toBeInTheDocument();
    });

    it("should show empty state when no standings", () => {
      renderWithRouter(<StandingsTable standings={[]} leagueId={mockLeagueId} seasonId={mockSeasonId} />);

      expect(screen.getByText("No standings data available")).toBeInTheDocument();
    });
  });

  describe("Rank Badges", () => {
    it("should show trophy icon for 1st place", () => {
      renderWithRouter(<StandingsTable standings={mockStandings} leagueId={mockLeagueId} seasonId={mockSeasonId} />);

      expect(screen.getByText(/🏆.*1st/)).toBeInTheDocument();
    });

    it("should show silver medal icon for 2nd place", () => {
      renderWithRouter(<StandingsTable standings={mockStandings} leagueId={mockLeagueId} seasonId={mockSeasonId} />);

      expect(screen.getByText(/🥈.*2nd/)).toBeInTheDocument();
    });

    it("should show bronze medal icon for 3rd place", () => {
      renderWithRouter(<StandingsTable standings={mockStandings} leagueId={mockLeagueId} seasonId={mockSeasonId} />);

      expect(screen.getByText(/🥉.*3rd/)).toBeInTheDocument();
    });

    it("should show plain rank for 4th place and below", () => {
      const standings: TeamStanding[] = [
        {
          ...mockStandings[0],
          currentRank: 4,
          teamName: "Fourth Place",
        },
      ];

      renderWithRouter(<StandingsTable standings={standings} leagueId={mockLeagueId} seasonId={mockSeasonId} />);

      // Should not have emoji, just the number
      const badge = screen.getByText("4");
      expect(badge).toBeInTheDocument();
    });
  });

  describe("Movement Indicators", () => {
    it("should show up arrow for positive rank change", () => {
      renderWithRouter(<StandingsTable standings={mockStandings} leagueId={mockLeagueId} seasonId={mockSeasonId} />);

      expect(screen.getByText("↑1")).toBeInTheDocument();
    });

    it("should show down arrow for negative rank change", () => {
      renderWithRouter(<StandingsTable standings={mockStandings} leagueId={mockLeagueId} seasonId={mockSeasonId} />);

      expect(screen.getByText("↓1")).toBeInTheDocument();
    });

    it("should not show indicator for no rank change", () => {
      renderWithRouter(<StandingsTable standings={mockStandings} leagueId={mockLeagueId} seasonId={mockSeasonId} />);

      // Third team has no change, so no arrow
      const arrows = screen.queryAllByText(/↑|↓/);
      expect(arrows).toHaveLength(2); // Only first two teams
    });
  });

  describe("Placement Breakdown", () => {
    it("should display placement counts", () => {
      const singleTeam: TeamStanding[] = [
        {
          teamId: "team1",
          teamName: "Test Team",
          totalPoints: 250,
          currentRank: 1,
          previousRank: null,
          rankChange: 0,
          placementCounts: {
            first: 2,
            second: 1,
            third: 0,
            fourth: 1,
            fifth: 0,
            sixth: 0,
            seventh: 0,
            eighth: 1,
          },
          participantsRemaining: 0,
          calculatedAt: new Date(),
        },
      ];

      renderWithRouter(<StandingsTable standings={singleTeam} leagueId={mockLeagueId} seasonId={mockSeasonId} showPlacementBreakdown={true} />);

      // Test Team: 2 firsts, 1 second, 1 fourth, 1 eighth
      expect(screen.getByText("1st×2")).toBeInTheDocument();
      expect(screen.getByText("2nd×1")).toBeInTheDocument();
      expect(screen.getByText("4th×1")).toBeInTheDocument();
      expect(screen.getByText("8th×1")).toBeInTheDocument();
    });

    it("should only show non-zero placement counts", () => {
      renderWithRouter(<StandingsTable standings={mockStandings} leagueId={mockLeagueId} seasonId={mockSeasonId} showPlacementBreakdown={true} />);

      // Should not show "3rd×0" for Champions United
      const placements = screen.queryByText("3rd×0");
      expect(placements).not.toBeInTheDocument();
    });

    it("should hide placement breakdown when disabled", () => {
      renderWithRouter(<StandingsTable standings={mockStandings} leagueId={mockLeagueId} seasonId={mockSeasonId} showPlacementBreakdown={false} />);

      expect(screen.queryByText("1st×2")).not.toBeInTheDocument();
    });

    it("should show 'None yet' when no placements", () => {
      const standings: TeamStanding[] = [
        {
          ...mockStandings[0],
          placementCounts: {
            first: 0,
            second: 0,
            third: 0,
            fourth: 0,
            fifth: 0,
            sixth: 0,
            seventh: 0,
            eighth: 0,
          },
        },
      ];

      renderWithRouter(<StandingsTable standings={standings} leagueId={mockLeagueId} seasonId={mockSeasonId} showPlacementBreakdown={true} />);

      expect(screen.getByText("None yet")).toBeInTheDocument();
    });
  });

  describe("Participants Remaining", () => {
    it("should show remaining count when participants are incomplete", () => {
      renderWithRouter(<StandingsTable standings={mockStandings} leagueId={mockLeagueId} seasonId={mockSeasonId} />);

      expect(screen.getByText("3 remaining")).toBeInTheDocument();
      expect(screen.getByText("5 remaining")).toBeInTheDocument();
    });

    it("should show 'Complete' badge when all participants done", () => {
      renderWithRouter(<StandingsTable standings={mockStandings} leagueId={mockLeagueId} seasonId={mockSeasonId} />);

      expect(screen.getByText("Complete")).toBeInTheDocument();
    });
  });

  describe("Table Structure", () => {
    it("should have correct table headers", () => {
      renderWithRouter(<StandingsTable standings={mockStandings} leagueId={mockLeagueId} seasonId={mockSeasonId} />);

      expect(screen.getByText("Rank")).toBeInTheDocument();
      expect(screen.getByText("Team")).toBeInTheDocument();
      expect(screen.getByText("Points")).toBeInTheDocument();
      expect(screen.getByText("Placements")).toBeInTheDocument();
      expect(screen.getByText("Remaining")).toBeInTheDocument();
    });

    it("should render teams in order", () => {
      const { container } = renderWithRouter(<StandingsTable standings={mockStandings} leagueId={mockLeagueId} seasonId={mockSeasonId} />);

      const rows = container.querySelectorAll("tbody tr");
      expect(rows).toHaveLength(3);

      // First row should be Champions United (rank 1)
      expect(rows[0].textContent).toContain("Champions United");

      // Second row should be Second Place Squad (rank 2)
      expect(rows[1].textContent).toContain("Second Place Squad");

      // Third row should be Bronze Warriors (rank 3)
      expect(rows[2].textContent).toContain("Bronze Warriors");
    });
  });

  describe("Tied Ranks", () => {
    it("should handle teams with same rank", () => {
      const tiedStandings: TeamStanding[] = [
        {
          ...mockStandings[0],
          currentRank: 1,
          teamName: "Team A",
        },
        {
          ...mockStandings[1],
          currentRank: 1,
          teamName: "Team B",
        },
        {
          ...mockStandings[2],
          currentRank: 3, // Skips 2
          teamName: "Team C",
        },
      ];

      renderWithRouter(<StandingsTable standings={tiedStandings} leagueId={mockLeagueId} seasonId={mockSeasonId} />);

      // Both teams should show rank 1
      const firstPlaceBadges = screen.getAllByText(/🏆.*1st/);
      expect(firstPlaceBadges).toHaveLength(2);

      // Third team should show rank 3 (not 2)
      expect(screen.getByText(/🥉.*3rd/)).toBeInTheDocument();
    });
  });

  describe("Accessibility", () => {
    it("should have title attributes for movement indicators", () => {
      const { container } = renderWithRouter(<StandingsTable standings={mockStandings} leagueId={mockLeagueId} seasonId={mockSeasonId} />);

      const upArrow = container.querySelector('[title*="Up"]');
      expect(upArrow).toBeInTheDocument();
      expect(upArrow?.getAttribute("title")).toContain("Up 1 place");

      const downArrow = container.querySelector('[title*="Down"]');
      expect(downArrow).toBeInTheDocument();
      expect(downArrow?.getAttribute("title")).toContain("Down 1 place");
    });

    it("should have title attributes for placement counts", () => {
      const { container } = renderWithRouter(<StandingsTable standings={mockStandings} leagueId={mockLeagueId} seasonId={mockSeasonId} showPlacementBreakdown={true} />);

      const firstPlace = container.querySelector('[title*="1st place"]');
      expect(firstPlace).toBeInTheDocument();
      expect(firstPlace?.getAttribute("title")).toContain("2 1st place finishes");
    });
  });
});
