import pytest

from fastbreak.models import LeagueDashTeamClutchResponse, TeamClutchStats


class TestTeamClutchStats:
    """Tests for TeamClutchStats model."""

    def test_parse_valid_entry(self) -> None:
        """TeamClutchStats parses valid data."""
        data = {
            "TEAM_ID": 1610612738,
            "TEAM_NAME": "Boston Celtics",
            "GP": 35,
            "W": 24,
            "L": 11,
            "W_PCT": 0.686,
            "MIN": 46.6,
            "FGM": 39.6,
            "FGA": 82.6,
            "FG_PCT": 0.48,
            "FG3M": 16.8,
            "FG3A": 44.3,
            "FG3_PCT": 0.379,
            "FTM": 26.5,
            "FTA": 34.9,
            "FT_PCT": 0.76,
            "OREB": 11.1,
            "DREB": 28.2,
            "REB": 39.3,
            "AST": 22.8,
            "TOV": 10.7,
            "STL": 5.7,
            "BLK": 6.7,
            "BLKA": 2.3,
            "PF": 23.2,
            "PFD": 27.9,
            "PTS": 122.5,
            "PLUS_MINUS": 19.8,
            "GP_RANK": 21,
            "W_RANK": 4,
            "L_RANK": 2,
            "W_PCT_RANK": 1,
            "MIN_RANK": 24,
            "FGM_RANK": 4,
            "FGA_RANK": 10,
            "FG_PCT_RANK": 3,
            "FG3M_RANK": 1,
            "FG3A_RANK": 1,
            "FG3_PCT_RANK": 6,
            "FTM_RANK": 22,
            "FTA_RANK": 20,
            "FT_PCT_RANK": 22,
            "OREB_RANK": 17,
            "DREB_RANK": 25,
            "REB_RANK": 24,
            "AST_RANK": 3,
            "TOV_RANK": 5,
            "STL_RANK": 16,
            "BLK_RANK": 3,
            "BLKA_RANK": 1,
            "PF_RANK": 7,
            "PFD_RANK": 9,
            "PTS_RANK": 2,
            "PLUS_MINUS_RANK": 3,
        }

        entry = TeamClutchStats.model_validate(data)

        assert entry.team_id == 1610612738
        assert entry.team_name == "Boston Celtics"
        assert entry.gp == 35
        assert entry.w == 24
        assert entry.losses == 11
        assert entry.w_pct == pytest.approx(0.686)
        assert entry.pts == pytest.approx(122.5)
        assert entry.plus_minus == pytest.approx(19.8)
        assert entry.w_pct_rank == 1
        assert entry.pts_rank == 2

    def test_parse_float_percentages(self) -> None:
        """TeamClutchStats handles float percentage values."""
        data = {
            "TEAM_ID": 1610612737,
            "TEAM_NAME": "Atlanta Hawks",
            "GP": 41,
            "W": 21,
            "L": 20,
            "W_PCT": 0.512,
            "MIN": 46.0,
            "FGM": 35.9,
            "FGA": 79.6,
            "FG_PCT": 0.451,
            "FG3M": 10.6,
            "FG3A": 31.3,
            "FG3_PCT": 0.339,
            "FTM": 33.0,
            "FTA": 40.5,
            "FT_PCT": 0.816,
            "OREB": 11.2,
            "DREB": 31.6,
            "REB": 42.8,
            "AST": 22.7,
            "TOV": 12.4,
            "STL": 6.3,
            "BLK": 4.9,
            "BLKA": 4.6,
            "PF": 23.0,
            "PFD": 28.4,
            "PTS": 115.5,
            "PLUS_MINUS": 8.3,
            "GP_RANK": 7,
            "W_RANK": 8,
            "L_RANK": 17,
            "W_PCT_RANK": 15,
            "MIN_RANK": 27,
            "FGM_RANK": 14,
            "FGA_RANK": 21,
            "FG_PCT_RANK": 10,
            "FG3M_RANK": 18,
            "FG3A_RANK": 22,
            "FG3_PCT_RANK": 11,
            "FTM_RANK": 8,
            "FTA_RANK": 9,
            "FT_PCT_RANK": 5,
            "OREB_RANK": 15,
            "DREB_RANK": 13,
            "REB_RANK": 13,
            "AST_RANK": 5,
            "TOV_RANK": 16,
            "STL_RANK": 16,
            "BLK_RANK": 18,
            "BLKA_RANK": 13,
            "PF_RANK": 7,
            "PFD_RANK": 9,
            "PTS_RANK": 9,
            "PLUS_MINUS_RANK": 10,
        }

        entry = TeamClutchStats.model_validate(data)

        assert entry.fg_pct == pytest.approx(0.451)
        assert entry.fg3_pct == pytest.approx(0.339)
        assert entry.ft_pct == pytest.approx(0.816)

    def test_parse_negative_plus_minus(self) -> None:
        """TeamClutchStats handles negative plus/minus."""
        data = {
            "TEAM_ID": 1610612764,
            "TEAM_NAME": "Washington Wizards",
            "GP": 30,
            "W": 8,
            "L": 22,
            "W_PCT": 0.267,
            "MIN": 40.0,
            "FGM": 30.0,
            "FGA": 75.0,
            "FG_PCT": 0.400,
            "FG3M": 8.0,
            "FG3A": 25.0,
            "FG3_PCT": 0.320,
            "FTM": 20.0,
            "FTA": 28.0,
            "FT_PCT": 0.714,
            "OREB": 9.0,
            "DREB": 28.0,
            "REB": 37.0,
            "AST": 18.0,
            "TOV": 14.0,
            "STL": 5.0,
            "BLK": 3.0,
            "BLKA": 6.0,
            "PF": 25.0,
            "PFD": 22.0,
            "PTS": 88.0,
            "PLUS_MINUS": -15.5,
            "GP_RANK": 30,
            "W_RANK": 30,
            "L_RANK": 1,
            "W_PCT_RANK": 30,
            "MIN_RANK": 30,
            "FGM_RANK": 30,
            "FGA_RANK": 30,
            "FG_PCT_RANK": 30,
            "FG3M_RANK": 30,
            "FG3A_RANK": 30,
            "FG3_PCT_RANK": 30,
            "FTM_RANK": 30,
            "FTA_RANK": 30,
            "FT_PCT_RANK": 30,
            "OREB_RANK": 30,
            "DREB_RANK": 30,
            "REB_RANK": 30,
            "AST_RANK": 30,
            "TOV_RANK": 1,
            "STL_RANK": 30,
            "BLK_RANK": 30,
            "BLKA_RANK": 30,
            "PF_RANK": 30,
            "PFD_RANK": 30,
            "PTS_RANK": 30,
            "PLUS_MINUS_RANK": 30,
        }

        entry = TeamClutchStats.model_validate(data)

        assert entry.plus_minus == pytest.approx(-15.5)
        assert entry.plus_minus_rank == 30


class TestLeagueDashTeamClutchResponse:
    """Tests for LeagueDashTeamClutchResponse model."""

    def test_parse_result_sets_format(self) -> None:
        """LeagueDashTeamClutchResponse parses tabular data correctly."""
        data = {
            "resource": "leaguedashteamclutch",
            "parameters": {
                "Season": "2024-25",
                "SeasonType": "Regular Season",
                "ClutchTime": "Last 5 Minutes",
                "AheadBehind": "Ahead or Behind",
                "PointDiff": 5,
            },
            "resultSets": [
                {
                    "name": "LeagueDashTeamClutch",
                    "headers": [
                        "TEAM_ID",
                        "TEAM_NAME",
                        "GP",
                        "W",
                        "L",
                        "W_PCT",
                        "MIN",
                        "FGM",
                        "FGA",
                        "FG_PCT",
                        "FG3M",
                        "FG3A",
                        "FG3_PCT",
                        "FTM",
                        "FTA",
                        "FT_PCT",
                        "OREB",
                        "DREB",
                        "REB",
                        "AST",
                        "TOV",
                        "STL",
                        "BLK",
                        "BLKA",
                        "PF",
                        "PFD",
                        "PTS",
                        "PLUS_MINUS",
                        "GP_RANK",
                        "W_RANK",
                        "L_RANK",
                        "W_PCT_RANK",
                        "MIN_RANK",
                        "FGM_RANK",
                        "FGA_RANK",
                        "FG_PCT_RANK",
                        "FG3M_RANK",
                        "FG3A_RANK",
                        "FG3_PCT_RANK",
                        "FTM_RANK",
                        "FTA_RANK",
                        "FT_PCT_RANK",
                        "OREB_RANK",
                        "DREB_RANK",
                        "REB_RANK",
                        "AST_RANK",
                        "TOV_RANK",
                        "STL_RANK",
                        "BLK_RANK",
                        "BLKA_RANK",
                        "PF_RANK",
                        "PFD_RANK",
                        "PTS_RANK",
                        "PLUS_MINUS_RANK",
                    ],
                    "rowSet": [
                        [
                            1610612738,
                            "Boston Celtics",
                            35,
                            24,
                            11,
                            0.686,
                            46.6,
                            39.6,
                            82.6,
                            0.48,
                            16.8,
                            44.3,
                            0.379,
                            26.5,
                            34.9,
                            0.76,
                            11.1,
                            28.2,
                            39.3,
                            22.8,
                            10.7,
                            5.7,
                            6.7,
                            2.3,
                            23.2,
                            27.9,
                            122.5,
                            19.8,
                            21,
                            4,
                            2,
                            1,
                            24,
                            4,
                            10,
                            3,
                            1,
                            1,
                            6,
                            22,
                            20,
                            22,
                            17,
                            25,
                            24,
                            3,
                            5,
                            16,
                            3,
                            1,
                            7,
                            9,
                            2,
                            3,
                        ],
                        [
                            1610612739,
                            "Cleveland Cavaliers",
                            38,
                            26,
                            12,
                            0.684,
                            50.0,
                            41.0,
                            85.0,
                            0.482,
                            15.0,
                            40.0,
                            0.375,
                            27.0,
                            35.0,
                            0.771,
                            10.0,
                            30.0,
                            40.0,
                            24.0,
                            11.0,
                            6.0,
                            5.0,
                            3.0,
                            22.0,
                            28.0,
                            124.0,
                            22.5,
                            10,
                            2,
                            3,
                            2,
                            10,
                            2,
                            5,
                            2,
                            3,
                            3,
                            5,
                            20,
                            18,
                            20,
                            20,
                            20,
                            20,
                            2,
                            8,
                            12,
                            8,
                            5,
                            8,
                            8,
                            1,
                            1,
                        ],
                    ],
                }
            ],
        }

        response = LeagueDashTeamClutchResponse.model_validate(data)

        assert len(response.teams) == 2
        assert response.teams[0].team_name == "Boston Celtics"
        assert response.teams[0].w_pct == pytest.approx(0.686)
        assert response.teams[0].pts == pytest.approx(122.5)
        assert response.teams[1].team_name == "Cleveland Cavaliers"
        assert response.teams[1].w == 26

    def test_handles_empty_result_set(self) -> None:
        """LeagueDashTeamClutchResponse handles empty rowSet gracefully."""
        data = {
            "resultSets": [
                {
                    "name": "LeagueDashTeamClutch",
                    "headers": [
                        "TEAM_ID",
                        "TEAM_NAME",
                        "GP",
                        "W",
                        "L",
                        "W_PCT",
                        "MIN",
                        "FGM",
                        "FGA",
                        "FG_PCT",
                        "FG3M",
                        "FG3A",
                        "FG3_PCT",
                        "FTM",
                        "FTA",
                        "FT_PCT",
                        "OREB",
                        "DREB",
                        "REB",
                        "AST",
                        "TOV",
                        "STL",
                        "BLK",
                        "BLKA",
                        "PF",
                        "PFD",
                        "PTS",
                        "PLUS_MINUS",
                        "GP_RANK",
                        "W_RANK",
                        "L_RANK",
                        "W_PCT_RANK",
                        "MIN_RANK",
                        "FGM_RANK",
                        "FGA_RANK",
                        "FG_PCT_RANK",
                        "FG3M_RANK",
                        "FG3A_RANK",
                        "FG3_PCT_RANK",
                        "FTM_RANK",
                        "FTA_RANK",
                        "FT_PCT_RANK",
                        "OREB_RANK",
                        "DREB_RANK",
                        "REB_RANK",
                        "AST_RANK",
                        "TOV_RANK",
                        "STL_RANK",
                        "BLK_RANK",
                        "BLKA_RANK",
                        "PF_RANK",
                        "PFD_RANK",
                        "PTS_RANK",
                        "PLUS_MINUS_RANK",
                    ],
                    "rowSet": [],
                }
            ],
        }

        response = LeagueDashTeamClutchResponse.model_validate(data)

        assert len(response.teams) == 0

    def test_preserves_order_from_api(self) -> None:
        """LeagueDashTeamClutchResponse maintains order from API response."""
        data = {
            "resultSets": [
                {
                    "name": "LeagueDashTeamClutch",
                    "headers": [
                        "TEAM_ID",
                        "TEAM_NAME",
                        "GP",
                        "W",
                        "L",
                        "W_PCT",
                        "MIN",
                        "FGM",
                        "FGA",
                        "FG_PCT",
                        "FG3M",
                        "FG3A",
                        "FG3_PCT",
                        "FTM",
                        "FTA",
                        "FT_PCT",
                        "OREB",
                        "DREB",
                        "REB",
                        "AST",
                        "TOV",
                        "STL",
                        "BLK",
                        "BLKA",
                        "PF",
                        "PFD",
                        "PTS",
                        "PLUS_MINUS",
                        "GP_RANK",
                        "W_RANK",
                        "L_RANK",
                        "W_PCT_RANK",
                        "MIN_RANK",
                        "FGM_RANK",
                        "FGA_RANK",
                        "FG_PCT_RANK",
                        "FG3M_RANK",
                        "FG3A_RANK",
                        "FG3_PCT_RANK",
                        "FTM_RANK",
                        "FTA_RANK",
                        "FT_PCT_RANK",
                        "OREB_RANK",
                        "DREB_RANK",
                        "REB_RANK",
                        "AST_RANK",
                        "TOV_RANK",
                        "STL_RANK",
                        "BLK_RANK",
                        "BLKA_RANK",
                        "PF_RANK",
                        "PFD_RANK",
                        "PTS_RANK",
                        "PLUS_MINUS_RANK",
                    ],
                    "rowSet": [
                        [
                            1,
                            "First",
                            10,
                            8,
                            2,
                            0.8,
                            40,
                            35,
                            70,
                            0.5,
                            10,
                            25,
                            0.4,
                            20,
                            25,
                            0.8,
                            8,
                            25,
                            33,
                            20,
                            10,
                            5,
                            4,
                            3,
                            20,
                            25,
                            100,
                            10,
                            1,
                            1,
                            1,
                            1,
                            1,
                            1,
                            1,
                            1,
                            1,
                            1,
                            1,
                            1,
                            1,
                            1,
                            1,
                            1,
                            1,
                            1,
                            1,
                            1,
                            1,
                            1,
                            1,
                            1,
                            1,
                            1,
                        ],
                        [
                            2,
                            "Second",
                            10,
                            7,
                            3,
                            0.7,
                            40,
                            34,
                            70,
                            0.486,
                            10,
                            25,
                            0.4,
                            20,
                            25,
                            0.8,
                            8,
                            25,
                            33,
                            20,
                            10,
                            5,
                            4,
                            3,
                            20,
                            25,
                            98,
                            8,
                            2,
                            2,
                            2,
                            2,
                            2,
                            2,
                            2,
                            2,
                            2,
                            2,
                            2,
                            2,
                            2,
                            2,
                            2,
                            2,
                            2,
                            2,
                            2,
                            2,
                            2,
                            2,
                            2,
                            2,
                            2,
                            2,
                        ],
                        [
                            3,
                            "Third",
                            10,
                            6,
                            4,
                            0.6,
                            40,
                            33,
                            70,
                            0.471,
                            10,
                            25,
                            0.4,
                            20,
                            25,
                            0.8,
                            8,
                            25,
                            33,
                            20,
                            10,
                            5,
                            4,
                            3,
                            20,
                            25,
                            96,
                            6,
                            3,
                            3,
                            3,
                            3,
                            3,
                            3,
                            3,
                            3,
                            3,
                            3,
                            3,
                            3,
                            3,
                            3,
                            3,
                            3,
                            3,
                            3,
                            3,
                            3,
                            3,
                            3,
                            3,
                            3,
                            3,
                            3,
                        ],
                    ],
                }
            ],
        }

        response = LeagueDashTeamClutchResponse.model_validate(data)

        assert response.teams[0].team_name == "First"
        assert response.teams[1].team_name == "Second"
        assert response.teams[2].team_name == "Third"

    def test_handles_pre_validated_dict(self) -> None:
        """LeagueDashTeamClutchResponse handles already-structured data."""
        data = {
            "teams": [
                {
                    "TEAM_ID": 1610612738,
                    "TEAM_NAME": "Boston Celtics",
                    "GP": 35,
                    "W": 24,
                    "L": 11,
                    "W_PCT": 0.686,
                    "MIN": 46.6,
                    "FGM": 39.6,
                    "FGA": 82.6,
                    "FG_PCT": 0.48,
                    "FG3M": 16.8,
                    "FG3A": 44.3,
                    "FG3_PCT": 0.379,
                    "FTM": 26.5,
                    "FTA": 34.9,
                    "FT_PCT": 0.76,
                    "OREB": 11.1,
                    "DREB": 28.2,
                    "REB": 39.3,
                    "AST": 22.8,
                    "TOV": 10.7,
                    "STL": 5.7,
                    "BLK": 6.7,
                    "BLKA": 2.3,
                    "PF": 23.2,
                    "PFD": 27.9,
                    "PTS": 122.5,
                    "PLUS_MINUS": 19.8,
                    "GP_RANK": 21,
                    "W_RANK": 4,
                    "L_RANK": 2,
                    "W_PCT_RANK": 1,
                    "MIN_RANK": 24,
                    "FGM_RANK": 4,
                    "FGA_RANK": 10,
                    "FG_PCT_RANK": 3,
                    "FG3M_RANK": 1,
                    "FG3A_RANK": 1,
                    "FG3_PCT_RANK": 6,
                    "FTM_RANK": 22,
                    "FTA_RANK": 20,
                    "FT_PCT_RANK": 22,
                    "OREB_RANK": 17,
                    "DREB_RANK": 25,
                    "REB_RANK": 24,
                    "AST_RANK": 3,
                    "TOV_RANK": 5,
                    "STL_RANK": 16,
                    "BLK_RANK": 3,
                    "BLKA_RANK": 1,
                    "PF_RANK": 7,
                    "PFD_RANK": 9,
                    "PTS_RANK": 2,
                    "PLUS_MINUS_RANK": 3,
                }
            ]
        }

        response = LeagueDashTeamClutchResponse.model_validate(data)

        assert len(response.teams) == 1
        assert response.teams[0].team_name == "Boston Celtics"
