# tests/integration/api/v1/admin/test_vendor_products.py
"""
Integration tests for admin vendor product catalog endpoints.

Tests the /api/v1/admin/vendor-products endpoints.
"""

import pytest


@pytest.mark.integration
@pytest.mark.api
@pytest.mark.admin
@pytest.mark.products
class TestAdminVendorProductsAPI:
    """Tests for admin vendor products endpoints."""

    def test_get_vendor_products_admin(self, client, admin_headers, test_product):
        """Test admin getting all vendor products."""
        response = client.get("/api/v1/admin/vendor-products", headers=admin_headers)

        assert response.status_code == 200
        data = response.json()
        assert "products" in data
        assert "total" in data
        assert "skip" in data
        assert "limit" in data
        assert data["total"] >= 1
        assert len(data["products"]) >= 1

        # Check that test_product is in the response
        product_ids = [p["id"] for p in data["products"]]
        assert test_product.id in product_ids

    def test_get_vendor_products_non_admin(self, client, auth_headers):
        """Test non-admin trying to access vendor products endpoint."""
        response = client.get("/api/v1/admin/vendor-products", headers=auth_headers)

        assert response.status_code == 403
        data = response.json()
        assert data["error_code"] == "ADMIN_REQUIRED"

    def test_get_vendor_products_with_vendor_filter(
        self, client, admin_headers, test_product, test_vendor
    ):
        """Test admin filtering products by vendor."""
        response = client.get(
            "/api/v1/admin/vendor-products",
            params={"vendor_id": test_vendor.id},
            headers=admin_headers,
        )

        assert response.status_code == 200
        data = response.json()
        assert data["total"] >= 1
        # All products should be from the filtered vendor
        for product in data["products"]:
            assert product["vendor_id"] == test_vendor.id

    def test_get_vendor_products_with_active_filter(
        self, client, admin_headers, test_product
    ):
        """Test admin filtering products by active status."""
        response = client.get(
            "/api/v1/admin/vendor-products",
            params={"is_active": True},
            headers=admin_headers,
        )

        assert response.status_code == 200
        data = response.json()
        # All products should be active
        for product in data["products"]:
            assert product["is_active"] is True

    def test_get_vendor_products_with_featured_filter(
        self, client, admin_headers, test_product
    ):
        """Test admin filtering products by featured status."""
        response = client.get(
            "/api/v1/admin/vendor-products",
            params={"is_featured": False},
            headers=admin_headers,
        )

        assert response.status_code == 200
        data = response.json()
        # All products should not be featured
        for product in data["products"]:
            assert product["is_featured"] is False

    def test_get_vendor_products_pagination(self, client, admin_headers, test_product):
        """Test admin vendor products pagination."""
        response = client.get(
            "/api/v1/admin/vendor-products",
            params={"skip": 0, "limit": 10},
            headers=admin_headers,
        )

        assert response.status_code == 200
        data = response.json()
        assert data["skip"] == 0
        assert data["limit"] == 10

    def test_get_vendor_product_stats_admin(self, client, admin_headers, test_product):
        """Test admin getting vendor product statistics."""
        response = client.get(
            "/api/v1/admin/vendor-products/stats", headers=admin_headers
        )

        assert response.status_code == 200
        data = response.json()
        assert "total" in data
        assert "active" in data
        assert "inactive" in data
        assert "featured" in data
        assert "digital" in data
        assert "physical" in data
        assert "by_vendor" in data
        assert data["total"] >= 1

    def test_get_vendor_product_stats_non_admin(self, client, auth_headers):
        """Test non-admin trying to access vendor product stats."""
        response = client.get(
            "/api/v1/admin/vendor-products/stats", headers=auth_headers
        )

        assert response.status_code == 403

    def test_get_catalog_vendors_admin(
        self, client, admin_headers, test_product, test_vendor
    ):
        """Test admin getting list of vendors with products."""
        response = client.get(
            "/api/v1/admin/vendor-products/vendors", headers=admin_headers
        )

        assert response.status_code == 200
        data = response.json()
        assert "vendors" in data
        assert isinstance(data["vendors"], list)
        assert len(data["vendors"]) >= 1

        # Check that test_vendor is in the list
        vendor_ids = [v["id"] for v in data["vendors"]]
        assert test_vendor.id in vendor_ids

    def test_get_vendor_product_detail_admin(self, client, admin_headers, test_product):
        """Test admin getting vendor product detail."""
        response = client.get(
            f"/api/v1/admin/vendor-products/{test_product.id}",
            headers=admin_headers,
        )

        assert response.status_code == 200
        data = response.json()
        assert data["id"] == test_product.id
        assert data["vendor_id"] == test_product.vendor_id
        assert data["marketplace_product_id"] == test_product.marketplace_product_id
        assert "source_marketplace" in data
        assert "source_vendor" in data

    def test_get_vendor_product_detail_not_found(self, client, admin_headers):
        """Test admin getting non-existent vendor product detail."""
        response = client.get(
            "/api/v1/admin/vendor-products/99999", headers=admin_headers
        )

        assert response.status_code == 404
        data = response.json()
        assert data["error_code"] == "PRODUCT_NOT_FOUND"

    def test_remove_vendor_product_admin(self, client, admin_headers, test_product, db):
        """Test admin removing product from vendor catalog."""
        product_id = test_product.id

        response = client.delete(
            f"/api/v1/admin/vendor-products/{product_id}",
            headers=admin_headers,
        )

        assert response.status_code == 200
        data = response.json()
        assert "message" in data
        assert "removed" in data["message"].lower()

        # Verify product is removed
        response = client.get(
            f"/api/v1/admin/vendor-products/{product_id}",
            headers=admin_headers,
        )
        assert response.status_code == 404

    def test_remove_vendor_product_not_found(self, client, admin_headers):
        """Test admin removing non-existent vendor product."""
        response = client.delete(
            "/api/v1/admin/vendor-products/99999",
            headers=admin_headers,
        )

        assert response.status_code == 404
        data = response.json()
        assert data["error_code"] == "PRODUCT_NOT_FOUND"

    def test_remove_vendor_product_non_admin(self, client, auth_headers, test_product):
        """Test non-admin trying to remove product."""
        response = client.delete(
            f"/api/v1/admin/vendor-products/{test_product.id}",
            headers=auth_headers,
        )

        assert response.status_code == 403


@pytest.mark.integration
@pytest.mark.api
@pytest.mark.admin
@pytest.mark.products
class TestAdminVendorProductCreateAPI:
    """Tests for admin vendor product creation endpoints."""

    def test_create_vendor_product_with_translations(
        self, client, admin_headers, test_vendor
    ):
        """Test creating a product with multi-language translations."""
        payload = {
            "vendor_id": test_vendor.id,
            "translations": {
                "en": {"title": "Test Product EN", "description": "English description"},
                "fr": {"title": "Test Product FR", "description": "French description"},
            },
            "vendor_sku": "CREATE_TEST_001",
            "brand": "TestBrand",
            "gtin": "1234567890123",
            "gtin_type": "ean13",
            "price": 29.99,
            "currency": "EUR",
            "tax_rate_percent": 17,
            "is_active": True,
            "is_digital": False,
        }

        response = client.post(
            "/api/v1/admin/vendor-products",
            json=payload,
            headers=admin_headers,
        )

        assert response.status_code == 200
        data = response.json()
        assert "id" in data
        assert data["message"] == "Product created successfully"

        # Verify the created product
        product_id = data["id"]
        detail_response = client.get(
            f"/api/v1/admin/vendor-products/{product_id}",
            headers=admin_headers,
        )
        assert detail_response.status_code == 200
        detail = detail_response.json()
        assert detail["vendor_id"] == test_vendor.id
        assert detail["vendor_sku"] == "CREATE_TEST_001"
        assert detail["brand"] == "TestBrand"
        assert detail["is_digital"] is False
        assert detail["vendor_translations"]["en"]["title"] == "Test Product EN"

    def test_create_digital_product(self, client, admin_headers, test_vendor):
        """Test creating a digital product directly."""
        payload = {
            "vendor_id": test_vendor.id,
            "translations": {
                "en": {"title": "Digital Game Key", "description": "Steam game key"},
            },
            "vendor_sku": "DIGITAL_001",
            "price": 49.99,
            "is_digital": True,
            "is_active": True,
        }

        response = client.post(
            "/api/v1/admin/vendor-products",
            json=payload,
            headers=admin_headers,
        )

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

        # Verify the product is digital
        detail_response = client.get(
            f"/api/v1/admin/vendor-products/{data['id']}",
            headers=admin_headers,
        )
        detail = detail_response.json()
        assert detail["is_digital"] is True
        assert detail["product_type"] == "digital"

    def test_create_product_without_marketplace_source(
        self, client, admin_headers, test_vendor
    ):
        """Test creating a direct product without marketplace source."""
        payload = {
            "vendor_id": test_vendor.id,
            "translations": {
                "en": {"title": "Direct Product", "description": "Created directly"},
            },
            "vendor_sku": "DIRECT_001",
            "brand": "DirectBrand",
            "price": 19.99,
            "is_active": True,
        }

        response = client.post(
            "/api/v1/admin/vendor-products",
            json=payload,
            headers=admin_headers,
        )

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

        # Verify there's no marketplace source
        detail_response = client.get(
            f"/api/v1/admin/vendor-products/{data['id']}",
            headers=admin_headers,
        )
        detail = detail_response.json()
        assert detail["marketplace_product_id"] is None
        assert detail["source_marketplace"] is None
        assert detail["source_vendor"] is None

    def test_create_product_non_admin(self, client, auth_headers, test_vendor):
        """Test non-admin trying to create product."""
        payload = {
            "vendor_id": test_vendor.id,
            "translations": {"en": {"title": "Test"}},
        }

        response = client.post(
            "/api/v1/admin/vendor-products",
            json=payload,
            headers=auth_headers,
        )

        assert response.status_code == 403


@pytest.mark.integration
@pytest.mark.api
@pytest.mark.admin
@pytest.mark.products
class TestAdminVendorProductUpdateAPI:
    """Tests for admin vendor product update endpoints."""

    def test_update_vendor_product_translations(
        self, client, admin_headers, test_vendor
    ):
        """Test updating product translations by first creating a product with translations."""
        # First create a product with translations
        create_payload = {
            "vendor_id": test_vendor.id,
            "translations": {
                "en": {"title": "Original Title EN", "description": "Original desc"},
            },
            "vendor_sku": "TRANS_TEST_001",
            "price": 10.00,
            "is_active": True,
        }
        create_response = client.post(
            "/api/v1/admin/vendor-products",
            json=create_payload,
            headers=admin_headers,
        )
        assert create_response.status_code == 200
        product_id = create_response.json()["id"]

        # Now update the translations
        update_payload = {
            "translations": {
                "en": {"title": "Updated Title EN", "description": "Updated desc EN"},
                "de": {"title": "Updated Title DE", "description": "Updated desc DE"},
            }
        }

        response = client.patch(
            f"/api/v1/admin/vendor-products/{product_id}",
            json=update_payload,
            headers=admin_headers,
        )

        assert response.status_code == 200

        # Re-fetch the product to verify translations were saved
        detail_response = client.get(
            f"/api/v1/admin/vendor-products/{product_id}",
            headers=admin_headers,
        )
        assert detail_response.status_code == 200
        data = detail_response.json()

        # Check translations are present and updated
        assert "vendor_translations" in data
        assert data["vendor_translations"] is not None
        assert "en" in data["vendor_translations"]
        assert data["vendor_translations"]["en"]["title"] == "Updated Title EN"

    def test_update_vendor_product_is_digital(
        self, client, admin_headers, test_product, db
    ):
        """Test updating product is_digital flag."""
        # First ensure it's not digital
        test_product.is_digital = False
        db.commit()

        payload = {"is_digital": True}

        response = client.patch(
            f"/api/v1/admin/vendor-products/{test_product.id}",
            json=payload,
            headers=admin_headers,
        )

        assert response.status_code == 200
        data = response.json()
        assert data["is_digital"] is True

    def test_update_vendor_product_pricing(self, client, admin_headers, test_product):
        """Test updating product pricing fields."""
        payload = {
            "price": 99.99,
            "sale_price": 79.99,
            "tax_rate_percent": 8,
            "availability": "in_stock",
        }

        response = client.patch(
            f"/api/v1/admin/vendor-products/{test_product.id}",
            json=payload,
            headers=admin_headers,
        )

        assert response.status_code == 200
        data = response.json()
        assert data["price"] == 99.99
        assert data["sale_price"] == 79.99
        assert data["tax_rate_percent"] == 8
        assert data["availability"] == "in_stock"

    def test_update_vendor_product_identifiers(
        self, client, admin_headers, test_product
    ):
        """Test updating product identifiers."""
        payload = {
            "vendor_sku": "UPDATED_SKU_001",
            "brand": "UpdatedBrand",
            "gtin": "9876543210123",
            "gtin_type": "ean13",
        }

        response = client.patch(
            f"/api/v1/admin/vendor-products/{test_product.id}",
            json=payload,
            headers=admin_headers,
        )

        assert response.status_code == 200
        data = response.json()
        assert data["vendor_sku"] == "UPDATED_SKU_001"
        assert data["brand"] == "UpdatedBrand"
        assert data["gtin"] == "9876543210123"

    def test_update_vendor_product_not_found(self, client, admin_headers):
        """Test updating non-existent product."""
        payload = {"brand": "Test"}

        response = client.patch(
            "/api/v1/admin/vendor-products/99999",
            json=payload,
            headers=admin_headers,
        )

        assert response.status_code == 404
        assert response.json()["error_code"] == "PRODUCT_NOT_FOUND"

    def test_update_vendor_product_non_admin(self, client, auth_headers, test_product):
        """Test non-admin trying to update product."""
        payload = {"brand": "Test"}

        response = client.patch(
            f"/api/v1/admin/vendor-products/{test_product.id}",
            json=payload,
            headers=auth_headers,
        )

        assert response.status_code == 403
