from pathlib import Path
import uuid

from app.jobs.cleanup_inactive_collection_registry import cleanup_inactive_collection_registry
from db.models import (
    BrochureTaxonomyGroup,
    BrochureTaxonomyGroupSku,
    CollectionCommerceProfile,
    ManualTaxonomyAssignment,
    ManualTaxonomyAssignmentCollection,
    MasterCollectionRegistry,
    MasterProduct,
)


def _write_dump_file(lines: list[str]) -> Path:
    path = Path("tests") / f"_tmp_collection_registry_{uuid.uuid4().hex}.csv"
    path.write_text("\n".join(lines), encoding="utf-8")
    return path


def test_cleanup_remaps_mapped_inactive_rows_and_deletes_registry_rows(catalog_intent_session):
    active = MasterCollectionRegistry(
        id=77,
        code="ASW",
        name="Anna Snow White",
        path_slug="kitchen-cabinets/anna-snow-white",
        aliases={"source_collection_code": "ASW"},
        is_active=True,
    )
    inactive = MasterCollectionRegistry(
        id=3,
        code="anna-snow-white",
        name="Anna Snow White",
        path_slug="kitchen-cabinets/anna-snow-white",
        is_active=False,
    )
    product = MasterProduct(
        sku="PB-PW-BF3",
        name="Pearl White Base Filler",
        row_hash="hash-1",
        collection_registry_id=3,
    )
    catalog_intent_session.add_all([active, inactive, product])
    catalog_intent_session.flush()

    dump_path = _write_dump_file(
        [
            "id,code,name,path_slug,brand_id,family_id,aliases,is_active,notes,created_at,updated_at",
            '77,ASW,Anna Snow White,kitchen-cabinets/anna-snow-white,13,1,"{""source_collection_code"": ""ASW""}",t,,2026-07-21,2026-07-23',
            "3,anna-snow-white,Anna Snow White,kitchen-cabinets/anna-snow-white,12,1,,f,,2026-06-19,2026-06-19",
        ]
    )

    try:
        summary = cleanup_inactive_collection_registry(
            catalog_intent_session,
            dump_path=dump_path,
            dry_run=False,
        )
        catalog_intent_session.flush()
    finally:
        dump_path.unlink(missing_ok=True)

    refreshed = catalog_intent_session.get(MasterProduct, product.id)
    assert refreshed.collection_registry_id == 77
    assert catalog_intent_session.get(MasterCollectionRegistry, 3) is None
    assert summary["mapped_inactive_rows"] == 1
    assert summary["steps"]["master_product"]["updated"] == 1
    assert summary["steps"]["master_collection_registry"]["deleted"] == 1


def test_cleanup_deletes_orphan_manual_assignment_collections_without_active_match(catalog_intent_session):
    active = MasterCollectionRegistry(
        id=77,
        code="ASW",
        name="Anna Snow White",
        path_slug="kitchen-cabinets/anna-snow-white",
        aliases={"source_collection_code": "ASW"},
        is_active=True,
    )
    orphan = MasterCollectionRegistry(
        id=18,
        code="cooper-slate",
        name="Cooper Slate",
        path_slug="kitchen-cabinets/cooper-slate",
        is_active=False,
    )
    assignment = ManualTaxonomyAssignment(
        source_sku="PB-CSG-BF3",
        canonical_taxonomy_path_slug="kitchen-cabinets/base-cabinets",
    )
    catalog_intent_session.add_all([active, orphan, assignment])
    catalog_intent_session.flush()
    child = ManualTaxonomyAssignmentCollection(
        assignment_id=assignment.id,
        collection_registry_id=18,
        collection_code="cooper-slate",
        sku_prefix="cooper-slate",
        collection_name="Cooper Slate",
        collection_path_slug="kitchen-cabinets/cooper-slate",
        shopping_collection="Cooper Slate",
        master_sku="PB-CSG-BF3",
    )
    catalog_intent_session.add(child)
    catalog_intent_session.flush()

    dump_path = _write_dump_file(
        [
            "id,code,name,path_slug,brand_id,family_id,aliases,is_active,notes,created_at,updated_at",
            '77,ASW,Anna Snow White,kitchen-cabinets/anna-snow-white,13,1,"{""source_collection_code"": ""ASW""}",t,,2026-07-21,2026-07-23',
            "18,cooper-slate,Cooper Slate,kitchen-cabinets/cooper-slate,12,1,,f,,2026-06-19,2026-06-19",
        ]
    )

    try:
        summary = cleanup_inactive_collection_registry(
            catalog_intent_session,
            dump_path=dump_path,
            dry_run=False,
        )
        catalog_intent_session.flush()
    finally:
        dump_path.unlink(missing_ok=True)

    assert catalog_intent_session.get(ManualTaxonomyAssignmentCollection, child.id) is None
    assert catalog_intent_session.get(MasterCollectionRegistry, 18) is None
    assert summary["unmapped_inactive_rows"] == 1
    assert summary["steps"]["manual_taxonomy_assignment_collection"]["deleted_orphans"] == 1


def test_cleanup_can_build_plan_from_database_without_dump(catalog_intent_session):
    active = MasterCollectionRegistry(
        id=77,
        code="ASW",
        name="Anna Snow White",
        path_slug="kitchen-cabinets/anna-snow-white",
        aliases={"source_collection_code": "ASW"},
        is_active=True,
    )
    inactive = MasterCollectionRegistry(
        id=3,
        code="anna-snow-white",
        name="Anna Snow White",
        path_slug="kitchen-cabinets/anna-snow-white",
        is_active=False,
    )
    product = MasterProduct(
        sku="PB-PW-BF3",
        name="Pearl White Base Filler",
        row_hash="hash-2",
        collection_registry_id=3,
    )
    catalog_intent_session.add_all([active, inactive, product])
    catalog_intent_session.flush()

    summary = cleanup_inactive_collection_registry(
        catalog_intent_session,
        dry_run=False,
    )
    catalog_intent_session.flush()

    refreshed = catalog_intent_session.get(MasterProduct, product.id)
    assert refreshed.collection_registry_id == 77
    assert catalog_intent_session.get(MasterCollectionRegistry, 3) is None
    assert summary["source"] == "database"
    assert summary["steps"]["master_product"]["updated"] == 1


def test_cleanup_merges_collection_commerce_profile_into_existing_active_scope(catalog_intent_session):
    active = MasterCollectionRegistry(
        id=75,
        code="ACH",
        name="Anna Caramel Harvest",
        path_slug="kitchen-cabinets/anna-caramel-harvest",
        aliases={"source_collection_code": "ACH"},
        is_active=True,
    )
    inactive = MasterCollectionRegistry(
        id=36,
        code="anna-caramel-harvest",
        name="Anna Caramel Harvest",
        path_slug="kitchen-cabinets/anna-caramel-harvest",
        is_active=False,
    )
    catalog_intent_session.add_all([active, inactive])
    catalog_intent_session.flush()

    keep = CollectionCommerceProfile(
        collection_registry_id=75,
        channel_code="magento",
        connection_id=4,
        collection_name="Anna Caramel Harvest",
        notes="keep me",
    )
    duplicate = CollectionCommerceProfile(
        collection_registry_id=36,
        channel_code="magento",
        connection_id=4,
        collection_name="Anna Caramel Harvest",
        notes="remove me",
    )
    catalog_intent_session.add_all([keep, duplicate])
    catalog_intent_session.flush()

    summary = cleanup_inactive_collection_registry(
        catalog_intent_session,
        dry_run=False,
    )
    catalog_intent_session.flush()

    rows = catalog_intent_session.query(CollectionCommerceProfile).all()
    assert len(rows) == 1
    assert rows[0].id == keep.id
    assert rows[0].collection_registry_id == 75
    assert catalog_intent_session.get(MasterCollectionRegistry, 36) is None
    assert summary["steps"]["collection_commerce_profile"]["deleted_duplicates"] == 1


def test_cleanup_normalizes_manual_assignment_payload_prefix_from_collection_name(catalog_intent_session):
    active = MasterCollectionRegistry(
        id=76,
        code="ANRO",
        name="Anna Natural Rift White Oak",
        path_slug="kitchen-cabinets/anna-natural-rift-white-oak",
        aliases={"source_collection_code": "ANRO", "alias_codes": ["ANRO"]},
        is_active=True,
    )
    assignment = ManualTaxonomyAssignment(
        source_sku="WDC2430",
        canonical_taxonomy_path_slug="kitchen-cabinets/wall-cabinets",
        assignment_status="active",
        raw_payload={
            "source_sku": "WDC2430",
            "canonical_taxonomy_path_slug": "kitchen-cabinets/wall-cabinets",
            "collections": [
                {
                    "master_sku": "ANRWO-WDC2430",
                    "sku_prefix": "ANRWO",
                    "alias_codes": ["ANRWO"],
                    "collection_code": "ANRO",
                    "collection_name": "Anna Natural Rift White Oak",
                }
            ],
        },
    )
    catalog_intent_session.add_all([active, assignment])
    catalog_intent_session.flush()
    child = ManualTaxonomyAssignmentCollection(
        assignment_id=assignment.id,
        collection_registry_id=76,
        collection_code="ANRO",
        source_collection_code="ANRO",
        sku_prefix="ANRWO",
        collection_name="Anna Natural Rift White Oak",
        collection_path_slug="kitchen-cabinets/anna-natural-rift-white-oak",
        shopping_collection="Anna Natural Rift White Oak",
        master_sku="ANRWO-WDC2430",
        alias_codes=["ANRWO"],
        is_active=True,
    )
    catalog_intent_session.add(child)
    catalog_intent_session.flush()

    summary = cleanup_inactive_collection_registry(
        catalog_intent_session,
        dry_run=False,
    )
    catalog_intent_session.flush()

    refreshed_child = catalog_intent_session.get(ManualTaxonomyAssignmentCollection, child.id)
    refreshed_assignment = catalog_intent_session.get(ManualTaxonomyAssignment, assignment.id)
    collections = refreshed_assignment.raw_payload.get("collections") or []

    assert refreshed_child.sku_prefix == "ANRO"
    assert refreshed_child.master_sku == "ANRO-WDC2430"
    assert refreshed_child.alias_codes == ["ANRO"]
    assert len(collections) == 1
    assert collections[0]["sku_prefix"] == "ANRO"
    assert collections[0]["master_sku"] == "ANRO-WDC2430"
    assert collections[0]["alias_codes"] == ["ANRO"]
    assert summary["steps"]["manual_taxonomy_assignment_normalization"]["updated_child_rows"] == 1
    assert summary["steps"]["manual_taxonomy_assignment_normalization"]["updated_payloads"] == 1


def test_cleanup_reparents_brochure_group_skus_before_deleting_duplicate_group(catalog_intent_session):
    active = MasterCollectionRegistry(
        id=75,
        code="ACH",
        name="Anna Caramel Harvest",
        path_slug="kitchen-cabinets/anna-caramel-harvest",
        aliases={"source_collection_code": "ACH"},
        is_active=True,
    )
    inactive = MasterCollectionRegistry(
        id=36,
        code="anna-caramel-harvest",
        name="Anna Caramel Harvest",
        path_slug="kitchen-cabinets/anna-caramel-harvest",
        is_active=False,
    )
    keep_group = BrochureTaxonomyGroup(
        collection_registry_id=75,
        brochure_collection_code="ACH",
        category_l1="Kitchen Cabinets",
        brochure_l1_label="Base Cabinets",
        brochure_l2_label="Single Door",
        brochure_leaf_label="BH09",
        brochure_path_text="Kitchen Cabinets / Base Cabinets / Single Door / BH09",
    )
    drop_group = BrochureTaxonomyGroup(
        collection_registry_id=36,
        brochure_collection_code="anna-caramel-harvest",
        category_l1="Kitchen Cabinets",
        brochure_l1_label="Base Cabinets",
        brochure_l2_label="Single Door",
        brochure_leaf_label="BH09",
        brochure_path_text="Kitchen Cabinets / Base Cabinets / Single Door / BH09",
    )
    catalog_intent_session.add_all([active, inactive])
    catalog_intent_session.flush()
    catalog_intent_session.add_all([keep_group, drop_group])
    catalog_intent_session.flush()
    keep_child = BrochureTaxonomyGroupSku(group_id=keep_group.id, brochure_sku="ACH-BH09")
    move_child = BrochureTaxonomyGroupSku(group_id=drop_group.id, brochure_sku="ACH-BH10")
    dup_child = BrochureTaxonomyGroupSku(group_id=drop_group.id, brochure_sku="ACH-BH09")
    catalog_intent_session.add_all([keep_child, move_child, dup_child])
    catalog_intent_session.flush()

    summary = cleanup_inactive_collection_registry(
        catalog_intent_session,
        dry_run=False,
    )
    catalog_intent_session.flush()

    groups = catalog_intent_session.query(BrochureTaxonomyGroup).order_by(BrochureTaxonomyGroup.id).all()
    children = catalog_intent_session.query(BrochureTaxonomyGroupSku).order_by(BrochureTaxonomyGroupSku.brochure_sku).all()
    assert len(groups) == 1
    assert groups[0].id == keep_group.id
    assert [(row.group_id, row.brochure_sku) for row in children] == [
        (keep_group.id, "ACH-BH09"),
        (keep_group.id, "ACH-BH10"),
    ]
    assert summary["steps"]["brochure_taxonomy_group"]["deleted_duplicates"] == 1
