import { describe, it, expect } from "vitest";
import { render, screen } from "@testing-library/react";
import { BrowserRouter } from "react-router";
import { StandingsPreview, type StandingsPreviewEntry } from "../StandingsPreview";

function renderWithRouter(ui: React.ReactElement) {
  return render(<BrowserRouter>{ui}</BrowserRouter>);
}

const baseEntry: StandingsPreviewEntry = {
  teamId: "team-1",
  teamName: "Lightning Wolves",
  ownerName: "alice",
  displayRank: 1,
  currentRank: 1,
  points: 2500,
  href: "/leagues/1/standings/1/teams/team-1",
};

describe("StandingsPreview", () => {
  describe("Avatar rendering", () => {
    it("renders an img for uploaded avatar type", () => {
      const entry: StandingsPreviewEntry = {
        ...baseEntry,
        avatarType: "uploaded",
        logoUrl: "https://example.com/team-logo.png",
      };
      renderWithRouter(<StandingsPreview entries={[entry]} />);

      const img = screen.getByAltText("Lightning Wolves");
      expect(img.tagName).toBe("IMG");
    });

    it("renders an SVG for flag avatar type", () => {
      const entry: StandingsPreviewEntry = {
        ...baseEntry,
        avatarType: "flag",
        flagConfig: { pattern: "triband-h", colors: ["#ff0000", "#ffffff", "#0000ff"] },
      };
      const { container } = renderWithRouter(<StandingsPreview entries={[entry]} />);

      expect(container.querySelector("svg")).toBeInTheDocument();
    });

    it("renders owner image when avatarType is owner with image ownerAvatarData", () => {
      const entry: StandingsPreviewEntry = {
        ...baseEntry,
        avatarType: "owner",
        ownerAvatarData: { type: "image", url: "https://example.com/owner.png" },
      };
      renderWithRouter(<StandingsPreview entries={[entry]} />);

      const img = screen.getByAltText("Lightning Wolves");
      expect(img.tagName).toBe("IMG");
    });

    it("falls back to a generated flag when no avatar data is provided", () => {
      const entry: StandingsPreviewEntry = { ...baseEntry, avatarType: undefined };
      const { container } = renderWithRouter(<StandingsPreview entries={[entry]} />);

      expect(container.querySelector("svg")).toBeInTheDocument();
    });
  });

  describe("Basic rendering", () => {
    it("renders team names for all entries", () => {
      const entries: StandingsPreviewEntry[] = [
        { ...baseEntry, teamId: "t1", teamName: "Team Alpha", displayRank: 1 },
        { ...baseEntry, teamId: "t2", teamName: "Team Beta", displayRank: 2 },
      ];
      renderWithRouter(<StandingsPreview entries={entries} />);

      // Use selector to target only the <p> element — the team name also appears
      // in the SVG <title> for accessibility, causing multiple matches otherwise.
      expect(screen.getByText("Team Alpha", { selector: "p" })).toBeInTheDocument();
      expect(screen.getByText("Team Beta", { selector: "p" })).toBeInTheDocument();
    });

    it("renders owner name below team name", () => {
      renderWithRouter(<StandingsPreview entries={[baseEntry]} />);

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

    it("renders rounded points", () => {
      renderWithRouter(<StandingsPreview entries={[{ ...baseEntry, points: 1500 }]} />);

      expect(screen.getByText("1,500")).toBeInTheDocument();
    });

    it("renders description when provided", () => {
      renderWithRouter(<StandingsPreview entries={[baseEntry]} description="Current Standings" />);

      expect(screen.getByText("Current Standings")).toBeInTheDocument();
    });

    it("renders full standings link when fullStandingsHref is provided", () => {
      renderWithRouter(
        <StandingsPreview entries={[baseEntry]} fullStandingsHref="/leagues/1/standings/1" />
      );

      const link = screen.getByRole("link", { name: "Full Standings" });
      expect(link).toHaveAttribute("href", "/leagues/1/standings/1");
    });
  });

  describe("Projections", () => {
    it("does not render a Projected column by default", () => {
      const entry: StandingsPreviewEntry = {
        ...baseEntry,
        projectedPoints: 3000,
        participantsRemaining: 3,
      };
      renderWithRouter(<StandingsPreview entries={[entry]} />);

      expect(screen.queryByText("Projected")).not.toBeInTheDocument();
      expect(screen.queryByText("3,000")).not.toBeInTheDocument();
    });

    it("renders the projected value when showProjected and participants remain", () => {
      const entry: StandingsPreviewEntry = {
        ...baseEntry,
        projectedPoints: 3000,
        participantsRemaining: 3,
      };
      renderWithRouter(<StandingsPreview entries={[entry]} showProjected />);

      expect(screen.getByText("Projected")).toBeInTheDocument();
      expect(screen.getByText("3,000")).toBeInTheDocument();
    });

    it("shows a placeholder instead of a value when no participants remain", () => {
      const entry: StandingsPreviewEntry = {
        ...baseEntry,
        projectedPoints: 9999,
        participantsRemaining: 0,
      };
      renderWithRouter(<StandingsPreview entries={[entry]} showProjected />);

      // Column header still present, but the projected total is not shown.
      expect(screen.getByText("Projected")).toBeInTheDocument();
      expect(screen.queryByText("9,999")).not.toBeInTheDocument();
    });

    it("shows a placeholder when projectedPoints is missing", () => {
      const entry: StandingsPreviewEntry = {
        ...baseEntry,
        projectedPoints: null,
        participantsRemaining: 3,
      };
      renderWithRouter(<StandingsPreview entries={[entry]} showProjected />);

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