"""
Tests for template helper utilities.

This module tests the template helper functions including series context
preparation using `key` as the primary identifier.
"""
from unittest.mock import Mock

import pytest

from src.server.utils.template_helpers import (
    filter_series_by_missing_episodes,
    get_base_context,
    get_series_by_key,
    list_available_templates,
    prepare_series_context,
    validate_template_exists,
)


class TestTemplateHelpers:
    """Test template helper utilities."""

    def test_get_base_context(self):
        """Test that base context is created correctly."""
        request = Mock()
        context = get_base_context(request, "Test Title")
        
        assert "request" in context
        assert context["request"] == request
        assert context["title"] == "Test Title"
        assert context["app_name"] == "Aniworld Download Manager"
        assert context["version"] == "1.0.1"

    def test_get_base_context_default_title(self):
        """Test that default title is used."""
        request = Mock()
        context = get_base_context(request)
        
        assert context["title"] == "Aniworld"

    def test_validate_template_exists_true(self):
        """Test template validation for existing template."""
        # index.html should exist
        exists = validate_template_exists("index.html")
        assert exists is True

    def test_validate_template_exists_false(self):
        """Test template validation for non-existing template."""
        exists = validate_template_exists("nonexistent.html")
        assert exists is False

    def test_list_available_templates(self):
        """Test listing available templates."""
        templates = list_available_templates()
        
        # Should be a list
        assert isinstance(templates, list)
        
        # Should contain at least the main templates
        expected_templates = [
            "index.html",
            "login.html",
            "setup.html",
            "queue.html",
            "error.html"
        ]
        for expected in expected_templates:
            assert expected in templates, (
                f"{expected} not found in templates list"
            )

    def test_list_available_templates_only_html(self):
        """Test that only HTML files are listed."""
        templates = list_available_templates()
        
        for template in templates:
            assert template.endswith(".html")

    @pytest.mark.parametrize("template_name", [
        "index.html",
        "login.html",
        "setup.html",
        "queue.html",
        "error.html"
    ])
    def test_all_required_templates_exist(self, template_name):
        """Test that all required templates exist."""
        assert validate_template_exists(template_name), \
            f"Required template {template_name} does not exist"


class TestSeriesContextHelpers:
    """Test series context helper functions.

    These tests verify that series helpers use `key` as the primary
    identifier following the project's identifier convention.
    """

    def test_prepare_series_context_uses_key(self):
        """Test that prepare_series_context uses key as primary identifier."""
        series_data = [
            {
                "key": "attack-on-titan",
                "name": "Attack on Titan",
                "folder": "Attack on Titan (2013)",
            },
            {
                "key": "one-piece",
                "name": "One Piece",
                "folder": "One Piece (1999)",
            },
        ]
        prepared = prepare_series_context(series_data)

        assert len(prepared) == 2
        # Verify key is present and used
        assert prepared[0]["key"] in ("attack-on-titan", "one-piece")
        assert all("key" in item for item in prepared)
        assert all("folder" in item for item in prepared)

    def test_prepare_series_context_sorts_by_name(self):
        """Test that series are sorted by name by default."""
        series_data = [
            {"key": "z-series", "name": "Zebra Anime", "folder": "z"},
            {"key": "a-series", "name": "Alpha Anime", "folder": "a"},
        ]
        prepared = prepare_series_context(series_data, sort_by="name")

        assert prepared[0]["name"] == "Alpha Anime"
        assert prepared[1]["name"] == "Zebra Anime"

    def test_prepare_series_context_sorts_by_key(self):
        """Test that series can be sorted by key."""
        series_data = [
            {"key": "z-series", "name": "Zebra", "folder": "z"},
            {"key": "a-series", "name": "Alpha", "folder": "a"},
        ]
        prepared = prepare_series_context(series_data, sort_by="key")

        assert prepared[0]["key"] == "a-series"
        assert prepared[1]["key"] == "z-series"

    def test_prepare_series_context_empty_list(self):
        """Test prepare_series_context with empty list."""
        prepared = prepare_series_context([])
        assert prepared == []

    def test_prepare_series_context_skips_missing_key(self):
        """Test that items without key are skipped with warning."""
        series_data = [
            {"key": "valid-series", "name": "Valid", "folder": "valid"},
            {"name": "No Key", "folder": "nokey"},  # Missing key
        ]
        prepared = prepare_series_context(series_data)

        assert len(prepared) == 1
        assert prepared[0]["key"] == "valid-series"

    def test_prepare_series_context_preserves_extra_fields(self):
        """Test that extra fields are preserved."""
        series_data = [
            {
                "key": "test",
                "name": "Test",
                "folder": "test",
                "missing_episodes": {"1": [1, 2]},
                "site": "aniworld.to",
            }
        ]
        prepared = prepare_series_context(series_data)

        assert prepared[0]["missing_episodes"] == {"1": [1, 2]}
        assert prepared[0]["site"] == "aniworld.to"

    def test_get_series_by_key_found(self):
        """Test finding a series by key."""
        series_data = [
            {"key": "attack-on-titan", "name": "Attack on Titan"},
            {"key": "one-piece", "name": "One Piece"},
        ]
        result = get_series_by_key(series_data, "attack-on-titan")

        assert result is not None
        assert result["name"] == "Attack on Titan"

    def test_get_series_by_key_not_found(self):
        """Test that None is returned when key not found."""
        series_data = [
            {"key": "attack-on-titan", "name": "Attack on Titan"},
        ]
        result = get_series_by_key(series_data, "non-existent")

        assert result is None

    def test_get_series_by_key_empty_list(self):
        """Test get_series_by_key with empty list."""
        result = get_series_by_key([], "any-key")
        assert result is None

    def test_filter_series_by_missing_episodes(self):
        """Test filtering series with missing episodes."""
        series_data = [
            {
                "key": "has-missing",
                "name": "Has Missing",
                "missing_episodes": {"1": [1, 2, 3]},
            },
            {
                "key": "no-missing",
                "name": "No Missing",
                "missing_episodes": {},
            },
            {
                "key": "empty-seasons",
                "name": "Empty Seasons",
                "missing_episodes": {"1": [], "2": []},
            },
        ]
        filtered = filter_series_by_missing_episodes(series_data)

        assert len(filtered) == 1
        assert filtered[0]["key"] == "has-missing"

    def test_filter_series_by_missing_episodes_empty(self):
        """Test filter with empty list."""
        filtered = filter_series_by_missing_episodes([])
        assert filtered == []

    def test_filter_preserves_key_identifier(self):
        """Test that filter preserves key as identifier."""
        series_data = [
            {
                "key": "test-series",
                "folder": "Test Series (2020)",
                "name": "Test",
                "missing_episodes": {"1": [1]},
            }
        ]
        filtered = filter_series_by_missing_episodes(series_data)

        assert filtered[0]["key"] == "test-series"
        assert filtered[0]["folder"] == "Test Series (2020)"
