# tests/integration/api/v1/admin/test_products.py
"""
Integration tests for admin marketplace product catalog endpoints.

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

import pytest


@pytest.mark.integration
@pytest.mark.api
@pytest.mark.admin
@pytest.mark.products
class TestAdminProductsAPI:
    """Tests for admin marketplace products endpoints."""

    def test_get_products_admin(self, client, admin_headers, test_marketplace_product):
        """Test admin getting all marketplace products."""
        response = client.get("/api/v1/admin/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_marketplace_product is in the response
        product_ids = [p["marketplace_product_id"] for p in data["products"]]
        assert test_marketplace_product.marketplace_product_id in product_ids

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

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

    def test_get_products_with_search(
        self, client, admin_headers, test_marketplace_product
    ):
        """Test admin searching products by title."""
        response = client.get(
            "/api/v1/admin/products",
            params={"search": "Test MarketplaceProduct"},
            headers=admin_headers,
        )

        assert response.status_code == 200
        data = response.json()
        assert data["total"] >= 1

    def test_get_products_with_marketplace_filter(
        self, client, admin_headers, test_marketplace_product
    ):
        """Test admin filtering products by marketplace."""
        response = client.get(
            "/api/v1/admin/products",
            params={"marketplace": test_marketplace_product.marketplace},
            headers=admin_headers,
        )

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

    def test_get_products_with_vendor_filter(
        self, client, admin_headers, test_marketplace_product
    ):
        """Test admin filtering products by vendor name."""
        response = client.get(
            "/api/v1/admin/products",
            params={"vendor_name": test_marketplace_product.vendor_name},
            headers=admin_headers,
        )

        assert response.status_code == 200
        data = response.json()
        assert data["total"] >= 1

    def test_get_products_pagination(self, client, admin_headers, multiple_products):
        """Test admin products pagination."""
        # Test first page
        response = client.get(
            "/api/v1/admin/products",
            params={"skip": 0, "limit": 2},
            headers=admin_headers,
        )

        assert response.status_code == 200
        data = response.json()
        assert len(data["products"]) <= 2
        assert data["skip"] == 0
        assert data["limit"] == 2

        # Test second page
        response = client.get(
            "/api/v1/admin/products",
            params={"skip": 2, "limit": 2},
            headers=admin_headers,
        )

        assert response.status_code == 200
        data = response.json()
        assert data["skip"] == 2

    def test_get_product_stats_admin(
        self, client, admin_headers, test_marketplace_product
    ):
        """Test admin getting product statistics."""
        response = client.get("/api/v1/admin/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 "digital" in data
        assert "physical" in data
        assert "by_marketplace" in data
        assert data["total"] >= 1

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

        assert response.status_code == 403

    def test_get_marketplaces_admin(
        self, client, admin_headers, test_marketplace_product
    ):
        """Test admin getting list of marketplaces."""
        response = client.get(
            "/api/v1/admin/products/marketplaces", headers=admin_headers
        )

        assert response.status_code == 200
        data = response.json()
        assert "marketplaces" in data
        assert isinstance(data["marketplaces"], list)
        assert test_marketplace_product.marketplace in data["marketplaces"]

    def test_get_vendors_admin(self, client, admin_headers, test_marketplace_product):
        """Test admin getting list of source vendors."""
        response = client.get("/api/v1/admin/products/vendors", headers=admin_headers)

        assert response.status_code == 200
        data = response.json()
        assert "vendors" in data
        assert isinstance(data["vendors"], list)
        assert test_marketplace_product.vendor_name in data["vendors"]

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

        assert response.status_code == 200
        data = response.json()
        assert data["id"] == test_marketplace_product.id
        assert (
            data["marketplace_product_id"]
            == test_marketplace_product.marketplace_product_id
        )
        assert data["marketplace"] == test_marketplace_product.marketplace
        assert data["vendor_name"] == test_marketplace_product.vendor_name
        assert "translations" in data

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

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

    def test_copy_to_vendor_admin(
        self, client, admin_headers, test_marketplace_product, test_vendor
    ):
        """Test admin copying marketplace product to vendor catalog."""
        response = client.post(
            "/api/v1/admin/products/copy-to-vendor",
            json={
                "marketplace_product_ids": [test_marketplace_product.id],
                "vendor_id": test_vendor.id,
                "skip_existing": True,
            },
            headers=admin_headers,
        )

        assert response.status_code == 200
        data = response.json()
        assert "copied" in data
        assert "skipped" in data
        assert "failed" in data
        assert data["copied"] == 1
        assert data["skipped"] == 0
        assert data["failed"] == 0

    def test_copy_to_vendor_skip_existing(
        self, client, admin_headers, test_marketplace_product, test_vendor, db
    ):
        """Test admin copying product that already exists skips it."""
        # First copy
        response = client.post(
            "/api/v1/admin/products/copy-to-vendor",
            json={
                "marketplace_product_ids": [test_marketplace_product.id],
                "vendor_id": test_vendor.id,
                "skip_existing": True,
            },
            headers=admin_headers,
        )
        assert response.status_code == 200
        assert response.json()["copied"] == 1

        # Second copy should skip
        response = client.post(
            "/api/v1/admin/products/copy-to-vendor",
            json={
                "marketplace_product_ids": [test_marketplace_product.id],
                "vendor_id": test_vendor.id,
                "skip_existing": True,
            },
            headers=admin_headers,
        )
        assert response.status_code == 200
        data = response.json()
        assert data["copied"] == 0
        assert data["skipped"] == 1

    def test_copy_to_vendor_not_found(self, client, admin_headers, test_vendor):
        """Test admin copying non-existent product."""
        response = client.post(
            "/api/v1/admin/products/copy-to-vendor",
            json={
                "marketplace_product_ids": [99999],
                "vendor_id": test_vendor.id,
                "skip_existing": True,
            },
            headers=admin_headers,
        )

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

    def test_copy_to_vendor_invalid_vendor(
        self, client, admin_headers, test_marketplace_product
    ):
        """Test admin copying to non-existent vendor."""
        response = client.post(
            "/api/v1/admin/products/copy-to-vendor",
            json={
                "marketplace_product_ids": [test_marketplace_product.id],
                "vendor_id": 99999,
                "skip_existing": True,
            },
            headers=admin_headers,
        )

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

    def test_copy_to_vendor_non_admin(
        self, client, auth_headers, test_marketplace_product, test_vendor
    ):
        """Test non-admin trying to copy products."""
        response = client.post(
            "/api/v1/admin/products/copy-to-vendor",
            json={
                "marketplace_product_ids": [test_marketplace_product.id],
                "vendor_id": test_vendor.id,
                "skip_existing": True,
            },
            headers=auth_headers,
        )

        assert response.status_code == 403
