from db.channel_capabilities import resolve_product_structure
from db.channel_exports import resolve_push_skus
from db.master_relations import (
    build_parent_relation_fields,
    extract_relations_from_records,
    _parse_configurable_variations,
)
from magento.master_catalog_rows import _payload_to_snapshot_row


def test_resolve_product_structure_defaults():
    assert resolve_product_structure("shopify") == "flat"
    assert resolve_product_structure("magento") == "parent_children"
    assert resolve_product_structure("magento", capabilities={"product_structure": "flat"}) == "flat"


def test_flat_channel_push_skus_excludes_parent_shells(monkeypatch):
    import db.channel_exports as mod

    monkeypatch.setattr(mod, "parent_skus_with_children", lambda _session, skus: {"PARENT"} & set(skus))

    result = resolve_push_skus(
        object(),
        "shopify",
        skus=["PARENT", "CHILD-1"],
        only_assigned=False,
        product_structure="flat",
    )

    assert result == {"CHILD-1"}


def test_parent_child_channel_push_skus_expands_relations(monkeypatch):
    import db.channel_exports as mod

    monkeypatch.setattr(mod, "active_skus_for_channel", lambda *_a, **_k: {"PARENT"})
    monkeypatch.setattr(mod, "expand_skus_with_children", lambda _session, skus: set(skus) | {"CHILD-1"})
    monkeypatch.setattr(mod, "expand_skus_with_parents", lambda _session, skus: set(skus) | {"PARENT"})

    result = resolve_push_skus(
        object(),
        "magento",
        skus=None,
        only_assigned=True,
        product_structure="parent_children",
    )

    assert result == {"PARENT", "CHILD-1"}


def test_explicit_sku_list_does_not_expand_relations(monkeypatch):
    import db.channel_exports as mod

    def _fail_expand(*_args, **_kwargs):
        raise AssertionError("expand_skus_with_children should not run for explicit SKU lists")

    monkeypatch.setattr(mod, "expand_skus_with_children", _fail_expand)
    monkeypatch.setattr(mod, "expand_skus_with_parents", _fail_expand)

    result = resolve_push_skus(
        object(),
        "magento",
        skus=["ASM-1", "ASM-2"],
        only_assigned=False,
        product_structure="parent_children",
    )

    assert result == {"ASM-1", "ASM-2"}


def test_explicit_sku_list_can_opt_in_to_expansion(monkeypatch):
    import db.channel_exports as mod

    monkeypatch.setattr(mod, "expand_skus_with_children", lambda _session, skus: set(skus) | {"CHILD-RTA"})
    monkeypatch.setattr(mod, "expand_skus_with_parents", lambda _session, skus: set(skus))

    result = resolve_push_skus(
        object(),
        "magento",
        skus=["ASM-1"],
        only_assigned=False,
        product_structure="parent_children",
        expand_relations=True,
    )

    assert result == {"ASM-1", "CHILD-RTA"}


def test_extract_relations_from_variant_of():
    records = [
        {"sku": "CHILD-1", "payload": {"variant_of": "PARENT-1"}},
        {"sku": "PARENT-1", "payload": {"variant_list": "CHILD-1,CHILD-2", "product_type": "configurable"}},
    ]
    rows = extract_relations_from_records(records)
    keys = {(r["parent_sku"], r["child_sku"]) for r in rows}
    assert ("PARENT-1", "CHILD-1") in keys
    assert ("PARENT-1", "CHILD-2") in keys


def test_parse_configurable_variations_with_options():
    parsed = _parse_configurable_variations("sku=C1,width=30,color=White|sku=C2,width=36,color=Gray")
    assert parsed == [
        ("C1", {"width": "30", "color": "White"}),
        ("C2", {"width": "36", "color": "Gray"}),
    ]


def test_build_parent_relation_fields_maps_variation_axes_to_magento(monkeypatch):
    class FakeSession:
        pass

    session = FakeSession()
    from db import master_relations as mod

    monkeypatch.setattr(mod, "children_by_parent", lambda _session, parent_skus: {
        "PARENT": [
            {"child_sku": "C1", "option_mapping": {"variation_width_in": "12"}},
            {"child_sku": "C2", "option_mapping": {"variation_width_in": "15"}},
        ]
    })
    fields = build_parent_relation_fields(session, ["PARENT"])
    assert fields["PARENT"]["configurable_attributes"] == "width"
    assert fields["PARENT"]["configurable_variation_axis"] == "width"
    assert "width=Width" in fields["PARENT"]["configurable_variation_labels"]
    assert fields["PARENT"]["configurable_variations"] == "sku=C1,width=12|sku=C2,width=15"


def test_build_parent_relation_fields_from_session_like_rows(monkeypatch):
    class FakeSession:
        pass

    session = FakeSession()
    from db import master_relations as mod

    monkeypatch.setattr(
        mod,
        "children_by_parent",
        lambda _session, parent_skus: {
            "PARENT": [
                {"child_sku": "C1", "option_mapping": {"width": "30"}},
                {"child_sku": "C2", "option_mapping": {"width": "36"}},
            ]
        },
    )
    fields = build_parent_relation_fields(session, ["PARENT"])
    assert fields["PARENT"]["variant_list"] == "C1,C2"
    assert fields["PARENT"]["product_type"] == "configurable"
    assert "width" in fields["PARENT"]["configurable_attributes"]
    assert "sku=C1,width=30" in fields["PARENT"]["configurable_variations"]


def test_payload_to_snapshot_row_maps_title_and_categories():
    row = _payload_to_snapshot_row(
        {
            "sku": "SKU-1",
            "product_role": "standalone",
            "canonical_fields": {
                "title": "Wall Cabinet",
                "category_l1": "Kitchen",
                "category_l2": "Wall",
                "cabinet_door_style": "Shaker",
            },
            "price": 99.0,
        }
    )
    assert row["sku"] == "SKU-1"
    assert row["name"] == "Wall Cabinet"
    assert row["categories"] == "Kitchen/Wall"
    assert row["cabinet_door_style"] == "Shaker"
    assert row["price"] == 99.0


def test_payload_to_snapshot_row_defaults_price_when_missing():
    row = _payload_to_snapshot_row(
        {
            "sku": "SKU-2",
            "product_role": "standalone",
            "canonical_fields": {"title": "No price row"},
        }
    )
    assert row["price"] == 1
