import json

from app.jobs.audit_product_channel_parity import (
    _audit_configurable_rows,
    _audit_master_product_relations,
    _expected_product_slug,
    _expected_product_slug_for_payload,
    _expected_product_slug_from_row,
    _group_category_mismatches,
    _looks_like_collection_only_title,
    _magento_path_covers_expected,
    _parent_relation_row_for_audit,
)
from db.models import MasterProduct, MasterProductRelation
from db.product_channel_taxonomy import _coalesce_magento_category_path
from magento.sync_hashes import _parse_children_from_row


def _product(sku: str, name: str, *, collection: str = "Belmont Drift White") -> MasterProduct:
    product = MasterProduct()
    product.sku = sku
    product.name = name
    product.collection = collection
    product.category_l1 = "Kitchen Cabinets"
    product.category_l2 = "Base Cabinets"
    product.is_active = True
    return product


def test_collection_only_parent_title_is_suspicious():
    product = _product("BDW-CONFIG", "Belmont Drift White")

    assert _looks_like_collection_only_title(
        product,
        [{"path_slug": "kitchen-cabinets/belmont-drift-white"}],
    )


def test_product_descriptor_title_is_not_collection_only_suspicious():
    product = _product("BDW-B12-CONFIG", "Belmont Drift White Base Cabinet")

    assert not _looks_like_collection_only_title(
        product,
        [{"path_slug": "kitchen-cabinets/belmont-drift-white"}],
    )


def test_configurable_row_audit_checks_generated_snapshot_rows():
    rows = [
        {
            "sku": "PARENT",
            "product_type": "configurable",
            "variant_list": "CHILD-1,CHILD-2",
            "configurable_attributes": "width",
            "configurable_variations": "sku=CHILD-1,width=30|sku=CHILD-2,width=99",
        }
    ]
    option_index = {"width": {"30": 450}}

    report = _audit_configurable_rows(
        rows,
        option_index,
        source="magento_snapshot_rows",
        sku_sample_limit=10,
    )

    assert report["source"] == "magento_snapshot_rows"
    assert report["parent_count"] == 1
    assert report["relation_count"] == 2
    assert report["missing_option_count"] == 1
    assert report["sample_missing_options"][0]["child_sku"] == "CHILD-2"


def test_expected_slug_prefers_imported_seo_url():
    product = _product("ACH-B12", '12"W x 34.5"H Single Door Base Cabinet (B12) - Anna Caramel Harvest | Port & Bell')
    product.raw_payload = {
        "product_url_slug": "12inw-x-34-5inh-single-door-base-cabinet-b12-anna-caramel-harvest-port-bell-ach-b12"
    }

    assert _expected_product_slug(product) == (
        "12inw-x-34-5inh-single-door-base-cabinet-b12-anna-caramel-harvest-port-bell-ach-b12"
    )
    assert _expected_product_slug_from_row(
        {
            "sku": "ACH-B12",
            "meta_title": product.name,
            "product_url_slug": product.raw_payload["product_url_slug"],
        },
        product,
        fallback_sku="ACH-B12",
    ) == product.raw_payload["product_url_slug"]
    assert _expected_product_slug_for_payload(
        {
            "sku": "ACH-B12",
            "channel_sku": "ACH-B12",
            "fields": {"handle": product.raw_payload["product_url_slug"]},
        },
        product,
        fallback_sku="ACH-B12",
    ) == product.raw_payload["product_url_slug"]


def test_leaf_only_remote_path_prefers_plp_slug():
    assert (
        _coalesce_magento_category_path(
            remote_path="single-door",
            plp_path_slug="kitchen-cabinets/base-cabinets/single-door",
        )
        == "kitchen-cabinets/base-cabinets/single-door"
    )
    assert (
        _coalesce_magento_category_path(
            remote_path="kitchen-cabinets/wall-cabinets/single-door",
            plp_path_slug="kitchen-cabinets/base-cabinets/single-door",
        )
        == "kitchen-cabinets/wall-cabinets/single-door"
    )


def test_magento_path_cover_requires_parent_facet_for_leaf_collisions():
    expected = "kitchen-cabinets/base-cabinets/single-door"
    assert not _magento_path_covers_expected(expected, ["single-door"])
    assert not _magento_path_covers_expected(
        expected,
        ["kitchen-cabinets/anna-caramel-harvest", "kitchen-cabinets/wall-cabinets/single-door"],
    )
    assert _magento_path_covers_expected(
        expected,
        ["kitchen-cabinets/anna-caramel-harvest", "kitchen-cabinets/base-cabinets/single-door"],
    )
    assert _magento_path_covers_expected(
        "kitchen-cabinets/anna-caramel-harvest",
        ["Kitchen Cabinets/Anna Caramel Harvest"],
    )


def test_parse_children_accepts_json_configurable_variations():
    row = {
        "variant_list": "ACH-BBC36/39L/R,ACH-BBC39/42L/R",
        "configurable_variations": json.dumps(
            [
                {"sku": "ACH-BBC36/39L/R", "variation_width_in": "36"},
                {"sku": "ACH-BBC39/42L/R", "variation_width_in": "39"},
            ]
        ),
    }
    children, mappings, child_to_mapping = _parse_children_from_row(row)
    assert children == ["ACH-BBC36/39L/R", "ACH-BBC39/42L/R"]
    assert child_to_mapping["ACH-BBC36/39L/R"]["width"] == "36"
    assert child_to_mapping["ACH-BBC39/42L/R"]["width"] == "39"
    assert len(mappings) == 2


def test_master_relation_audit_reads_option_mapping_directly():
    rel_a = MasterProductRelation()
    rel_a.parent_sku = "ACH-BBC-PARENT"
    rel_a.child_sku = "ACH-BBC36/39L/R"
    rel_a.option_mapping = {"variation_width_in": "36"}
    rel_b = MasterProductRelation()
    rel_b.parent_sku = "ACH-BBC-PARENT"
    rel_b.child_sku = "ACH-BBC39/42L/R"
    rel_b.option_mapping = {"variation_width_in": "39"}

    report = _audit_master_product_relations(
        {"ACH-BBC-PARENT": [rel_a, rel_b]},
        {"width": {"36": 1, "39": 2}},
        sku_sample_limit=10,
    )
    assert report["source"] == "master_product_relations"
    assert report["relation_count"] == 2
    assert report["missing_mapping_count"] == 0
    assert report["missing_option_count"] == 0
    assert report["issue_count"] == 0


def test_parent_relation_row_emits_magento_pipe_format():
    rel = MasterProductRelation()
    rel.parent_sku = "ACH-BBC-PARENT"
    rel.child_sku = "ACH-BBC36/39L/R"
    rel.option_mapping = {"variation_width_in": "36"}
    row = _parent_relation_row_for_audit("ACH-BBC-PARENT", [rel])
    assert "sku=ACH-BBC36/39L/R" in row["configurable_variations"]
    assert "width=36" in row["configurable_variations"]
    assert "[" not in row["configurable_variations"]


def test_group_category_mismatches_collapses_sku_noise():
    issues = [
        {
            "sku": "ACH-B12",
            "expected_paths": ["kitchen-cabinets/base-cabinets/single-door"],
            "would_push_paths": ["kitchen-cabinets/wall-cabinets/single-door"],
            "category_ids": [142],
        },
        {
            "sku": "ACH-B15",
            "expected_paths": ["kitchen-cabinets/base-cabinets/single-door"],
            "would_push_paths": ["kitchen-cabinets/wall-cabinets/single-door"],
            "category_ids": [142],
        },
        {
            "sku": "ACH-BM8",
            "expected_paths": ["kitchen-cabinets/mouldings/bead-molding"],
            "would_push_paths": ["kitchen-cabinets/accessories/bead-molding"],
            "category_ids": [223],
        },
    ]
    groups = _group_category_mismatches(issues, sample_limit=10)
    assert len(groups) == 2
    assert groups[0]["count"] == 2
    assert groups[0]["sample_skus"] == ["ACH-B12", "ACH-B15"]
    assert groups[1]["count"] == 1
