"""
Unit tests for key generation utilities.
"""

import pytest
from src.core.utils.key_utils import (
    generate_key_from_folder,
    normalize_key,
    is_valid_key,
    sanitize_key_for_url,
    validate_key_uniqueness,
)


class TestGenerateKeyFromFolder:
    """Test generate_key_from_folder function with edge cases."""

    def test_standard_folder_name(self):
        """Test standard folder name with year."""
        key = generate_key_from_folder("Attack on Titan (2013)")
        assert key == "attack-on-titan-2013"
        assert is_valid_key(key)

    def test_a_time_called_you(self):
        """Test 'A Time Called You (2023)' - the specific failing case."""
        key = generate_key_from_folder("A Time Called You (2023)")
        assert key is not None
        assert key != ""
        assert is_valid_key(key)

    def test_andor_2022(self):
        """Test 'Andor (2022)' - the specific failing case."""
        key = generate_key_from_folder("Andor (2022)")
        assert key is not None
        assert key != ""
        assert is_valid_key(key)

    def test_japanese_mixed_folder(self):
        """Test '25-sai no Joshikousei (2018)' - Japanese + Latin mixed."""
        key = generate_key_from_folder("25-sai no Joshikousei (2018)")
        assert key is not None
        assert key != ""
        assert is_valid_key(key)

    def test_folder_with_only_special_characters(self):
        """Test folder that would slugify to empty string."""
        key = generate_key_from_folder("!!!@@@###")
        assert key is not None
        assert key != ""
        # Should use UUID fallback

    def test_folder_with_only_numbers(self):
        """Test folder that is just numbers."""
        key = generate_key_from_folder("12345")
        assert key is not None
        assert key != ""
        assert is_valid_key(key)

    def test_folder_with_parentheses_and_year(self):
        """Test folder with parentheses containing year."""
        key = generate_key_from_folder("My Series (2020)")
        assert key is not None
        assert key != ""
        assert is_valid_key(key)

    def test_folder_with_brackets(self):
        """Test folder with square brackets."""
        key = generate_key_from_folder("My Series [Special] (2021)")
        assert key is not None
        assert key != ""
        assert is_valid_key(key)

    def test_unicode_characters(self):
        """Test folder with various Unicode characters."""
        key = generate_key_from_folder("Héros Légende (2022)")
        assert key is not None
        assert key != ""
        assert is_valid_key(key)

    def test_korean_characters(self):
        """Test folder with Korean characters."""
        key = generate_key_from_folder("나의 애니메이션 (2023)")
        assert key is not None
        assert key != ""

    def test_chinese_characters(self):
        """Test folder with Chinese characters."""
        key = generate_key_from_folder("我的动漫 (2024)")
        assert key is not None
        assert key != ""

    def test_empty_string_input(self):
        """Test empty string input raises ValueError."""
        with pytest.raises(ValueError, match="Folder name cannot be empty"):
            generate_key_from_folder("")

    def test_only_whitespace_input(self):
        """Test whitespace-only input raises ValueError."""
        with pytest.raises(ValueError, match="Folder name cannot be empty"):
            generate_key_from_folder("   ")

    def test_single_character_folder(self):
        """Test single character folder name."""
        key = generate_key_from_folder("X")
        assert key is not None
        assert key != ""
        assert is_valid_key(key)

    def test_very_long_folder_name(self):
        """Test very long folder name."""
        long_name = "A" * 200
        key = generate_key_from_folder(long_name)
        assert key is not None
        assert key != ""

    def test_multiple_spaces(self):
        """Test folder with multiple consecutive spaces."""
        key = generate_key_from_folder("My    Series   Name")
        assert key is not None
        assert key != ""

    def test_leading_trailing_spaces(self):
        """Test folder with leading and trailing spaces."""
        key = generate_key_from_folder("  My Series  ")
        assert key is not None
        assert key != ""

    def test_diacritics_normalization(self):
        """Test that diacritics are properly normalized."""
        key = generate_key_from_folder("Animé (2023)")
        assert key is not None
        assert is_valid_key(key)


class TestNormalizeKey:
    """Test normalize_key function."""

    def test_normalize_standard_key(self):
        """Test normalizing a standard key."""
        result = normalize_key("Attack-on-Titan")
        assert result == "attack-on-titan"

    def test_normalize_with_underscores(self):
        """Test normalizing key with underscores."""
        result = normalize_key("attack_on_titan")
        assert result == "attack-on-titan"

    def test_normalize_mixed_case(self):
        """Test normalizing mixed case key."""
        result = normalize_key("Attack_On_Titan")
        assert result == "attack-on-titan"

    def test_normalize_with_spaces(self):
        """Test normalizing key with spaces."""
        result = normalize_key("attack on titan")
        assert result == "attack-on-titan"

    def test_normalize_empty_string(self):
        """Test normalizing empty string returns empty."""
        result = normalize_key("")
        assert result == ""

    def test_normalize_only_special_chars(self):
        """Test normalizing string with only special characters."""
        result = normalize_key("!!!@@@")
        assert result == ""


class TestIsValidKey:
    """Test is_valid_key function."""

    def test_valid_simple_key(self):
        """Test valid simple key."""
        assert is_valid_key("attack-on-titan")

    def test_valid_key_with_numbers(self):
        """Test valid key with numbers."""
        assert is_valid_key("a-time-called-you-2023")

    def test_valid_key_with_underscores(self):
        """Test valid key with underscores."""
        assert is_valid_key("a_time_called_you_2023")

    def test_valid_key_starting_with_number(self):
        """Test valid key starting with number."""
        assert is_valid_key("25-sai-no-joshikousei-2018")

    def test_invalid_empty_key(self):
        """Test invalid empty key."""
        assert not is_valid_key("")

    def test_invalid_key_with_spaces(self):
        """Test invalid key with spaces."""
        assert not is_valid_key("attack on titan")

    def test_invalid_key_with_special_chars(self):
        """Test invalid key with special characters."""
        assert not is_valid_key("attack@titan")

    def test_invalid_key_with_unicode(self):
        """Test invalid key with unstripped unicode."""
        assert not is_valid_key("attack\u00a0titan")  # Non-breaking space

    def test_invalid_single_char(self):
        """Test invalid single character key."""
        assert not is_valid_key("a")

    def test_valid_two_char_key(self):
        """Test valid two character key."""
        assert is_valid_key("ab")

    def test_invalid_key_starting_with_hyphen(self):
        """Test invalid key starting with hyphen."""
        assert not is_valid_key("-attack")


class TestSanitizeKeyForUrl:
    """Test sanitize_key_for_url function."""

    def test_standard_key_unchanged(self):
        """Test standard key remains unchanged."""
        result = sanitize_key_for_url("attack-on-titan-2013")
        assert result == "attack-on-titan-2013"

    def test_spaces_replaced(self):
        """Test spaces are replaced with hyphens."""
        result = sanitize_key_for_url("attack on titan")
        assert result == "attack-on-titan"

    def test_uppercase_preserved(self):
        """Test uppercase is preserved (use normalize_key for lowercase)."""
        result = sanitize_key_for_url("AttackOnTitan")
        # sanitize_key_for_url preserves case, only removes special chars
        assert result == "AttackOnTitan"

    def test_special_chars_removed(self):
        """Test special characters are removed."""
        result = sanitize_key_for_url("Attack@#@On!Titan")
        assert result == "AttackOnTitan"

    def test_accents_preserved(self):
        """Test accented characters are preserved (use normalize_key for full normalization)."""
        result = sanitize_key_for_url("AttäckÖnTïtan")
        # Only removes truly problematic chars, preserves accented letters
        assert "AttäckÖnTïtan" in result

    def test_multiple_hyphens_collapses(self):
        """Test multiple hyphens are collapsed."""
        result = sanitize_key_for_url("attack---on---titan")
        assert result == "attack-on-titan"

    def test_leading_trailing_hyphens_removed(self):
        """Test leading and trailing hyphens are removed."""
        result = sanitize_key_for_url("-attack-on-titan-")
        assert result == "attack-on-titan"


class TestValidateKeyUniqueness:
    """Test validate_key_uniqueness function."""

    def test_unique_key(self):
        """Test key that is unique."""
        existing_keys = {"attack-on-titan", "one-piece", "naruto"}
        is_valid, error = validate_key_uniqueness("new-series", existing_keys)
        assert is_valid is True
        assert error == ""

    def test_duplicate_key(self):
        """Test key that already exists."""
        existing_keys = {"attack-on-titan", "one-piece", "naruto"}
        is_valid, error = validate_key_uniqueness("one-piece", existing_keys)
        assert is_valid is False
        assert "already in use" in error

    def test_empty_existing_set(self):
        """Test with empty existing keys set."""
        is_valid, error = validate_key_uniqueness("new-series", set())
        assert is_valid is True
        assert error == ""

    def test_key_differs_only_by_case(self):
        """Test key that differs only by case is NOT flagged by utility (API layer handles case-insensitivity)."""
        existing_keys = {"attack-on-titan"}  # lowercase in set
        is_valid, error = validate_key_uniqueness("Attack-on-Titan", existing_keys)
        # Utility function does case-sensitive check; API layer handles case-insensitivity
        assert is_valid is True
        assert error == ""

    def test_same_key_same_case(self):
        """Test same key in existing set is flagged."""
        existing_keys = {"my-series"}
        is_valid, error = validate_key_uniqueness("my-series", existing_keys)
        assert is_valid is False