# app/modules/marketplace/tests/integration/test_store_page_routes.py
"""
Integration tests for marketplace store page routes.

Tests the onboarding, marketplace, and letzshop page routes at:
    GET /store/{store_code}/onboarding
    GET /store/{store_code}/marketplace
    GET /store/{store_code}/letzshop

Verifies:
- Onboarding page redirects to dashboard on non-marketplace platforms
- Onboarding page redirects to dashboard when already completed
- Onboarding page renders when marketplace enabled and not completed
- Marketplace/Letzshop pages redirect to onboarding when not completed
- Marketplace/Letzshop pages render when onboarding is completed
"""

import uuid
from datetime import UTC, datetime

import pytest

from app.api.deps import get_current_store_from_cookie_or_header
from app.modules.marketplace.models import OnboardingStatus, StoreOnboarding
from app.modules.tenancy.models import Merchant, Platform, Store, User
from app.modules.tenancy.models.platform_module import PlatformModule
from app.modules.tenancy.models.store_platform import StorePlatform
from app.modules.tenancy.schemas.auth import UserContext
from main import app

# ============================================================================
# Fixtures
# ============================================================================


@pytest.fixture
def mp_admin(db):
    """Create an admin user for enabling modules."""
    from middleware.auth import AuthManager

    auth = AuthManager()
    user = User(
        email=f"mpadmin_{uuid.uuid4().hex[:8]}@test.com",
        username=f"mpadmin_{uuid.uuid4().hex[:8]}",
        hashed_password=auth.hash_password("pass123"),
        role="super_admin",
        is_active=True,
    )
    db.add(user)
    db.commit()
    db.refresh(user)
    return user


@pytest.fixture
def mp_owner(db):
    """Create a store owner user."""
    from middleware.auth import AuthManager

    auth = AuthManager()
    user = User(
        email=f"mpowner_{uuid.uuid4().hex[:8]}@test.com",
        username=f"mpowner_{uuid.uuid4().hex[:8]}",
        hashed_password=auth.hash_password("pass123"),
        role="merchant_owner",
        is_active=True,
    )
    db.add(user)
    db.commit()
    db.refresh(user)
    return user


@pytest.fixture
def mp_platform_no_marketplace(db):
    """Create a platform without marketplace module enabled."""
    platform = Platform(
        code=f"mpnm_{uuid.uuid4().hex[:8]}",
        name="No Marketplace Platform",
        is_active=True,
    )
    db.add(platform)
    db.commit()
    db.refresh(platform)
    return platform


@pytest.fixture
def mp_platform_with_marketplace(db, mp_admin):
    """Create a platform with marketplace module enabled."""
    platform = Platform(
        code=f"mpmk_{uuid.uuid4().hex[:8]}",
        name="Marketplace Platform",
        is_active=True,
    )
    db.add(platform)
    db.flush()

    pm = PlatformModule(
        platform_id=platform.id,
        module_code="marketplace",
        is_enabled=True,
        enabled_at=datetime.now(UTC),
        enabled_by_user_id=mp_admin.id,
        config={},
    )
    db.add(pm)
    db.commit()
    db.refresh(platform)
    return platform


@pytest.fixture
def mp_merchant(db, mp_owner):
    """Create a merchant."""
    merchant = Merchant(
        name="MP Test Merchant",
        owner_user_id=mp_owner.id,
        contact_email=mp_owner.email,
        is_active=True,
        is_verified=True,
    )
    db.add(merchant)
    db.commit()
    db.refresh(merchant)
    return merchant


@pytest.fixture
def mp_store(db, mp_merchant):
    """Create a store."""
    uid = uuid.uuid4().hex[:8]
    store = Store(
        merchant_id=mp_merchant.id,
        store_code=f"MPSTORE_{uid.upper()}",
        subdomain=f"mpstore{uid.lower()}",
        name="MP Test Store",
        is_active=True,
        is_verified=True,
    )
    db.add(store)
    db.commit()
    db.refresh(store)
    return store


@pytest.fixture
def mp_store_no_marketplace(db, mp_store, mp_platform_no_marketplace):
    """Link store to a platform without marketplace."""
    sp = StorePlatform(
        store_id=mp_store.id,
        platform_id=mp_platform_no_marketplace.id,
        is_active=True,
    )
    db.add(sp)
    db.commit()
    db.refresh(sp)
    return sp


@pytest.fixture
def mp_store_with_marketplace(db, mp_store, mp_platform_with_marketplace):
    """Link store to a platform with marketplace enabled."""
    sp = StorePlatform(
        store_id=mp_store.id,
        platform_id=mp_platform_with_marketplace.id,
        is_active=True,
    )
    db.add(sp)
    db.commit()
    db.refresh(sp)
    return sp


@pytest.fixture
def mp_onboarding_not_completed(db, mp_store):
    """Create an incomplete onboarding record for the store."""
    onboarding = StoreOnboarding(
        store_id=mp_store.id,
        status=OnboardingStatus.IN_PROGRESS.value,
    )
    db.add(onboarding)
    db.commit()
    db.refresh(onboarding)
    return onboarding


@pytest.fixture
def mp_onboarding_completed(db, mp_store):
    """Create a completed onboarding record for the store."""
    onboarding = StoreOnboarding(
        store_id=mp_store.id,
        status=OnboardingStatus.COMPLETED.value,
        step_merchant_profile_completed=True,
        step_letzshop_api_completed=True,
        step_product_import_completed=True,
        step_order_sync_completed=True,
    )
    db.add(onboarding)
    db.commit()
    db.refresh(onboarding)
    return onboarding


@pytest.fixture
def mp_auth(mp_owner, mp_store):
    """Override auth dependency for store cookie/header auth."""
    user_context = UserContext(
        id=mp_owner.id,
        email=mp_owner.email,
        username=mp_owner.username,
        role="merchant_owner",
        is_active=True,
        token_store_id=mp_store.id,
        token_store_code=mp_store.store_code,
    )

    def _override():
        return user_context

    app.dependency_overrides[get_current_store_from_cookie_or_header] = _override
    yield {"Authorization": "Bearer fake-token"}
    app.dependency_overrides.pop(get_current_store_from_cookie_or_header, None)


# ============================================================================
# Onboarding page tests
# ============================================================================


@pytest.mark.integration
@pytest.mark.marketplace
class TestOnboardingPageRoutes:
    """Tests for GET /store/{store_code}/onboarding."""

    def test_redirects_to_dashboard_on_non_marketplace_platform(
        self, client, db, mp_auth, mp_store, mp_store_no_marketplace
    ):
        """Onboarding page redirects to dashboard on platform without marketplace."""
        response = client.get(
            f"/store/{mp_store.subdomain}/onboarding",
            headers=mp_auth,
            follow_redirects=False,
        )
        assert response.status_code == 302
        assert f"/store/{mp_store.subdomain}/dashboard" in response.headers["location"]

    def test_redirects_to_dashboard_when_onboarding_completed(
        self, client, db, mp_auth, mp_store, mp_store_with_marketplace,
        mp_onboarding_completed,
    ):
        """Onboarding page redirects to dashboard when already completed."""
        response = client.get(
            f"/store/{mp_store.subdomain}/onboarding",
            headers=mp_auth,
            follow_redirects=False,
        )
        assert response.status_code == 302
        assert f"/store/{mp_store.subdomain}/dashboard" in response.headers["location"]

    def test_renders_onboarding_when_not_completed(
        self, client, db, mp_auth, mp_store, mp_store_with_marketplace,
        mp_onboarding_not_completed,
    ):
        """Onboarding page renders wizard when marketplace enabled and not completed."""
        response = client.get(
            f"/store/{mp_store.subdomain}/onboarding",
            headers=mp_auth,
            follow_redirects=False,
        )
        assert response.status_code == 200

    def test_renders_onboarding_when_no_onboarding_record(
        self, client, db, mp_auth, mp_store, mp_store_with_marketplace,
    ):
        """Onboarding page renders wizard when marketplace enabled and no record exists."""
        # No mp_onboarding_* fixture — is_completed() returns False for missing record
        response = client.get(
            f"/store/{mp_store.subdomain}/onboarding",
            headers=mp_auth,
            follow_redirects=False,
        )
        assert response.status_code == 200

    def test_requires_auth(self, client):
        """Returns 401 without auth."""
        app.dependency_overrides.pop(get_current_store_from_cookie_or_header, None)
        response = client.get(
            "/store/anystore/onboarding",
            follow_redirects=False,
        )
        assert response.status_code == 401


# ============================================================================
# Marketplace page tests
# ============================================================================


@pytest.mark.integration
@pytest.mark.marketplace
class TestMarketplacePageRoutes:
    """Tests for GET /store/{store_code}/marketplace."""

    def test_renders_when_onboarding_completed(
        self, client, db, mp_auth, mp_store, mp_store_with_marketplace,
        mp_onboarding_completed,
    ):
        """Marketplace page renders when onboarding is completed."""
        response = client.get(
            f"/store/{mp_store.subdomain}/marketplace",
            headers=mp_auth,
            follow_redirects=False,
        )
        assert response.status_code == 200


# ============================================================================
# Letzshop page tests
# ============================================================================


@pytest.mark.integration
@pytest.mark.marketplace
class TestLetzshopPageRoutes:
    """Tests for GET /store/{store_code}/letzshop."""

    def test_renders_when_onboarding_completed(
        self, client, db, mp_auth, mp_store, mp_store_with_marketplace,
        mp_onboarding_completed,
    ):
        """Letzshop page renders when onboarding is completed."""
        response = client.get(
            f"/store/{mp_store.subdomain}/letzshop",
            headers=mp_auth,
            follow_redirects=False,
        )
        assert response.status_code == 200
