from sqlalchemy import select

from db.master_taxonomy_hierarchy import NODE_COLLECTION, NODE_HUB
from db.master_taxonomy_intent import apply_taxonomy_proposals, summarize_import_taxonomy_intent
from db.models import MasterProduct, MasterTaxonomyNode


def test_summarize_import_proposes_unknown_collection(catalog_intent_session):
    session = catalog_intent_session
    session.add(
        MasterProduct(
            sku="NEW-1",
            name="New",
            category_l1="Kitchen Cabinets",
            collection="Brand New Collection",
            row_hash="h1",
            is_active=True,
        )
    )
    session.flush()

    records = [
        {
            "sku": "NEW-1",
            "category_l1": "Kitchen Cabinets",
            "collection": "Brand New Collection",
            "attributes": {},
        }
    ]
    intent = summarize_import_taxonomy_intent(session, records)
    assert intent["row_count"] == 1
    proposed_slugs = {p["path_slug"] for p in intent["proposed_nodes"]}
    assert any("brand-new-collection" in s for s in proposed_slugs)


def test_summarize_import_prefers_anna_caramel_harvest_over_suffix(catalog_intent_session):
    session = catalog_intent_session
    session.add(
        MasterProduct(
            sku="ACH-B12",
            name="B12 - Anna Caramel Harvest",
            category_l1="Kitchen Cabinets",
            collection="Anna Caramel Harvest",
            row_hash="h-ach",
            is_active=True,
        )
    )
    session.flush()

    records = [
        {
            "sku": "ACH-B12",
            "category_l1": "Kitchen Cabinets",
            "collection": "Anna Caramel Harvest",
            "attributes": {"cabinet_type_sub_category_1": "Base"},
        },
        {
            "sku": "PB-CH-BF3",
            "category_l1": "Kitchen Cabinets",
            "collection": "Caramel Harvest",
            "attributes": {"cabinet_type_sub_category_1": "Base"},
        },
    ]
    intent = summarize_import_taxonomy_intent(session, records)
    proposed_slugs = {p["path_slug"] for p in intent["proposed_nodes"]}
    proposed_names = {p.get("name") for p in intent["proposed_nodes"]}

    assert "kitchen-cabinets/anna-caramel-harvest" in proposed_slugs
    assert "kitchen-cabinets/caramel-harvest" not in proposed_slugs
    assert "Kitchen Cabinets / Anna Caramel Harvest" in proposed_names
    assert "Kitchen Cabinets / Caramel Harvest" not in proposed_names


def test_summarize_import_prefers_active_maple_over_inactive_espresso(catalog_intent_session):
    """Short Plymouth Espresso must not reactivate when preferred maple node is active."""
    session = catalog_intent_session
    hub = MasterTaxonomyNode(
        parent_id=None,
        node_kind=NODE_HUB,
        code="kitchen-cabinets",
        name="Kitchen Cabinets",
        path_slug="kitchen-cabinets",
        is_active=True,
    )
    session.add(hub)
    session.flush()
    session.add(
        MasterTaxonomyNode(
            parent_id=hub.id,
            node_kind=NODE_COLLECTION,
            code="plymouth-espresso",
            name="Plymouth Espresso",
            path_slug="kitchen-cabinets/plymouth-espresso",
            is_active=False,
        )
    )
    maple = MasterTaxonomyNode(
        parent_id=hub.id,
        node_kind=NODE_COLLECTION,
        code="plymouth-espresso-maple",
        name="Plymouth Espresso Maple",
        path_slug="kitchen-cabinets/plymouth-espresso-maple",
        is_active=True,
    )
    session.add(maple)
    session.add(
        MasterProduct(
            sku="PEM-B12",
            name="Base",
            category_l1="Kitchen Cabinets",
            collection="Plymouth Espresso",
            row_hash="h-pem",
            is_active=True,
        )
    )
    session.flush()

    intent = summarize_import_taxonomy_intent(
        session,
        [
            {
                "sku": "PEM-B12",
                "category_l1": "Kitchen Cabinets",
                "collection": "Plymouth Espresso",
                "attributes": {},
            }
        ],
    )
    proposed_slugs = {p["path_slug"] for p in intent["proposed_nodes"]}
    assert "kitchen-cabinets/plymouth-espresso" not in proposed_slugs

    matched_slugs = {
        match["path_slug"]
        for row in intent["sku_rows"]
        for match in row.get("matched_nodes") or []
    }
    assert "kitchen-cabinets/plymouth-espresso-maple" in matched_slugs


def test_summarize_import_rejects_suffix_only_root_collections(catalog_intent_session):
    session = catalog_intent_session
    session.add(
        MasterProduct(
            sku="EOB-BF3",
            name="BF3",
            category_l1="Kitchen Cabinets",
            collection="Eleanor Ocean Blue",
            row_hash="h-eob-full",
            is_active=True,
        )
    )
    session.add(
        MasterProduct(
            sku="HPW-B15",
            name="Base",
            category_l1="Kitchen Cabinets",
            collection="Harriet Pearl White",
            row_hash="h-hpw",
            is_active=True,
        )
    )
    session.add(
        MasterProduct(
            sku="FHF-B12",
            name="Base",
            category_l1="Kitchen Cabinets",
            collection="Hallmark Frost",
            row_hash="h-fhf",
            is_active=True,
        )
    )
    session.flush()

    records = [
        {
            "sku": "EOB-BF3",
            "category_l1": "Kitchen Cabinets",
            "collection": "Ocean Blue",
            "attributes": {},
        },
        {
            "sku": "PB-OB-BF3",
            "category_l1": "Kitchen Cabinets",
            "collection": "Ocean Blue",
            "attributes": {},
        },
        {
            "sku": "HPW-B15",
            "category_l1": "Kitchen Cabinets",
            "collection": "Pearl White",
            "attributes": {},
        },
        {
            "sku": "FHF-B12",
            "category_l1": "Kitchen Cabinets",
            "collection": "Frost",
            "attributes": {},
        },
    ]
    intent = summarize_import_taxonomy_intent(session, records)
    proposed_slugs = {p["path_slug"] for p in intent["proposed_nodes"]}

    assert "kitchen-cabinets/eleanor-ocean-blue" in proposed_slugs
    assert "ocean-blue" not in proposed_slugs
    assert "kitchen-cabinets/ocean-blue" not in proposed_slugs
    assert "kitchen-cabinets/harriet-pearl-white" in proposed_slugs
    assert "pearl-white" not in proposed_slugs
    assert "kitchen-cabinets/hallmark-frost" in proposed_slugs
    assert "frost" not in proposed_slugs


def test_apply_proposals_creates_nodes(catalog_intent_session):
    session = catalog_intent_session
    session.add(
        MasterTaxonomyNode(
            parent_id=None,
            node_kind=NODE_HUB,
            code="kitchen-cabinets",
            name="Kitchen Cabinets",
            path_slug="kitchen-cabinets",
            is_active=True,
        )
    )
    session.flush()

    result = apply_taxonomy_proposals(
        session,
        [
            {
                "approved": True,
                "name": "Kitchen Cabinets / Brand New Collection",
                "path_slug": "kitchen-cabinets/brand-new-collection",
                "node_kind": NODE_COLLECTION,
                "parent_path_slug": "kitchen-cabinets",
            }
        ],
        dry_run=False,
        allow_invent=True,
    )
    session.flush()
    assert result["created_count"] == 1
    node = session.scalar(
        select(MasterTaxonomyNode).where(MasterTaxonomyNode.path_slug == "kitchen-cabinets/brand-new-collection").limit(1)
    )
    assert node is not None
    assert node.node_kind == NODE_COLLECTION


def test_apply_proposals_reactivates_existing_inactive_path_slug(catalog_intent_session):
    session = catalog_intent_session
    hub = MasterTaxonomyNode(
        parent_id=None,
        node_kind=NODE_HUB,
        code="kitchen-cabinets",
        name="Kitchen Cabinets",
        path_slug="kitchen-cabinets",
        is_active=True,
    )
    session.add(hub)
    session.flush()
    inactive = MasterTaxonomyNode(
        parent_id=hub.id,
        node_kind=NODE_COLLECTION,
        code="plymouth-espresso",
        name="Plymouth Espresso",
        path_slug="kitchen-cabinets/plymouth-espresso",
        is_active=False,
    )
    session.add(inactive)
    session.flush()
    inactive_id = inactive.id

    result = apply_taxonomy_proposals(
        session,
        [
            {
                "approved": True,
                "name": "Kitchen Cabinets / Plymouth Espresso",
                "path_slug": "kitchen-cabinets/plymouth-espresso",
                "node_kind": NODE_COLLECTION,
                "parent_path_slug": "kitchen-cabinets",
            }
        ],
        dry_run=False,
        allow_invent=True,
    )
    session.flush()

    assert result["created_count"] == 0
    assert result["updated_count"] == 1
    node = session.get(MasterTaxonomyNode, inactive_id)
    assert node is not None
    assert node.is_active is True
    assert node.path_slug == "kitchen-cabinets/plymouth-espresso"
