# tests/integration/api/v1/test_store_api_dashboard.py
"""
Integration tests for store dashboard API endpoints.

Tests cover:
1. Dashboard stats retrieval
2. Store-specific data isolation
3. Permission checks
4. Data accuracy
"""

import pytest

from app.modules.tenancy.models import Platform


@pytest.fixture
def _ensure_main_platform(db):
    """Ensure a 'main' platform exists for the PlatformContextMiddleware.

    The TestClient uses 'testserver' as Host, which the middleware treats as
    localhost and resolves to the 'main' platform via path_prefix lookup.
    """
    platform = db.query(Platform).filter(Platform.code == "main").first()
    if not platform:
        platform = Platform(
            code="main",
            name="Main Platform",
            path_prefix="main",
            is_active=True,
            is_public=True,
            default_language="en",
            supported_languages=["en"],
        )
        db.add(platform)
        db.commit()
    return platform


@pytest.mark.integration
@pytest.mark.api
@pytest.mark.store
@pytest.mark.usefixtures("_ensure_main_platform")
class TestStoreDashboardAPI:
    """Test store dashboard stats endpoint"""

    def test_get_dashboard_stats_structure(
        self, client, store_user_headers, test_store_with_store_user, db
    ):
        """Test dashboard stats returns correct data structure"""
        response = client.get(
            "/api/v1/store/dashboard/stats", headers=store_user_headers
        )

        assert response.status_code == 200
        data = response.json()

        # Verify top-level structure
        assert "store" in data
        assert "products" in data
        assert "orders" in data
        assert "customers" in data
        assert "revenue" in data

        # Verify store info
        assert "id" in data["store"]
        assert "name" in data["store"]
        assert "store_code" in data["store"]
        assert data["store"]["id"] == test_store_with_store_user.id

        # Verify products stats
        assert "total" in data["products"]
        assert "active" in data["products"]
        assert isinstance(data["products"]["total"], int)
        assert isinstance(data["products"]["active"], int)

        # Verify orders stats
        assert "total" in data["orders"]
        assert "pending" in data["orders"]
        assert "completed" in data["orders"]

        # Verify customers stats
        assert "total" in data["customers"]
        assert "active" in data["customers"]

        # Verify revenue stats
        assert "total" in data["revenue"]
        assert "this_month" in data["revenue"]

    def test_dashboard_stats_without_store_association(self, client, db, auth_manager):
        """Test dashboard stats for user not associated with any store"""
        import uuid

        from app.modules.tenancy.models import User

        # Create store user without store association
        hashed_password = auth_manager.hash_password("testpass123")
        orphan_user = User(
            email=f"orphan_{uuid.uuid4().hex[:8]}@example.com",
            username=f"orphanstore_{uuid.uuid4().hex[:8]}",
            hashed_password=hashed_password,
            role="merchant_owner",
            is_active=True,
        )
        db.add(orphan_user)
        db.commit()
        db.refresh(orphan_user)

        # Get token
        token_data = auth_manager.create_access_token(orphan_user)
        headers = {"Authorization": f"Bearer {token_data['access_token']}"}

        # Try to get dashboard stats
        response = client.get("/api/v1/store/dashboard/stats", headers=headers)

        # Should fail - user not associated with store (401 if no store context, 403 if forbidden)
        assert response.status_code in [401, 403, 404]

    def test_dashboard_stats_with_inactive_store(
        self, client, db, test_store_user, test_merchant, auth_manager
    ):
        """Test dashboard stats for inactive store"""
        import uuid

        from app.modules.tenancy.models import Store, StoreUser

        # Create inactive store
        unique_code = f"INACTIVE_{uuid.uuid4().hex[:8].upper()}"
        store = Store(
            store_code=unique_code,
            subdomain=f"inactive-{uuid.uuid4().hex[:8]}",
            name="Inactive Store",
            merchant_id=test_merchant.id,
            is_active=False,  # Inactive
            is_verified=True,
        )
        db.add(store)
        db.commit()

        # Associate with user (ownership determined via Merchant.owner_user_id)
        store_user = StoreUser(
            store_id=store.id,
            user_id=test_store_user.id,
            is_active=True,
        )
        db.add(store_user)
        db.commit()

        # Get token
        token_data = auth_manager.create_access_token(test_store_user)
        headers = {"Authorization": f"Bearer {token_data['access_token']}"}

        # Try to get dashboard stats
        response = client.get("/api/v1/store/dashboard/stats", headers=headers)

        # Should fail - store is inactive (could be 401, 403 or 404 depending on implementation)
        assert response.status_code in [401, 403, 404]

    def test_dashboard_stats_empty_store(
        self, client, store_user_headers, test_store_with_store_user
    ):
        """Test dashboard stats for store with no data"""
        response = client.get(
            "/api/v1/store/dashboard/stats", headers=store_user_headers
        )

        assert response.status_code == 200
        data = response.json()

        # Should return zeros for empty store
        assert data["products"]["total"] == 0
        assert data["products"]["active"] == 0
        assert data["orders"]["total"] == 0
        assert data["customers"]["total"] == 0
        assert data["revenue"]["total"] == 0

    def test_dashboard_stats_response_time(
        self, client, store_user_headers, test_store_with_store_user
    ):
        """Test that dashboard stats responds quickly"""
        import time

        start_time = time.time()
        response = client.get(
            "/api/v1/store/dashboard/stats", headers=store_user_headers
        )
        end_time = time.time()

        assert response.status_code == 200
        # Should respond in less than 2 seconds
        assert (end_time - start_time) < 2.0

    def test_dashboard_stats_caching_behavior(
        self, client, store_user_headers, test_store_with_store_user
    ):
        """Test that dashboard stats can be called multiple times"""
        # Make multiple requests
        responses = []
        for _ in range(3):
            response = client.get(
                "/api/v1/store/dashboard/stats", headers=store_user_headers
            )
            responses.append(response)

        # All should succeed
        for response in responses:
            assert response.status_code == 200

        # All should return consistent data
        data_list = [r.json() for r in responses]
        for data in data_list[1:]:
            assert data["store"]["id"] == data_list[0]["store"]["id"]
            assert data["products"]["total"] == data_list[0]["products"]["total"]
