"""Tests for alias loaders."""

import pytest
import json
import tempfile
from datetime import date
from pathlib import Path

from sportstime_parser.normalizers.alias_loader import (
    TeamAliasLoader,
    StadiumAliasLoader,
)
from sportstime_parser.models.aliases import AliasType


class TestTeamAliasLoader:
    """Tests for TeamAliasLoader class."""

    @pytest.fixture
    def sample_aliases_file(self):
        """Create a temporary aliases file for testing."""
        data = [
            {
                "id": "1",
                "team_canonical_id": "nba_okc",
                "alias_type": "name",
                "alias_value": "Seattle SuperSonics",
                "valid_from": "1967-01-01",
                "valid_until": "2008-07-02",
            },
            {
                "id": "2",
                "team_canonical_id": "nba_okc",
                "alias_type": "name",
                "alias_value": "Oklahoma City Thunder",
                "valid_from": "2008-07-03",
                "valid_until": None,
            },
            {
                "id": "3",
                "team_canonical_id": "nba_okc",
                "alias_type": "abbreviation",
                "alias_value": "OKC",
                "valid_from": "2008-07-03",
                "valid_until": None,
            },
        ]
        with tempfile.NamedTemporaryFile(
            mode="w", suffix=".json", delete=False
        ) as f:
            json.dump(data, f)
            return Path(f.name)

    def test_load_aliases(self, sample_aliases_file):
        """Test loading aliases from file."""
        loader = TeamAliasLoader(sample_aliases_file)
        loader.load()
        assert len(loader._aliases) == 3

    def test_resolve_current_alias(self, sample_aliases_file):
        """Test resolving a current alias."""
        loader = TeamAliasLoader(sample_aliases_file)

        # Current date should resolve to Thunder
        result = loader.resolve("Oklahoma City Thunder")
        assert result == "nba_okc"

        # Abbreviation should also work
        result = loader.resolve("OKC")
        assert result == "nba_okc"

    def test_resolve_historical_alias(self, sample_aliases_file):
        """Test resolving a historical alias with date."""
        loader = TeamAliasLoader(sample_aliases_file)

        # Historical date should resolve SuperSonics
        result = loader.resolve("Seattle SuperSonics", check_date=date(2007, 1, 1))
        assert result == "nba_okc"

        # After relocation, SuperSonics shouldn't resolve
        result = loader.resolve("Seattle SuperSonics", check_date=date(2010, 1, 1))
        assert result is None

    def test_resolve_case_insensitive(self, sample_aliases_file):
        """Test case insensitive resolution."""
        loader = TeamAliasLoader(sample_aliases_file)

        result = loader.resolve("oklahoma city thunder")
        assert result == "nba_okc"

        result = loader.resolve("okc")
        assert result == "nba_okc"

    def test_resolve_with_type_filter(self, sample_aliases_file):
        """Test filtering by alias type."""
        loader = TeamAliasLoader(sample_aliases_file)

        # Should find when searching all types
        result = loader.resolve("OKC")
        assert result == "nba_okc"

        # Should not find when filtering to name only
        result = loader.resolve("OKC", alias_types=[AliasType.NAME])
        assert result is None

    def test_get_aliases_for_team(self, sample_aliases_file):
        """Test getting all aliases for a team."""
        loader = TeamAliasLoader(sample_aliases_file)

        aliases = loader.get_aliases_for_team("nba_okc")
        assert len(aliases) == 3

        # Filter by current date
        aliases = loader.get_aliases_for_team(
            "nba_okc", check_date=date(2020, 1, 1)
        )
        assert len(aliases) == 2  # Thunder name + OKC abbreviation

    def test_missing_file(self):
        """Test handling of missing file."""
        loader = TeamAliasLoader(Path("/nonexistent/file.json"))
        loader.load()  # Should not raise
        assert len(loader._aliases) == 0


class TestStadiumAliasLoader:
    """Tests for StadiumAliasLoader class."""

    @pytest.fixture
    def sample_stadium_aliases(self):
        """Create a temporary stadium aliases file."""
        data = [
            {
                "alias_name": "Crypto.com Arena",
                "stadium_canonical_id": "crypto_arena_los_angeles_ca",
                "valid_from": "2021-12-25",
                "valid_until": None,
            },
            {
                "alias_name": "Staples Center",
                "stadium_canonical_id": "crypto_arena_los_angeles_ca",
                "valid_from": "1999-10-17",
                "valid_until": "2021-12-24",
            },
        ]
        with tempfile.NamedTemporaryFile(
            mode="w", suffix=".json", delete=False
        ) as f:
            json.dump(data, f)
            return Path(f.name)

    def test_load_stadium_aliases(self, sample_stadium_aliases):
        """Test loading stadium aliases."""
        loader = StadiumAliasLoader(sample_stadium_aliases)
        loader.load()
        assert len(loader._aliases) == 2

    def test_resolve_current_name(self, sample_stadium_aliases):
        """Test resolving current stadium name."""
        loader = StadiumAliasLoader(sample_stadium_aliases)

        result = loader.resolve("Crypto.com Arena")
        assert result == "crypto_arena_los_angeles_ca"

    def test_resolve_historical_name(self, sample_stadium_aliases):
        """Test resolving historical stadium name."""
        loader = StadiumAliasLoader(sample_stadium_aliases)

        # Staples Center in 2020
        result = loader.resolve("Staples Center", check_date=date(2020, 1, 1))
        assert result == "crypto_arena_los_angeles_ca"

        # Staples Center after rename shouldn't resolve
        result = loader.resolve("Staples Center", check_date=date(2023, 1, 1))
        assert result is None

    def test_date_boundary(self, sample_stadium_aliases):
        """Test exact date boundaries."""
        loader = StadiumAliasLoader(sample_stadium_aliases)

        # Last day of Staples Center
        result = loader.resolve("Staples Center", check_date=date(2021, 12, 24))
        assert result == "crypto_arena_los_angeles_ca"

        # First day of Crypto.com Arena
        result = loader.resolve("Crypto.com Arena", check_date=date(2021, 12, 25))
        assert result == "crypto_arena_los_angeles_ca"

    def test_get_all_names(self, sample_stadium_aliases):
        """Test getting all stadium names."""
        loader = StadiumAliasLoader(sample_stadium_aliases)

        names = loader.get_all_names()
        assert len(names) == 2
        assert "Crypto.com Arena" in names
        assert "Staples Center" in names


class TestDateRangeHandling:
    """Tests for date range edge cases in aliases."""

    @pytest.fixture
    def date_range_aliases(self):
        """Create aliases with various date range scenarios."""
        data = [
            {
                "id": "1",
                "team_canonical_id": "test_team",
                "alias_type": "name",
                "alias_value": "Always Valid",
                "valid_from": None,
                "valid_until": None,
            },
            {
                "id": "2",
                "team_canonical_id": "test_team",
                "alias_type": "name",
                "alias_value": "Future Only",
                "valid_from": "2030-01-01",
                "valid_until": None,
            },
            {
                "id": "3",
                "team_canonical_id": "test_team",
                "alias_type": "name",
                "alias_value": "Past Only",
                "valid_from": None,
                "valid_until": "2000-01-01",
            },
        ]
        with tempfile.NamedTemporaryFile(
            mode="w", suffix=".json", delete=False
        ) as f:
            json.dump(data, f)
            return Path(f.name)

    def test_always_valid_alias(self, date_range_aliases):
        """Test alias with no date restrictions."""
        loader = TeamAliasLoader(date_range_aliases)

        result = loader.resolve("Always Valid", check_date=date(2025, 1, 1))
        assert result == "test_team"

        result = loader.resolve("Always Valid", check_date=date(1990, 1, 1))
        assert result == "test_team"

    def test_future_only_alias(self, date_range_aliases):
        """Test alias that starts in the future."""
        loader = TeamAliasLoader(date_range_aliases)

        # Before valid_from
        result = loader.resolve("Future Only", check_date=date(2025, 1, 1))
        assert result is None

        # After valid_from
        result = loader.resolve("Future Only", check_date=date(2035, 1, 1))
        assert result == "test_team"

    def test_past_only_alias(self, date_range_aliases):
        """Test alias that expired in the past."""
        loader = TeamAliasLoader(date_range_aliases)

        # Before valid_until
        result = loader.resolve("Past Only", check_date=date(1990, 1, 1))
        assert result == "test_team"

        # After valid_until
        result = loader.resolve("Past Only", check_date=date(2025, 1, 1))
        assert result is None
