# tests/integration/middleware/test_theme_loading_flow.py
"""
Integration tests for theme loading end-to-end flow.

These tests verify that vendor themes are correctly loaded and injected
into request.state through real HTTP requests.

Note: These tests use pre-registered routes in middleware_test_routes.py.
The conftest patches get_db and settings.platform_domain for proper testing.
"""

import pytest


@pytest.mark.integration
@pytest.mark.middleware
@pytest.mark.theme
class TestThemeLoadingFlow:
    """Test theme loading through real HTTP requests."""

    # ========================================================================
    # Basic Theme Loading Tests
    # ========================================================================

    def test_theme_loaded_for_vendor_with_custom_theme(self, client, vendor_with_theme):
        """Test that custom theme is loaded for vendor with theme."""
        response = client.get(
            "/middleware-test/theme-loading",
            headers={"host": f"{vendor_with_theme.subdomain}.platform.com"},
        )

        assert response.status_code == 200
        data = response.json()
        assert data["has_theme"] is True
        assert data["theme_data"] is not None
        # Colors are flattened to root level by the route
        assert data["primary_color"] == "#FF5733"
        assert data["secondary_color"] == "#33FF57"

    def test_default_theme_loaded_for_vendor_without_theme(
        self, client, vendor_with_subdomain
    ):
        """Test that default theme is loaded for vendor without custom theme."""
        response = client.get(
            "/middleware-test/theme-default",
            headers={"host": f"{vendor_with_subdomain.subdomain}.platform.com"},
        )

        assert response.status_code == 200
        data = response.json()
        assert data["has_theme"] is True
        # Default theme should have basic structure
        assert data["theme_data"] is not None
        # Colors are flattened to root level by the route
        assert data["primary_color"] is not None
        assert data["secondary_color"] is not None

    def test_no_theme_loaded_without_vendor(self, client):
        """Test that no theme is loaded when there's no vendor."""
        response = client.get(
            "/middleware-test/theme-no-vendor", headers={"host": "platform.com"}
        )

        assert response.status_code == 200
        data = response.json()
        assert data["has_vendor"] is False
        # No vendor means middleware doesn't set theme (or sets default)
        # The actual behavior depends on ThemeContextMiddleware implementation

    # ========================================================================
    # Theme Structure Tests
    # ========================================================================

    def test_custom_theme_contains_all_fields(self, client, vendor_with_theme):
        """Test that custom theme contains all expected fields."""
        response = client.get(
            "/middleware-test/theme-fields",
            headers={"host": f"{vendor_with_theme.subdomain}.platform.com"},
        )

        assert response.status_code == 200
        data = response.json()
        assert data["primary_color"] == "#FF5733"
        assert data["secondary_color"] == "#33FF57"
        assert data["logo_url"] == "/static/vendors/themedvendor/logo.png"
        assert data["favicon_url"] == "/static/vendors/themedvendor/favicon.ico"
        assert "background" in data["custom_css"]

    def test_default_theme_structure(self, client, vendor_with_subdomain):
        """Test that default theme has expected structure."""
        response = client.get(
            "/middleware-test/theme-structure",
            headers={"host": f"{vendor_with_subdomain.subdomain}.platform.com"},
        )

        assert response.status_code == 200
        data = response.json()
        # Default theme should have basic structure
        assert data["has_primary_color"] is True
        assert data["has_secondary_color"] is True

    # ========================================================================
    # Theme Loading for Different Contexts Tests
    # ========================================================================

    def test_theme_loaded_in_shop_context(self, client, vendor_with_theme):
        """Test that theme is loaded in SHOP context."""
        response = client.get(
            "/shop/middleware-test/theme",
            headers={"host": f"{vendor_with_theme.subdomain}.platform.com"},
        )

        assert response.status_code == 200
        data = response.json()
        assert data["context_type"] == "shop"
        assert data["has_theme"] is True
        assert data["theme_primary"] == "#FF5733"

    # Note: Theme loading in vendor dashboard context is tested via unit tests in
    # tests/unit/middleware/test_theme_context.py since /vendor/* integration test
    # routes are shadowed by the catch-all /vendor/{vendor_code}/{slug} route.

    def test_theme_loaded_in_api_context_with_vendor(self, client, vendor_with_theme):
        """Test API context detection and theme behavior with vendor subdomain.

        Note: For API context, vendor detection from subdomain may be skipped
        depending on middleware configuration. This test verifies the context
        is correctly set to 'api' regardless of vendor detection.
        """
        response = client.get(
            "/api/middleware-test/theme",
            headers={"host": f"{vendor_with_theme.subdomain}.platform.com"},
        )

        assert response.status_code == 200
        data = response.json()
        assert data["context_type"] == "api"
        # Vendor and theme detection for API routes depends on middleware config
        # The important assertion is that context_type is correctly set to 'api'

    def test_no_theme_in_admin_context(self, client):
        """Test theme behavior in ADMIN context (no vendor)."""
        response = client.get("/admin/middleware-test/no-theme")

        assert response.status_code == 200
        data = response.json()
        assert data["context_type"] == "admin"
        # Admin context has no vendor - theme behavior depends on middleware config

    # ========================================================================
    # Theme Loading with Different Routing Modes Tests
    # ========================================================================

    def test_theme_loaded_with_subdomain_routing(self, client, vendor_with_theme):
        """Test theme loading with subdomain routing."""
        response = client.get(
            "/middleware-test/theme-fields",
            headers={"host": f"{vendor_with_theme.subdomain}.platform.com"},
        )

        assert response.status_code == 200
        data = response.json()
        assert data["logo_url"] == "/static/vendors/themedvendor/logo.png"

    def test_theme_loaded_with_custom_domain_routing(
        self, client, vendor_with_custom_domain, db
    ):
        """Test theme loading behavior with custom domain routing.

        Note: Custom domain detection requires the domain to be verified in the
        database. This test verifies the theme loading mechanism when a custom
        domain is used.
        """
        from models.database.vendor_theme import VendorTheme

        # Add theme to custom domain vendor
        theme = VendorTheme(
            vendor_id=vendor_with_custom_domain.id,
            colors={
                "primary": "#123456",
                "secondary": "#654321",
                "accent": "#ec4899",
                "background": "#ffffff",
                "text": "#1f2937",
                "border": "#e5e7eb",
            },
        )
        db.add(theme)
        db.commit()

        response = client.get(
            "/middleware-test/theme-loading", headers={"host": "customdomain.com"}
        )

        assert response.status_code == 200
        data = response.json()
        # Custom domain vendor detection depends on domain verification status
        # If vendor is detected and has custom theme, verify it's loaded
        # Otherwise, default theme may be applied

    # ========================================================================
    # Theme Dependency on Vendor Context Tests
    # ========================================================================

    def test_theme_middleware_depends_on_vendor_middleware(
        self, client, vendor_with_theme
    ):
        """Test that theme loading depends on vendor being detected first."""
        response = client.get(
            "/middleware-test/theme-vendor-dependency",
            headers={"host": f"{vendor_with_theme.subdomain}.platform.com"},
        )

        assert response.status_code == 200
        data = response.json()
        assert data["has_vendor"] is True
        assert data["vendor_id"] == vendor_with_theme.id
        assert data["has_theme"] is True

    # ========================================================================
    # Theme Caching and Performance Tests
    # ========================================================================

    def test_theme_loaded_consistently_across_requests(self, client, vendor_with_theme):
        """Test that theme is loaded consistently across multiple requests."""
        # Make multiple requests
        responses = []
        for _ in range(3):
            response = client.get(
                "/middleware-test/theme-consistency",
                headers={"host": f"{vendor_with_theme.subdomain}.platform.com"},
            )
            responses.append(response.json())

        # All responses should have same theme
        assert all(r["theme_primary"] == "#FF5733" for r in responses)

    # ========================================================================
    # Edge Cases and Error Handling Tests
    # ========================================================================

    def test_theme_gracefully_handles_missing_theme_fields(
        self, client, vendor_with_subdomain
    ):
        """Test that missing theme fields are handled gracefully."""
        response = client.get(
            "/middleware-test/theme-partial",
            headers={"host": f"{vendor_with_subdomain.subdomain}.platform.com"},
        )

        assert response.status_code == 200
        data = response.json()
        assert data["has_theme"] is True
        # Should have defaults for missing fields (route provides "default" fallback)
        assert data["primary_color"] is not None

    def test_theme_dict_is_mutable(self, client, vendor_with_theme):
        """Test that theme dict can be accessed and read from."""
        response = client.get(
            "/middleware-test/theme-mutable",
            headers={"host": f"{vendor_with_theme.subdomain}.platform.com"},
        )

        assert response.status_code == 200
        data = response.json()
        assert data["can_read"] is True
        assert data["value"] == "#FF5733"
