# app/modules/core/tests/integration/test_onboarding_routes.py
"""
Integration tests for the onboarding API endpoint.

Tests the store dashboard onboarding endpoint at:
    GET /api/v1/store/dashboard/onboarding

Verifies:
- Endpoint returns onboarding steps with completion status
- Endpoint requires store authentication
- Response structure matches expected schema
"""

import uuid

import pytest

from app.api.deps import get_current_store_api, require_platform
from app.modules.tenancy.models import Merchant, Platform, Store, User
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 onb_owner(db):
    """Create a store owner user for onboarding tests."""
    from middleware.auth import AuthManager

    auth = AuthManager()
    user = User(
        email=f"onbroute_{uuid.uuid4().hex[:8]}@test.com",
        username=f"onbroute_{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 onb_platform(db):
    """Create a platform for onboarding tests."""
    platform = Platform(
        code=f"onbp_{uuid.uuid4().hex[:8]}",
        name="Onboarding Test Platform",
        is_active=True,
    )
    db.add(platform)
    db.commit()
    db.refresh(platform)
    return platform


@pytest.fixture
def onb_merchant(db, onb_owner):
    """Create a merchant for onboarding tests."""
    merchant = Merchant(
        name="Onboarding Route Test Merchant",
        owner_user_id=onb_owner.id,
        contact_email=onb_owner.email,
        is_active=True,
        is_verified=True,
    )
    db.add(merchant)
    db.commit()
    db.refresh(merchant)
    return merchant


@pytest.fixture
def onb_store(db, onb_merchant):
    """Create a store for onboarding tests."""
    uid = uuid.uuid4().hex[:8]
    store = Store(
        merchant_id=onb_merchant.id,
        store_code=f"ONBROUTE_{uid.upper()}",
        subdomain=f"onbroute{uid.lower()}",
        name="Onboarding Route Test Store",
        is_active=True,
        is_verified=True,
    )
    db.add(store)
    db.commit()
    db.refresh(store)
    return store


@pytest.fixture
def onb_store_platform(db, onb_store, onb_platform):
    """Link store to platform."""
    sp = StorePlatform(
        store_id=onb_store.id,
        platform_id=onb_platform.id,
        is_active=True,
    )
    db.add(sp)
    db.commit()
    db.refresh(sp)
    return sp


@pytest.fixture
def onb_auth(onb_owner, onb_store, onb_platform):
    """Override auth dependency for store API auth."""
    user_context = UserContext(
        id=onb_owner.id,
        email=onb_owner.email,
        username=onb_owner.username,
        role="merchant_owner",
        is_active=True,
        token_store_id=onb_store.id,
        token_store_code=onb_store.store_code,
    )

    def _override():
        return user_context

    def _override_platform():
        return onb_platform

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


# ============================================================================
# Tests
# ============================================================================


@pytest.mark.integration
@pytest.mark.core
class TestOnboardingEndpoint:
    """Tests for GET /api/v1/store/dashboard/onboarding."""

    def test_returns_onboarding_summary(
        self, client, db, onb_auth, onb_store, onb_store_platform
    ):
        """Endpoint returns onboarding summary with expected structure."""
        response = client.get(
            "/api/v1/store/dashboard/onboarding",
            headers=onb_auth,
        )
        assert response.status_code == 200

        data = response.json()
        assert "steps" in data
        assert "total_steps" in data
        assert "completed_steps" in data
        assert "progress_percentage" in data
        assert "all_completed" in data
        assert isinstance(data["steps"], list)
        assert isinstance(data["total_steps"], int)
        assert isinstance(data["completed_steps"], int)

    def test_includes_tenancy_step(
        self, client, db, onb_auth, onb_store, onb_store_platform
    ):
        """Response includes the tenancy customize_store step (always present)."""
        response = client.get(
            "/api/v1/store/dashboard/onboarding",
            headers=onb_auth,
        )
        assert response.status_code == 200

        data = response.json()
        step_keys = [s["key"] for s in data["steps"]]
        assert "tenancy.customize_store" in step_keys

    def test_step_data_has_required_fields(
        self, client, db, onb_auth, onb_store, onb_store_platform
    ):
        """Each step has key, title_key, description_key, icon, route, completed."""
        response = client.get(
            "/api/v1/store/dashboard/onboarding",
            headers=onb_auth,
        )
        data = response.json()

        for step in data["steps"]:
            assert "key" in step
            assert "title_key" in step
            assert "description_key" in step
            assert "icon" in step
            assert "route" in step
            assert "completed" in step
            assert isinstance(step["completed"], bool)

    def test_routes_contain_store_code(
        self, client, db, onb_auth, onb_store, onb_store_platform
    ):
        """Step routes have {store_code} replaced with the actual store code."""
        response = client.get(
            "/api/v1/store/dashboard/onboarding",
            headers=onb_auth,
        )
        data = response.json()

        for step in data["steps"]:
            assert "{store_code}" not in step["route"]
            if "/store/" in step["route"]:
                assert onb_store.store_code in step["route"]

    def test_requires_auth(self, client, onb_platform):
        """Returns 401 without authentication."""
        app.dependency_overrides.pop(get_current_store_api, None)
        app.dependency_overrides[require_platform] = lambda: onb_platform
        try:
            response = client.get(
                "/api/v1/store/dashboard/onboarding",
            )
            assert response.status_code == 401
        finally:
            app.dependency_overrides.pop(require_platform, None)
