from db.models import CollectionLandingPage, MasterTaxonomyNode
from db.start_shopping_config_prune import (
    active_taxonomy_path_set,
    prune_start_shopping_config_dict,
    prune_start_shopping_configs,
    rewrite_path_slug,
)


def test_rewrite_path_slug_exact_and_prefix():
    rewrites = {
        "kitchen-cabinets/base-cabinets": "kitchen-cabinets/bases",
        "kitchen-cabinets/wall-cabinets": None,
    }
    assert rewrite_path_slug("kitchen-cabinets/base-cabinets", rewrites) == "kitchen-cabinets/bases"
    assert (
        rewrite_path_slug("kitchen-cabinets/base-cabinets/sink-base", rewrites)
        == "kitchen-cabinets/bases/sink-base"
    )
    assert rewrite_path_slug("kitchen-cabinets/wall-cabinets", rewrites) is None
    assert rewrite_path_slug("kitchen-cabinets/wall-cabinets/corner-wall", rewrites) is None
    assert rewrite_path_slug("kitchen-cabinets/mouldings", rewrites) == "kitchen-cabinets/mouldings"


def test_prune_start_shopping_config_dict_drops_and_rewrites():
    active = {
        "kitchen-cabinets",
        "kitchen-cabinets/bases",
        "kitchen-cabinets/bases/sink-base",
        "kitchen-cabinets/mouldings",
    }
    config = {
        "hub_path_slug": "kitchen-cabinets",
        "items": [
            {
                "l1_path_slug": "kitchen-cabinets/base-cabinets",
                "l2_path_slugs": [
                    "kitchen-cabinets/base-cabinets/sink-base",
                    "kitchen-cabinets/base-cabinets/gone",
                ],
            },
            {
                "l1_path_slug": "kitchen-cabinets/wall-cabinets",
                "l2_path_slugs": ["kitchen-cabinets/wall-cabinets/corner-wall"],
            },
            {
                "l1_path_slug": "kitchen-cabinets/mouldings",
                "l2_path_slugs": [],
            },
        ],
    }
    pruned, counts = prune_start_shopping_config_dict(
        config,
        active_paths=active,
        path_rewrites={
            "kitchen-cabinets/base-cabinets": "kitchen-cabinets/bases",
            "kitchen-cabinets/wall-cabinets": None,
        },
    )
    assert pruned == {
        "hub_path_slug": "kitchen-cabinets",
        "items": [
            {
                "l1_path_slug": "kitchen-cabinets/bases",
                "l2_path_slugs": ["kitchen-cabinets/bases/sink-base"],
            },
            {
                "l1_path_slug": "kitchen-cabinets/mouldings",
                "l2_path_slugs": [],
            },
        ],
    }
    assert counts["dropped_l1"] >= 1
    assert counts["dropped_l2"] >= 1
    assert counts["rewritten_paths"] >= 1


def test_prune_start_shopping_configs_persists_and_dry_run(catalog_intent_session):
    session = catalog_intent_session
    session.add_all(
        [
            MasterTaxonomyNode(
                parent_id=None,
                node_kind="hub",
                code="kitchen-cabinets",
                name="Kitchen Cabinets",
                path_slug="kitchen-cabinets",
                sort_order=1,
            ),
            MasterTaxonomyNode(
                parent_id=None,
                node_kind="category",
                code="base-cabinets",
                name="Base Cabinets",
                path_slug="kitchen-cabinets/base-cabinets",
                sort_order=10,
            ),
            MasterTaxonomyNode(
                parent_id=None,
                node_kind="collection",
                code="anna-snow-white",
                name="Anna Snow White",
                path_slug="kitchen-cabinets/anna-snow-white",
                sort_order=20,
            ),
        ]
    )
    session.flush()
    page = CollectionLandingPage(
        path_slug="kitchen-cabinets/anna-snow-white",
        page_type="collection",
        category_l1="Kitchen Cabinets",
        collection="Anna Snow White",
        title="Anna Snow White",
        parent_path_slug="kitchen-cabinets",
        start_shopping_config={
            "hub_path_slug": "kitchen-cabinets",
            "items": [
                {
                    "l1_path_slug": "kitchen-cabinets/base-cabinets",
                    "l2_path_slugs": ["kitchen-cabinets/base-cabinets/missing-child"],
                },
                {
                    "l1_path_slug": "kitchen-cabinets/wall-cabinets",
                    "l2_path_slugs": [],
                },
            ],
        },
        is_active=True,
        sort_order=100,
    )
    session.add(page)
    session.flush()

    dry = prune_start_shopping_configs(session, dry_run=True, refresh_intersections=False)
    assert dry["updated_count"] == 1
    assert dry["dropped_l1"] == 1
    assert dry["dropped_l2"] == 1
    session.refresh(page)
    assert page.start_shopping_config["items"][1]["l1_path_slug"] == "kitchen-cabinets/wall-cabinets"

    applied = prune_start_shopping_configs(session, dry_run=False, refresh_intersections=False)
    assert applied["updated_count"] == 1
    session.refresh(page)
    assert page.start_shopping_config == {
        "hub_path_slug": "kitchen-cabinets",
        "items": [
            {
                "l1_path_slug": "kitchen-cabinets/base-cabinets",
                "l2_path_slugs": [],
            }
        ],
    }


def test_active_taxonomy_path_set_excludes_descendants_of_inactive_parent(catalog_intent_session):
    session = catalog_intent_session
    hub = MasterTaxonomyNode(
        parent_id=None,
        node_kind="hub",
        code="kitchen-cabinets",
        name="Kitchen Cabinets",
        path_slug="kitchen-cabinets",
        sort_order=1,
        is_active=True,
    )
    session.add(hub)
    session.flush()
    tall = MasterTaxonomyNode(
        parent_id=hub.id,
        node_kind="category",
        code="tall",
        name="Tall",
        path_slug="kitchen-cabinets/tall",
        sort_order=2,
        is_active=False,
    )
    session.add(tall)
    session.flush()
    pantry = MasterTaxonomyNode(
        parent_id=tall.id,
        node_kind="category",
        code="pantry-cabinet",
        name="Pantry Cabinet",
        path_slug="kitchen-cabinets/tall/pantry-cabinet",
        sort_order=3,
        is_active=True,
    )
    session.add(pantry)
    session.flush()

    active_paths = active_taxonomy_path_set(session)

    assert "kitchen-cabinets" in active_paths
    assert "kitchen-cabinets/tall" not in active_paths
    assert "kitchen-cabinets/tall/pantry-cabinet" not in active_paths
