from shopify.pull_query import (
    _variant_selection_lines,
    build_products_pull_query,
    variant_weight,
)


class _FakeClient:
    endpoint = "https://example.myshopify.com/admin/api/2026-04/graphql.json"

    def __init__(self, field_map):
        self.field_map = field_map
        self.calls = []

    def graphql(self, query, variables=None):
        self.calls.append((query, variables))
        if "__type" in query:
            type_name = (variables or {}).get("name")
            return {"__type": {"fields": [{"name": name} for name in self.field_map.get(type_name, [])]}}
        raise AssertionError("unexpected graphql call")


def test_variant_selection_uses_inventory_item_when_weight_removed():
    lines = _variant_selection_lines(
        {
            "id",
            "sku",
            "price",
            "inventoryItem",
            "selectedOptions",
        },
        {"id", "measurement", "sku"},
    )
    joined = " ".join(lines)
    assert "weightUnit" not in joined
    assert "selectedOptions { name value }" in joined
    assert "inventoryItem { id sku measurement { weight { value unit } } }" in joined


def test_variant_selection_keeps_legacy_weight_when_available():
    lines = _variant_selection_lines(
        {"id", "sku", "price", "weight", "weightUnit"},
        set(),
    )
    joined = " ".join(lines)
    assert "weight" in joined
    assert "weightUnit" in joined
    assert "inventoryItem" not in joined


def test_build_products_pull_query_uses_schema_introspection():
    client = _FakeClient(
        {
            "Product": ["id", "title", "handle", "variants"],
            "ProductVariant": ["id", "sku", "price", "inventoryItem", "selectedOptions"],
            "InventoryItem": ["id", "measurement"],
        }
    )
    query = build_products_pull_query(client)
    assert "inventoryItem" in query
    assert "measurement { weight { value unit } }" in query
    assert "weightUnit" not in query
    assert len(client.calls) == 3
    assert build_products_pull_query(client) == query


def test_variant_weight_reads_inventory_item_measurement():
    weight, unit = variant_weight(
        {
            "inventoryItem": {
                "measurement": {
                    "weight": {"value": 1.25, "unit": "KILOGRAMS"},
                }
            }
        }
    )
    assert weight == 1.25
    assert unit == "KILOGRAMS"


def test_variant_weight_falls_back_to_legacy_fields():
    weight, unit = variant_weight({"weight": 2.5, "weightUnit": "POUNDS"})
    assert weight == 2.5
    assert unit == "POUNDS"
