# tests/integration/api/v1/test_vendor_api_dashboard.py
"""
Integration tests for vendor dashboard API endpoints.

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

import pytest


@pytest.mark.integration
@pytest.mark.api
@pytest.mark.vendor
class TestVendorDashboardAPI:
    """Test vendor dashboard stats endpoint"""

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

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

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

        # Verify vendor info
        assert "id" in data["vendor"]
        assert "name" in data["vendor"]
        assert "vendor_code" in data["vendor"]
        assert data["vendor"]["id"] == test_vendor_with_vendor_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_vendor_isolation(
        self, client, db, test_vendor_user, auth_manager
    ):
        """Test that dashboard stats only show data for the authenticated vendor"""
        from models.database.marketplace_product import MarketplaceProduct
        from models.database.product import Product
        from models.database.vendor import Vendor, VendorUser

        # Create two separate vendors with different data
        vendor1 = Vendor(
            vendor_code="VENDOR1",
            subdomain="vendor1",
            name="Vendor One",
            owner_user_id=test_vendor_user.id,
            is_active=True,
            is_verified=True,
        )
        db.add(vendor1)
        db.commit()
        db.refresh(vendor1)

        # Associate vendor1 with test_vendor_user
        vendor_user1 = VendorUser(
            vendor_id=vendor1.id,
            user_id=test_vendor_user.id,
            is_owner=True,
            is_active=True,
        )
        db.add(vendor_user1)
        db.commit()

        # Create marketplace product for vendor1
        mp1 = MarketplaceProduct(
            gtin="1234567890123",
            title="Product for Vendor 1",
            is_active=True,
        )
        db.add(mp1)
        db.commit()

        # Create products for vendor1
        for i in range(3):
            product = Product(
                vendor_id=vendor1.id,
                marketplace_product_id=mp1.id,
                price=10.0 + i,
                is_active=True,
            )
            db.add(product)
        db.commit()

        # Get token for vendor1 user
        token_data = auth_manager.create_access_token(test_vendor_user)
        vendor1_headers = {"Authorization": f"Bearer {token_data['access_token']}"}

        # Get stats for vendor1
        response = client.get("/api/v1/vendor/dashboard/stats", headers=vendor1_headers)

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

        # Should show 3 products for vendor1
        assert data["vendor"]["id"] == vendor1.id
        assert data["products"]["total"] == 3

    def test_dashboard_stats_without_vendor_association(self, client, db, auth_manager):
        """Test dashboard stats for user not associated with any vendor"""
        from models.database.user import User

        # Create vendor user without vendor association
        hashed_password = auth_manager.hash_password("testpass123")
        orphan_user = User(
            email="orphan@example.com",
            username="orphanvendor",
            hashed_password=hashed_password,
            role="vendor",
            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/vendor/dashboard/stats", headers=headers)

        # Should fail - user not associated with vendor
        assert response.status_code == 403
        data = response.json()
        assert "not associated with any vendor" in data["message"]

    def test_dashboard_stats_with_inactive_vendor(
        self, client, db, test_vendor_user, auth_manager
    ):
        """Test dashboard stats for inactive vendor"""
        from models.database.vendor import Vendor, VendorUser

        # Create inactive vendor
        vendor = Vendor(
            vendor_code="INACTIVE",
            subdomain="inactive",
            name="Inactive Vendor",
            owner_user_id=test_vendor_user.id,
            is_active=False,  # Inactive
            is_verified=True,
        )
        db.add(vendor)
        db.commit()

        # Associate with user
        vendor_user = VendorUser(
            vendor_id=vendor.id,
            user_id=test_vendor_user.id,
            is_owner=True,
            is_active=True,
        )
        db.add(vendor_user)
        db.commit()

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

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

        # Should fail - vendor is inactive
        assert response.status_code == 404
        data = response.json()
        assert "not found or inactive" in data["message"]

    def test_dashboard_stats_empty_vendor(
        self, client, vendor_user_headers, test_vendor_with_vendor_user
    ):
        """Test dashboard stats for vendor with no data"""
        response = client.get(
            "/api/v1/vendor/dashboard/stats", headers=vendor_user_headers
        )

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

        # Should return zeros for empty vendor
        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_with_products(
        self, client, db, vendor_user_headers, test_vendor_with_vendor_user
    ):
        """Test dashboard stats accuracy with actual products"""
        from models.database.marketplace_product import MarketplaceProduct
        from models.database.product import Product

        # Create marketplace products
        mp = MarketplaceProduct(
            gtin="1234567890124",
            title="Test Product",
            is_active=True,
        )
        db.add(mp)
        db.commit()

        # Create products (3 active, 2 inactive)
        for i in range(5):
            product = Product(
                vendor_id=test_vendor_with_vendor_user.id,
                marketplace_product_id=mp.id,
                price=10.0 + i,
                is_active=(i < 3),  # First 3 are active
            )
            db.add(product)
        db.commit()

        # Get stats
        response = client.get(
            "/api/v1/vendor/dashboard/stats", headers=vendor_user_headers
        )

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

        assert data["products"]["total"] == 5
        assert data["products"]["active"] == 3

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

        start_time = time.time()
        response = client.get(
            "/api/v1/vendor/dashboard/stats", headers=vendor_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, vendor_user_headers, test_vendor_with_vendor_user
    ):
        """Test that dashboard stats can be called multiple times"""
        # Make multiple requests
        responses = []
        for _ in range(3):
            response = client.get(
                "/api/v1/vendor/dashboard/stats", headers=vendor_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["vendor"]["id"] == data_list[0]["vendor"]["id"]
            assert data["products"]["total"] == data_list[0]["products"]["total"]
