# app/modules/marketplace/tests/unit/test_store_page_routes.py
"""
Unit tests for marketplace store page routes.

Tests the onboarding, marketplace, and letzshop page route logic:
- Onboarding page guards (marketplace module check, completion redirect)
- Marketplace page onboarding gate
- Letzshop page onboarding gate
"""

from unittest.mock import MagicMock, patch

import pytest
from fastapi import Request
from fastapi.responses import RedirectResponse

from app.modules.marketplace.routes.pages.store import (
    store_letzshop_page,
    store_marketplace_page,
    store_onboarding_page,
)
from app.modules.tenancy.schemas.auth import UserContext


def _make_user_context(store_id: int = 1, store_code: str = "teststore") -> UserContext:
    """Create a UserContext for testing."""
    return UserContext(
        id=1,
        email="test@test.com",
        username="testuser",
        role="merchant_owner",
        is_active=True,
        token_store_id=store_id,
        token_store_code=store_code,
    )


def _make_request() -> MagicMock:
    """Create a mock Request."""
    return MagicMock(spec=Request)


# ============================================================================
# ONBOARDING PAGE
# ============================================================================


@pytest.mark.unit
@pytest.mark.marketplace
@pytest.mark.asyncio
class TestOnboardingPageGuard:
    """Test that onboarding page redirects to dashboard when marketplace is not enabled."""

    @patch("app.modules.marketplace.routes.pages.store.module_service")
    @patch("app.modules.marketplace.routes.pages.store.get_store_context")
    @patch("app.modules.marketplace.routes.pages.store.templates")
    async def test_redirects_to_dashboard_when_no_store_platform(
        self, mock_templates, mock_ctx, mock_module_service, db
    ):
        """Redirect to dashboard if store has no StorePlatform record."""
        user = _make_user_context(store_id=99999)
        response = await store_onboarding_page(
            request=_make_request(),
            store_code="teststore",
            current_user=user,
            db=db,
        )
        assert isinstance(response, RedirectResponse)
        assert response.status_code == 302
        assert "/store/teststore/dashboard" in response.headers["location"]

    @patch("app.modules.marketplace.routes.pages.store.module_service")
    @patch("app.modules.marketplace.routes.pages.store.get_store_context")
    @patch("app.modules.marketplace.routes.pages.store.templates")
    async def test_redirects_to_dashboard_when_marketplace_not_enabled(
        self, mock_templates, mock_ctx, mock_module_service, db, test_store
    ):
        """Redirect to dashboard if marketplace module is not enabled on platform."""
        from app.modules.tenancy.models import Platform
        from app.modules.tenancy.models.store_platform import StorePlatform

        platform = Platform(code="nomarket", name="No Marketplace", is_active=True)
        db.add(platform)
        db.flush()

        sp = StorePlatform(store_id=test_store.id, platform_id=platform.id, is_active=True)
        db.add(sp)
        db.commit()

        mock_module_service.is_module_enabled.return_value = False

        user = _make_user_context(store_id=test_store.id)
        response = await store_onboarding_page(
            request=_make_request(),
            store_code="teststore",
            current_user=user,
            db=db,
        )
        assert isinstance(response, RedirectResponse)
        assert response.status_code == 302
        assert "/store/teststore/dashboard" in response.headers["location"]
        mock_module_service.is_module_enabled.assert_called_once_with(
            db, platform.id, "marketplace"
        )

    @patch("app.modules.marketplace.routes.pages.store.OnboardingService")
    @patch("app.modules.marketplace.routes.pages.store.module_service")
    @patch("app.modules.marketplace.routes.pages.store.get_store_context")
    @patch("app.modules.marketplace.routes.pages.store.templates")
    async def test_redirects_to_dashboard_when_onboarding_completed(
        self, mock_templates, mock_ctx, mock_module_service, mock_onboarding_cls, db, test_store
    ):
        """Redirect to dashboard if onboarding is already completed."""
        from app.modules.tenancy.models import Platform
        from app.modules.tenancy.models.store_platform import StorePlatform

        platform = Platform(code="mktplace", name="Marketplace", is_active=True)
        db.add(platform)
        db.flush()

        sp = StorePlatform(store_id=test_store.id, platform_id=platform.id, is_active=True)
        db.add(sp)
        db.commit()

        mock_module_service.is_module_enabled.return_value = True
        mock_svc = MagicMock()
        mock_svc.is_completed.return_value = True
        mock_onboarding_cls.return_value = mock_svc

        user = _make_user_context(store_id=test_store.id)
        response = await store_onboarding_page(
            request=_make_request(),
            store_code="teststore",
            current_user=user,
            db=db,
        )
        assert isinstance(response, RedirectResponse)
        assert response.status_code == 302
        assert "/store/teststore/dashboard" in response.headers["location"]

    @patch("app.modules.marketplace.routes.pages.store.OnboardingService")
    @patch("app.modules.marketplace.routes.pages.store.module_service")
    @patch("app.modules.marketplace.routes.pages.store.get_store_context")
    @patch("app.modules.marketplace.routes.pages.store.templates")
    async def test_renders_onboarding_when_marketplace_enabled_and_not_completed(
        self, mock_templates, mock_ctx, mock_module_service, mock_onboarding_cls, db, test_store
    ):
        """Render onboarding wizard when marketplace enabled and onboarding not completed."""
        from app.modules.tenancy.models import Platform
        from app.modules.tenancy.models.store_platform import StorePlatform

        platform = Platform(code="mktplace2", name="Marketplace 2", is_active=True)
        db.add(platform)
        db.flush()

        sp = StorePlatform(store_id=test_store.id, platform_id=platform.id, is_active=True)
        db.add(sp)
        db.commit()

        mock_module_service.is_module_enabled.return_value = True
        mock_svc = MagicMock()
        mock_svc.is_completed.return_value = False
        mock_onboarding_cls.return_value = mock_svc

        mock_ctx.return_value = {"request": _make_request()}
        mock_templates.TemplateResponse.return_value = "rendered"

        user = _make_user_context(store_id=test_store.id)
        response = await store_onboarding_page(
            request=_make_request(),
            store_code="teststore",
            current_user=user,
            db=db,
        )
        assert response == "rendered"
        mock_templates.TemplateResponse.assert_called_once()
        template_name = mock_templates.TemplateResponse.call_args[0][0]
        assert template_name == "marketplace/store/onboarding.html"


# ============================================================================
# MARKETPLACE PAGE
# ============================================================================


@pytest.mark.unit
@pytest.mark.marketplace
@pytest.mark.asyncio
class TestMarketplacePageRendering:
    """Test that marketplace page renders correctly."""

    @patch("app.modules.marketplace.routes.pages.store.get_store_context")
    @patch("app.modules.marketplace.routes.pages.store.templates")
    async def test_renders_marketplace_page(
        self, mock_templates, mock_ctx, db
    ):
        """Render marketplace page."""
        mock_ctx.return_value = {"request": _make_request()}
        mock_templates.TemplateResponse.return_value = "rendered"

        user = _make_user_context()
        response = await store_marketplace_page(
            request=_make_request(),
            store_code="teststore",
            current_user=user,
            db=db,
        )
        assert response == "rendered"
        mock_templates.TemplateResponse.assert_called_once()
        template_name = mock_templates.TemplateResponse.call_args[0][0]
        assert template_name == "marketplace/store/marketplace.html"


# ============================================================================
# LETZSHOP PAGE
# ============================================================================


@pytest.mark.unit
@pytest.mark.marketplace
@pytest.mark.asyncio
class TestLetzshopPageRendering:
    """Test that letzshop page renders correctly."""

    @patch("app.modules.marketplace.routes.pages.store.get_store_context")
    @patch("app.modules.marketplace.routes.pages.store.templates")
    async def test_renders_letzshop_page(
        self, mock_templates, mock_ctx, db
    ):
        """Render letzshop page."""
        mock_ctx.return_value = {"request": _make_request()}
        mock_templates.TemplateResponse.return_value = "rendered"

        user = _make_user_context()
        response = await store_letzshop_page(
            request=_make_request(),
            store_code="teststore",
            current_user=user,
            db=db,
        )
        assert response == "rendered"
        mock_templates.TemplateResponse.assert_called_once()
        template_name = mock_templates.TemplateResponse.call_args[0][0]
        assert template_name == "marketplace/store/letzshop.html"
