# tests/integration/api/v1/vendor/test_products.py
"""Integration tests for vendor product management endpoints.

Tests the /api/v1/vendor/products/* endpoints.
All endpoints require vendor JWT authentication.
"""

import pytest


@pytest.mark.integration
@pytest.mark.api
@pytest.mark.vendor
class TestVendorProductsAPI:
    """Test vendor product management endpoints at /api/v1/vendor/products/*."""

    def test_add_product_to_catalog_success(
        self, client, vendor_user_headers, test_vendor_with_vendor_user, unique_product
    ):
        """Test adding product to vendor catalog successfully."""
        product_data = {
            "marketplace_product_id": unique_product.id,
            "price": 29.99,
            "is_featured": False,
        }

        response = client.post(
            "/api/v1/vendor/products",
            headers=vendor_user_headers,
            json=product_data,
        )

        assert response.status_code == 200, f"Failed: {response.json()}"
        data = response.json()

        assert data["vendor_id"] == test_vendor_with_vendor_user.id
        assert data["price"] == 29.99
        assert data["is_active"] is True
        assert data["is_featured"] is False
        assert "marketplace_product" in data
        assert data["marketplace_product"]["id"] == unique_product.id

    def test_add_product_duplicate_returns_error(
        self,
        client,
        vendor_user_headers,
        test_vendor_with_vendor_user,
        test_product,
        db,
    ):
        """Test adding product that already exists returns error."""
        # Ensure test_product belongs to the vendor
        from app.modules.catalog.models import Product

        product = db.query(Product).filter(Product.id == test_product.id).first()
        product.vendor_id = test_vendor_with_vendor_user.id
        db.commit()

        product_data = {
            "marketplace_product_id": test_product.marketplace_product_id,
            "price": 29.99,
        }

        response = client.post(
            "/api/v1/vendor/products",
            headers=vendor_user_headers,
            json=product_data,
        )

        # Service wraps ProductAlreadyExistsException in ValidationException
        assert response.status_code in [409, 422]
        data = response.json()
        assert data["error_code"] in ["PRODUCT_ALREADY_EXISTS", "VALIDATION_ERROR"]

    def test_add_nonexistent_product_returns_error(self, client, vendor_user_headers):
        """Test adding nonexistent marketplace product returns error."""
        product_data = {
            "marketplace_product_id": 99999,
            "price": 29.99,
        }

        response = client.post(
            "/api/v1/vendor/products",
            headers=vendor_user_headers,
            json=product_data,
        )

        # Service wraps ProductNotFoundException in ValidationException
        assert response.status_code in [404, 422]
        data = response.json()
        assert data["error_code"] in ["PRODUCT_NOT_FOUND", "VALIDATION_ERROR"]
        assert "99999" in data["message"]

    def test_get_products_success(
        self, client, vendor_user_headers, test_vendor_with_vendor_user, db
    ):
        """Test getting vendor products list."""
        response = client.get(
            "/api/v1/vendor/products",
            headers=vendor_user_headers,
        )

        assert response.status_code == 200
        data = response.json()
        assert "products" in data
        assert "total" in data
        assert isinstance(data["products"], list)

    def test_get_products_with_filters(self, client, vendor_user_headers):
        """Test getting vendor products with filters."""
        # Test active_only filter
        response = client.get(
            "/api/v1/vendor/products?active_only=true",
            headers=vendor_user_headers,
        )
        assert response.status_code == 200

        # Test featured_only filter
        response = client.get(
            "/api/v1/vendor/products?featured_only=true",
            headers=vendor_user_headers,
        )
        assert response.status_code == 200

    def test_get_products_without_auth_returns_unauthorized(self, client):
        """Test getting products without authentication returns unauthorized."""
        response = client.get("/api/v1/vendor/products")

        assert response.status_code == 401
        data = response.json()
        assert data["error_code"] == "INVALID_TOKEN"

    def test_get_product_detail_success(
        self,
        client,
        vendor_user_headers,
        test_vendor_with_vendor_user,
        test_product,
        db,
    ):
        """Test getting product details."""
        # Ensure test_product belongs to the vendor
        from app.modules.catalog.models import Product

        product = db.query(Product).filter(Product.id == test_product.id).first()
        product.vendor_id = test_vendor_with_vendor_user.id
        db.commit()

        response = client.get(
            f"/api/v1/vendor/products/{test_product.id}",
            headers=vendor_user_headers,
        )

        assert response.status_code == 200
        data = response.json()
        assert data["id"] == test_product.id

    def test_get_product_detail_not_found(self, client, vendor_user_headers):
        """Test getting non-existent product returns not found."""
        response = client.get(
            "/api/v1/vendor/products/99999",
            headers=vendor_user_headers,
        )

        assert response.status_code == 404

    def test_update_product_success(
        self,
        client,
        vendor_user_headers,
        test_vendor_with_vendor_user,
        test_product,
        db,
    ):
        """Test updating product details."""
        # Ensure test_product belongs to the vendor
        from app.modules.catalog.models import Product

        product = db.query(Product).filter(Product.id == test_product.id).first()
        product.vendor_id = test_vendor_with_vendor_user.id
        db.commit()

        update_data = {
            "price": 49.99,
            "is_featured": True,
        }

        response = client.put(
            f"/api/v1/vendor/products/{test_product.id}",
            headers=vendor_user_headers,
            json=update_data,
        )

        assert response.status_code == 200
        data = response.json()
        assert data["price"] == 49.99
        assert data["is_featured"] is True

    def test_toggle_product_active(
        self,
        client,
        vendor_user_headers,
        test_vendor_with_vendor_user,
        test_product,
        db,
    ):
        """Test toggling product active status."""
        # Ensure test_product belongs to the vendor
        from app.modules.catalog.models import Product

        product = db.query(Product).filter(Product.id == test_product.id).first()
        product.vendor_id = test_vendor_with_vendor_user.id
        db.commit()

        response = client.put(
            f"/api/v1/vendor/products/{test_product.id}/toggle-active",
            headers=vendor_user_headers,
        )

        assert response.status_code == 200
        data = response.json()
        assert "is_active" in data
        assert "message" in data

    def test_toggle_product_featured(
        self,
        client,
        vendor_user_headers,
        test_vendor_with_vendor_user,
        test_product,
        db,
    ):
        """Test toggling product featured status."""
        # Ensure test_product belongs to the vendor
        from app.modules.catalog.models import Product

        product = db.query(Product).filter(Product.id == test_product.id).first()
        product.vendor_id = test_vendor_with_vendor_user.id
        db.commit()

        response = client.put(
            f"/api/v1/vendor/products/{test_product.id}/toggle-featured",
            headers=vendor_user_headers,
        )

        assert response.status_code == 200
        data = response.json()
        assert "is_featured" in data
        assert "message" in data

    def test_delete_product_success(
        self,
        client,
        vendor_user_headers,
        test_vendor_with_vendor_user,
        test_product,
        db,
    ):
        """Test removing product from catalog."""
        # Ensure test_product belongs to the vendor
        from app.modules.catalog.models import Product

        product = db.query(Product).filter(Product.id == test_product.id).first()
        product.vendor_id = test_vendor_with_vendor_user.id
        db.commit()

        response = client.delete(
            f"/api/v1/vendor/products/{test_product.id}",
            headers=vendor_user_headers,
        )

        assert response.status_code == 200
        data = response.json()
        assert "message" in data


@pytest.mark.integration
@pytest.mark.api
@pytest.mark.vendor
class TestVendorInfoAPI:
    """Test public vendor info endpoint at /api/v1/vendor/{vendor_code}."""

    def test_get_vendor_info_success(self, client, test_vendor):
        """Test getting public vendor information (no auth required)."""
        response = client.get(f"/api/v1/vendor/{test_vendor.vendor_code}")

        assert response.status_code == 200
        data = response.json()
        assert data["vendor_code"] == test_vendor.vendor_code
        assert data["name"] == test_vendor.name

    def test_get_vendor_info_not_found(self, client):
        """Test getting non-existent vendor returns not found."""
        response = client.get("/api/v1/vendor/NONEXISTENT")

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