"""
Tests for API filter and search parameter consistency.

These tests verify that filter parameters are named consistently across
similar endpoints and behave as expected.
"""

from django.test import TestCase
from rest_framework import status
from rest_framework.test import APIClient


class FilterParameterNamingTestCase(TestCase):
    """Tests for consistent filter parameter naming."""

    def setUp(self):
        """Set up test client."""
        self.client = APIClient()

    def test_range_filter_naming_convention(self):
        """Test that range filters use {field}_min/{field}_max naming."""
        # Test parks rating range filter
        response = self.client.get("/api/v1/parks/hybrid/", {"rating_min": 3.0, "rating_max": 5.0})
        # Should not return error for valid filter names
        self.assertIn(response.status_code, [status.HTTP_200_OK, status.HTTP_400_BAD_REQUEST])

    def test_search_parameter_naming(self):
        """Test that search parameter is named consistently."""
        response = self.client.get("/api/v1/parks/hybrid/", {"search": "cedar"})
        self.assertIn(response.status_code, [status.HTTP_200_OK, status.HTTP_400_BAD_REQUEST])

    def test_ordering_parameter_naming(self):
        """Test that ordering parameter is named consistently."""
        response = self.client.get("/api/v1/parks/hybrid/", {"ordering": "name"})
        self.assertIn(response.status_code, [status.HTTP_200_OK, status.HTTP_400_BAD_REQUEST])

    def test_ordering_descending_prefix(self):
        """Test that descending ordering uses - prefix."""
        response = self.client.get("/api/v1/parks/hybrid/", {"ordering": "-name"})
        self.assertIn(response.status_code, [status.HTTP_200_OK, status.HTTP_400_BAD_REQUEST])


class FilterBehaviorTestCase(TestCase):
    """Tests for consistent filter behavior."""

    def setUp(self):
        """Set up test client."""
        self.client = APIClient()

    def test_filter_combination_and_logic(self):
        """Test that multiple different filters use AND logic."""
        response = self.client.get("/api/v1/parks/hybrid/", {"rating_min": 4.0, "country": "us"})
        if response.status_code == status.HTTP_200_OK:
            data = response.json()
            # Results should match both criteria
            self.assertIn("success", data)

    def test_multi_select_filter_or_logic(self):
        """Test that multi-select filters within same field use OR logic."""
        response = self.client.get("/api/v1/rides/hybrid/", {"ride_type": "Coaster,Dark Ride"})
        if response.status_code == status.HTTP_200_OK:
            data = response.json()
            self.assertIn("success", data)

    def test_invalid_filter_value_returns_error(self):
        """Test that invalid filter values return appropriate error."""
        response = self.client.get("/api/v1/parks/hybrid/", {"rating_min": "not_a_number"})
        # Could be 200 (ignored) or 400 (validation error)
        self.assertIn(response.status_code, [status.HTTP_200_OK, status.HTTP_400_BAD_REQUEST])


class FilterMetadataTestCase(TestCase):
    """Tests for filter metadata endpoint consistency."""

    def setUp(self):
        """Set up test client."""
        self.client = APIClient()

    def test_parks_filter_metadata_structure(self):
        """Test parks filter metadata has expected structure."""
        response = self.client.get("/api/v1/parks/filter-metadata/")

        if response.status_code == status.HTTP_200_OK:
            data = response.json()
            self.assertIn("success", data)
            self.assertIn("data", data)

            if data.get("data"):
                metadata = data["data"]
                # Should have categorical and/or ranges
                self.assertTrue(
                    "categorical" in metadata
                    or "ranges" in metadata
                    or "total_count" in metadata
                    or "ordering_options" in metadata,
                    "Filter metadata should contain filter options",
                )

    def test_rides_filter_metadata_structure(self):
        """Test rides filter metadata has expected structure."""
        response = self.client.get("/api/v1/rides/filter-metadata/")

        if response.status_code == status.HTTP_200_OK:
            data = response.json()
            self.assertIn("success", data)
            self.assertIn("data", data)

    def test_filter_option_format(self):
        """Test that filter options have consistent format."""
        response = self.client.get("/api/v1/parks/filter-metadata/")

        if response.status_code == status.HTTP_200_OK:
            data = response.json()
            if data.get("data") and data["data"].get("categorical"):
                for _field, options in data["data"]["categorical"].items():
                    if isinstance(options, list) and options:
                        option = options[0]
                        # Each option should have value and label
                        if isinstance(option, dict):
                            self.assertIn("value", option)
                            self.assertIn("label", option)
