import json
import shutil
from pathlib import Path

from sqlalchemy import select

from db.kitchen_cabinets_taxonomy_import import (
    build_seed_payload_from_taxonomy_collection,
    expand_taxonomy_collections_with_brochure_twins,
    seed_kitchen_cabinets_taxonomy,
)
from db.models import BrochureTaxonomyGroup, MasterCollectionRegistry, MasterTaxonomyNode


def test_expand_taxonomy_collections_with_brochure_twins_copies_declared_sibling():
    taxonomy_payload = {
        "collections": {
            "johnson-sandstone": {
                "display_name": "Johnson Sandstone",
                "sku_count": 1,
                "assignments": [
                    {
                        "sku": "GD-W1530",
                        "l2_category": "Accessories",
                        "l3_category": "Loose Glass Door",
                    }
                ],
            }
        }
    }
    brochure_payloads = {
        "johnson-sandstone": {
            "collection": {"canonical_code": "johnson-sandstone", "display_name": "Johnson Sandstone"},
            "source_document": {"notes": []},
        },
        "johnson-white": {
            "collection": {"canonical_code": "johnson-white", "display_name": "Johnson White"},
            "source_document": {
                "notes": ["Brand/line relationship inherited from Johnson Sandstone brochure sibling."]
            },
        },
    }

    expanded, summary = expand_taxonomy_collections_with_brochure_twins(taxonomy_payload, brochure_payloads)

    assert expanded["collections"]["johnson-white"]["display_name"] == "Johnson White"
    assert expanded["collections"]["johnson-white"]["assignments"][0]["sku"] == "GD-W1530"
    assert expanded["collections"]["johnson-white"]["copied_from_collection"] == "johnson-sandstone"
    assert summary["created"][0]["canonical_code"] == "johnson-white"


def test_seed_kitchen_cabinets_taxonomy_seeds_twin_collection_groups(catalog_intent_session):
    scratch = Path("E:/workroom/2026/PlytixMage/.tmp_test_kitchen_taxonomy")
    if scratch.exists():
        shutil.rmtree(scratch)
    try:
        brochure_dir = scratch / "brochures"
        brochure_dir.mkdir(parents=True)
        taxonomy_path = scratch / "kitchen_cabinets_taxonomy.json"

        taxonomy_path.write_text(
            json.dumps(
                {
                    "master_taxonomy_reference": {
                        "confirmed_hierarchy": {"Accessories": ["Loose Glass Door"]},
                        "proposed_new_l3_categories": {},
                    },
                    "collections": {
                        "johnson-sandstone": {
                            "display_name": "Johnson Sandstone",
                            "sku_count": 1,
                            "assignments": [
                                {
                                    "sku": "GD-W1530",
                                    "l2_category": "Accessories",
                                    "l3_category": "Loose Glass Door",
                                    "source_family": "accessories",
                                    "source_sku_type": "glass_door",
                                    "confidence": "high",
                                }
                            ],
                        }
                    },
                }
            ),
            encoding="utf-8",
        )

        (brochure_dir / "JohnsonSandstone_0226.json").write_text(
            json.dumps(
                {
                    "source_document": {"collection_code": "JS", "file_name": "JohnsonSandstone_0226.pdf", "notes": []},
                    "collection": {
                        "canonical_code": "johnson-sandstone",
                        "display_name": "Johnson Sandstone",
                        "brand_label": "Legion Manor",
                        "line_name": "Johnson",
                        "color_label": "Sandstone",
                        "category_l1": "Kitchen Cabinets",
                        "product_family": "Cabinets",
                    },
                    "availability": {"modes": []},
                    "matching_styles": [],
                    "sample_products": [],
                    "specifications": {},
                    "kitchen_packages": [],
                }
            ),
            encoding="utf-8",
        )
        (brochure_dir / "JohnsonWhite_site.json").write_text(
            json.dumps(
                {
                    "source_document": {
                        "collection_code": "JW",
                        "notes": ["Brand/line relationship inherited from Johnson Sandstone brochure sibling."],
                    },
                    "collection": {
                        "canonical_code": "johnson-white",
                        "display_name": "Johnson White",
                        "brand_label": "Legion Manor",
                        "line_name": "Johnson",
                        "color_label": "White",
                        "category_l1": "Kitchen Cabinets",
                        "product_family": "Cabinets",
                    },
                    "availability": {"modes": []},
                    "matching_styles": [],
                    "sample_products": [],
                    "specifications": {},
                    "kitchen_packages": [],
                }
            ),
            encoding="utf-8",
        )

        result = seed_kitchen_cabinets_taxonomy(
            catalog_intent_session,
            taxonomy_path=taxonomy_path,
            brochure_folder=brochure_dir,
        )

        registry = catalog_intent_session.scalar(
            select(MasterCollectionRegistry).where(MasterCollectionRegistry.code == "JW")
        )
        assert registry is not None
        assert registry.name == "Johnson White"
        assert any(item["canonical_code"] == "johnson-white" for item in result["twin_expansion"]["created"])

        groups = list(
            catalog_intent_session.scalars(
                select(BrochureTaxonomyGroup).where(BrochureTaxonomyGroup.collection_registry_id == registry.id)
            ).all()
        )
        assert len(groups) == 1
        assert groups[0].canonical_taxonomy_path_label == "Kitchen Cabinets / Accessories / Loose Glass Door"

        node = catalog_intent_session.scalar(
            select(MasterTaxonomyNode).where(
                MasterTaxonomyNode.path_slug == "kitchen-cabinets/accessories/loose-glass-door"
            )
        )
        assert node is not None
    finally:
        if scratch.exists():
            shutil.rmtree(scratch)


def test_build_seed_payload_prefers_explicit_canonical_taxonomy_path_slug():
    collection_entry = {
        "display_name": "Anna Caramel Harvest",
        "assignments": [
            {
                "sku": "BEC1224L",
                "l2_category": "Base Cabinets",
                "l3_category": "Angle End",
                "canonical_taxonomy_path_slug": "kitchen-cabinets/base-cabinets/angle-end-base-cabinet",
            }
        ],
    }
    brochure_payload = {
        "collection": {
            "canonical_code": "anna-caramel-harvest",
            "display_name": "Anna Caramel Harvest",
            "category_l1": "Kitchen Cabinets",
        }
    }

    payload = build_seed_payload_from_taxonomy_collection(collection_entry, brochure_payload)

    assert payload["taxonomy_groups"][0]["brochure_l1_label"] == "Base Cabinets"
    assert payload["taxonomy_groups"][0]["brochure_l2_label"] == "Angle End"
    assert payload["taxonomy_groups"][0]["canonical_taxonomy_path_slug"] == (
        "kitchen-cabinets/base-cabinets/angle-end-base-cabinet"
    )
    assert payload["taxonomy_groups"][0]["canonical_taxonomy_path_label"] == (
        "Kitchen Cabinets / Base Cabinets / Angle End Base Cabinet"
    )


def test_sanitize_strips_polluted_clearance_kit_collection_paths():
    from db.kitchen_cabinets_taxonomy_import import (
        sanitize_brochure_collection_payload,
        sanitize_kitchen_cabinets_taxonomy_payload,
    )

    taxonomy = {
        "master_taxonomy_reference": {
            "confirmed_hierarchy": {"Accessories": ["Clearance Kit"]},
            "cross_l2_notes": [],
        },
        "collections": {
            "anna-snow-white": {
                "display_name": "Anna Snow White",
                "path_slug": "kitchen-cabinets/anna-snow-white",
                "assignments": [],
            },
            "bad-clearance": {
                "display_name": "Clearance Kit Base Cabinets",
                "path_slug": "kitchen-cabinets/accessories/clearance-kit/base-cabinets",
                "assignments": [],
            },
        },
    }
    cleaned = sanitize_kitchen_cabinets_taxonomy_payload(taxonomy)
    assert "bad-clearance" not in cleaned["payload"]["collections"]
    assert "anna-snow-white" in cleaned["payload"]["collections"]
    assert any("never finish collections" in n.lower() for n in cleaned["payload"]["master_taxonomy_reference"]["cross_l2_notes"])

    brochure = {
        "collection": {"canonical_code": "ACH", "display_name": "Anna"},
        "taxonomy_groups": [
            {
                "canonical_taxonomy_path_slug": "kitchen-cabinets/accessories/clearance-kit",
                "skus": ["CK1"],
            },
            {
                "canonical_taxonomy_path_slug": "kitchen-cabinets/accessories/clearance-kit/base-cabinets/double-door-base-cabinet",
                "skus": ["B12"],
            },
        ],
        "start_shopping_config": {
            "items": [
                {"path": "kitchen-cabinets/accessories/clearance-kit/base-cabinets"},
                {"path": "kitchen-cabinets/anna-snow-white/base-cabinets"},
            ]
        },
    }
    brochure_cleaned = sanitize_brochure_collection_payload(brochure)
    slugs = [
        g["canonical_taxonomy_path_slug"] for g in brochure_cleaned["payload"]["taxonomy_groups"]
    ]
    assert "kitchen-cabinets/accessories/clearance-kit" in slugs
    assert all("/clearance-kit/base-cabinets" not in s for s in slugs)
