# tests/unit/test_exception_handler.py
"""
Unit tests for exception handler login redirect.

Tests the _redirect_to_login function to ensure correct URL generation
for storefront contexts, preventing double 'storefront/' in redirects.
"""

from unittest.mock import Mock

import pytest
from fastapi import Request

from app.exceptions.handler import _redirect_to_login
from app.modules.enums import FrontendType


def _make_request(
    path="/storefront/FASHIONHUB/account/dashboard",
    frontend_type=FrontendType.STOREFRONT,
    store=None,
    store_context=None,
    platform=None,
    platform_original_path=None,
):
    request = Mock(spec=Request)
    request.url = Mock(path=path)
    request.method = "GET"
    request.headers = {"accept": "text/html"}
    request.state = Mock()
    request.state.frontend_type = frontend_type
    request.state.store = store
    request.state.store_context = store_context
    request.state.platform = platform
    request.state.platform_original_path = platform_original_path
    return request


def _make_store(store_code="FASHIONHUB", subdomain="fashionhub"):
    store = Mock()
    store.store_code = store_code
    store.subdomain = subdomain
    return store


def _make_platform(code="loyalty"):
    platform = Mock()
    platform.code = code
    return platform


@pytest.mark.unit
class TestRedirectToLogin:
    """Tests for _redirect_to_login storefront URL generation."""

    def test_storefront_redirect_dev_mode_no_double_storefront(self):
        """Dev mode redirect should not have double 'storefront/' in URL."""
        store = _make_store(store_code="FASHIONHUB")
        platform = _make_platform(code="loyalty")
        store_context = {"detection_method": "path", "full_prefix": "/storefront/"}

        request = _make_request(
            store=store,
            store_context=store_context,
            platform=platform,
            platform_original_path="/platforms/loyalty/storefront/FASHIONHUB/account/dashboard",
        )

        response = _redirect_to_login(request)

        assert response.status_code == 302
        location = response.headers["location"]
        assert location == "/platforms/loyalty/storefront/FASHIONHUB/account/login"
        assert "/storefront/storefront/" not in location

    def test_storefront_redirect_prod_mode(self):
        """Prod mode redirect should use /account/login."""
        store = _make_store()
        store_context = {"detection_method": "subdomain", "subdomain": "fashionhub"}

        request = _make_request(
            store=store,
            store_context=store_context,
        )

        response = _redirect_to_login(request)

        assert response.status_code == 302
        location = response.headers["location"]
        assert location == "/account/login"

    def test_storefront_redirect_uses_store_code_not_subdomain(self):
        """Redirect URL should use store_code (uppercase), not subdomain (lowercase)."""
        store = _make_store(store_code="FASHIONHUB", subdomain="fashionhub")
        platform = _make_platform(code="loyalty")
        store_context = {"detection_method": "path", "full_prefix": "/storefront/"}

        request = _make_request(
            store=store,
            store_context=store_context,
            platform=platform,
            platform_original_path="/platforms/loyalty/storefront/FASHIONHUB/dashboard",
        )

        response = _redirect_to_login(request)

        location = response.headers["location"]
        assert "FASHIONHUB" in location
        assert "fashionhub" not in location

    def test_admin_redirect(self):
        """Admin requests redirect to /admin/login."""
        request = _make_request(frontend_type=FrontendType.ADMIN)

        response = _redirect_to_login(request)

        assert response.headers["location"] == "/admin/login"

    def test_merchant_redirect(self):
        """Merchant requests redirect to /merchants/login."""
        request = _make_request(frontend_type=FrontendType.MERCHANT)

        response = _redirect_to_login(request)

        assert response.headers["location"] == "/merchants/login"
