"""Tests for Shopify MCP handler."""

import json
from unittest.mock import patch

import pytest
from nlweb_core.retrieved_item import RetrievedItem
from nlweb_platform_handlers.shopify import ShopifyMCPHandler, _shopify_mcp_cache


@pytest.fixture(autouse=True)
def clear_cache():
    """Clear the Shopify MCP cache before each test."""
    _shopify_mcp_cache.clear()
    yield
    _shopify_mcp_cache.clear()


class TestShopifyMCPHandler:
    """Tests for ShopifyMCPHandler."""

    def setup_method(self):
        # Mock set_request_id since it depends on global state
        with patch("nlweb_core.handler.set_request_id", return_value="test-req-id"):
            self.handler = ShopifyMCPHandler()

    def test_product_to_schema_basic(self):
        """Test basic product to schema.org conversion."""
        product = {
            "title": "Blue T-Shirt",
            "product_id": "123",
            "url": "https://store.myshopify.com/products/blue-tshirt",
            "image_url": "https://cdn.shopify.com/image.jpg",
            "vendor": "TestBrand",
        }
        result = self.handler._product_to_schema(product)

        assert result["@type"] == "Product"
        assert result["@context"] == "https://schema.org"
        assert result["name"] == "Blue T-Shirt"
        assert result["productID"] == "123"
        assert result["image"] == "https://cdn.shopify.com/image.jpg"
        assert result["brand"] == {"@type": "Brand", "name": "TestBrand"}

    def test_product_to_schema_with_price_range(self):
        """Test product with price range → AggregateOffer."""
        product = {
            "title": "Sneakers",
            "price_range": {"min": "49.99", "max": "99.99", "currency": "USD"},
        }
        result = self.handler._product_to_schema(product)

        assert result["offers"]["@type"] == "AggregateOffer"
        assert result["offers"]["lowPrice"] == 49.99
        assert result["offers"]["highPrice"] == 99.99
        assert result["offers"]["priceCurrency"] == "USD"

    def test_product_to_schema_with_variants(self):
        """Test product with multiple variants → list of Offers."""
        product = {
            "title": "Sneakers",
            "variants": [
                {"title": "Size 8", "price": "49.99"},
                {"title": "Size 10", "price": "54.99"},
            ],
        }
        result = self.handler._product_to_schema(product)

        assert isinstance(result["offers"], list)
        assert len(result["offers"]) == 2
        assert result["offers"][0]["@type"] == "Offer"

    def test_product_to_schema_skips_empty_values(self):
        """Test that empty/None values are excluded."""
        product = {
            "title": "Item",
            "vendor": "",
            "image_url": None,
        }
        result = self.handler._product_to_schema(product)

        assert result["name"] == "Item"
        assert "brand" not in result
        assert "image" not in result

    def test_parse_mcp_response_content_array(self):
        """Test parsing standard MCP content array format."""
        products = {"products": [{"title": "Item A", "url": "https://store/a"}]}
        mcp_response = {
            "result": {
                "content": [
                    {"type": "text", "text": json.dumps(products)},
                ]
            }
        }

        result = self.handler._parse_mcp_response(mcp_response, "store.myshopify.com")
        assert len(result) == 1
        assert result[0].url == "https://store/a"
        assert result[0].site == "store.myshopify.com"

    def test_parse_mcp_response_direct_format(self):
        """Test parsing direct result format (no content wrapper)."""
        mcp_response = {
            "result": {"products": [{"title": "Item B", "url": "https://store/b"}]}
        }

        result = self.handler._parse_mcp_response(mcp_response, "store.myshopify.com")
        assert len(result) == 1
        assert result[0].url == "https://store/b"

    def test_parse_mcp_response_error(self):
        """Test that MCP errors return empty list."""
        mcp_response = {"error": {"code": -32600, "message": "Invalid Request"}}
        result = self.handler._parse_mcp_response(mcp_response, "store.myshopify.com")
        assert result == []

    async def test_retrieve_items_no_site(self):
        """Test that missing site returns empty list."""
        result = await self.handler._retrieve_items("query", site=None, num_results=10)
        assert result == []

    async def test_retrieve_items_uses_cache(self):
        """Test that cached results are returned."""
        cached_items = [
            RetrievedItem(
                url="https://store/cached",
                raw_schema_object={"@type": "Product", "name": "Cached"},
                site="store.myshopify.com",
            )
        ]
        _shopify_mcp_cache[("store.myshopify.com", "shoes")] = cached_items

        result = await self.handler._retrieve_items(
            "shoes", site="store.myshopify.com", num_results=10
        )
        assert len(result) == 1
        assert result[0].url == "https://store/cached"
