from __future__ import annotations

from unittest.mock import MagicMock

from sqlalchemy import select

from db.models import (
    CollectionCommerceProfile,
    CollectionLandingPage,
    MasterBrand,
    MasterCollectionRegistry,
    MasterProduct,
)
from db.sample_category import (
    discover_sample_master_skus,
    ensure_sample_master_products,
    is_plausible_collection_sample_sku,
    is_sample_hub_path,
    is_sample_master_sku,
    sync_magento_sample_hub,
)


def test_is_sample_master_sku_heuristics():
    assert is_sample_master_sku("ACH-SD") is True
    assert is_sample_master_sku("ACH-SDP") is True
    assert is_sample_master_sku("ACH-B12") is False
    assert is_sample_master_sku("X1", name="SD Sample Door - Anna") is True
    assert is_sample_master_sku("X1", name="Wall Cabinet") is False
    assert is_plausible_collection_sample_sku("ACH-SD") is True
    assert is_plausible_collection_sample_sku("CORONET-HONEY-SD") is True
    assert is_plausible_collection_sample_sku("PB-HE-SD") is True
    assert is_plausible_collection_sample_sku("ANNA-CARAMEL-HARVEST-SD") is False
    assert is_plausible_collection_sample_sku("KITCHEN-CABINETS-HALLMARK-FROST-SD") is False
    assert is_plausible_collection_sample_sku("FROST-ACCESSORIES-SD") is False
    assert is_plausible_collection_sample_sku("anna-caramel-harvest-SD") is False


def test_is_sample_hub_path_allows_root_and_legacy():
    assert is_sample_hub_path("samples") is True
    assert is_sample_hub_path("Samples") is True
    assert is_sample_hub_path("sample") is True
    assert is_sample_hub_path("product-category/sample_doors") is True
    assert is_sample_hub_path("kitchen-cabinets") is False


def test_is_magento_outbound_allows_sample_hub():
    from db.master_taxonomy_product_paths import is_magento_outbound_category_membership

    assert is_magento_outbound_category_membership("samples") is True
    assert is_magento_outbound_category_membership("sample") is True
    assert is_magento_outbound_category_membership("product-category/sample_doors") is True
    assert is_magento_outbound_category_membership("kitchen-cabinets") is False


def test_discover_only_uses_active_collection_landings(catalog_intent_session):
    session = catalog_intent_session
    session.add(MasterProduct(sku="ACH-SD", name="Sample Door", row_hash="1", is_active=True))
    session.add(MasterProduct(sku="POLLUTED-PATH-SD", name="Junk", row_hash="2", is_active=True))
    session.add(
        CollectionLandingPage(
            path_slug="kitchen-cabinets/anna-caramel-harvest",
            page_type="collection",
            category_l1="Kitchen Cabinets",
            collection="Anna Caramel Harvest",
            title="Anna Caramel Harvest",
            sku_prefixes={"items": ["ACH"]},
            is_active=True,
        )
    )
    session.add(
        CollectionCommerceProfile(
            category_l1="Kitchen Cabinets",
            collection_name="Sanibel",
            sample_master_sku="SANIBEL-SD",
            is_active=True,
        )
    )
    session.flush()

    discovered = discover_sample_master_skus(session)
    assert discovered["intent_skus"] == ["ACH-SD"]
    assert "ACH-SD" in discovered["skus"]
    assert "SANIBEL-SD" not in discovered["skus"]
    assert "SANIBEL-SD" not in discovered["missing_master_skus"]
    assert "POLLUTED-PATH-SD" not in discovered["skus"]


def test_ensure_sample_master_products_creates_missing_for_landing(catalog_intent_session):
    session = catalog_intent_session
    brand = MasterBrand(code="port-bell", name="Port & Bell", is_active=True)
    session.add(brand)
    session.flush()
    registry = MasterCollectionRegistry(
        code="SANIBEL",
        name="Sanibel",
        brand_id=brand.id,
        is_active=True,
    )
    session.add(registry)
    session.flush()
    session.add(
        CollectionLandingPage(
            path_slug="kitchen-cabinets/sanibel",
            page_type="collection",
            category_l1="Kitchen Cabinets",
            collection="Sanibel",
            collection_registry_id=registry.id,
            brand="Port & Bell",
            title="Sanibel",
            is_active=True,
        )
    )
    session.add(
        CollectionCommerceProfile(
            collection_registry_id=registry.id,
            category_l1="Kitchen Cabinets",
            collection_name="Sanibel",
            sample_master_sku="SANIBEL-SD",
            is_active=True,
        )
    )
    session.flush()

    result = ensure_sample_master_products(session, dry_run=False)
    assert result["intent_count"] == 1
    assert "SANIBEL-SD" in result["created"]
    product = session.scalar(select(MasterProduct).where(MasterProduct.sku == "SANIBEL-SD"))
    assert product is not None
    assert product.collection == "Sanibel"
    assert product.brand == "Port & Bell"
    assert product.category_l2 == "Samples"
    assert product.is_active is True


def test_ensure_does_not_invent_path_slug_sample_skus(catalog_intent_session):
    session = catalog_intent_session
    registry = MasterCollectionRegistry(
        code="anna-caramel-harvest",
        name="Anna Caramel Harvest",
        is_active=True,
    )
    session.add(registry)
    session.flush()
    session.add(
        CollectionLandingPage(
            path_slug="kitchen-cabinets/anna-caramel-harvest",
            page_type="collection",
            category_l1="Kitchen Cabinets",
            collection="Anna Caramel Harvest",
            collection_registry_id=registry.id,
            title="Anna Caramel Harvest",
            is_active=True,
        )
    )
    session.flush()

    result = ensure_sample_master_products(session, dry_run=False)
    assert result["intent_count"] == 0
    assert result["created"] == []
    assert session.scalar(select(MasterProduct).where(MasterProduct.sku == "ANNA-CARAMEL-HARVEST-SD")) is None


def test_sync_magento_sample_hub_dry_run(catalog_intent_session):
    session = catalog_intent_session
    session.add(MasterProduct(sku="ACH-SD", name="Sample Door", row_hash="1", is_active=True))
    session.add(
        CollectionLandingPage(
            path_slug="kitchen-cabinets/anna-caramel-harvest",
            page_type="collection",
            category_l1="Kitchen Cabinets",
            collection="Anna Caramel Harvest",
            title="Anna Caramel Harvest",
            sku_prefixes={"items": ["ACH"]},
            is_active=True,
        )
    )
    session.flush()

    result = sync_magento_sample_hub(
        session,
        connection_id=4,
        dry_run=True,
    )
    assert result["dry_run"] is True
    assert result["path_slug"] == "samples"
    assert result["remote_path"] == "Samples"
    assert result["sample_sku_count"] == 1
    assert result["sample_skus"] == ["ACH-SD"]
    assert result["would_assign"] == 1


def test_sync_magento_sample_hub_creates_missing_then_assigns(catalog_intent_session, monkeypatch):
    session = catalog_intent_session
    session.add(
        CollectionLandingPage(
            path_slug="kitchen-cabinets/anna-natural-rift-white-oak",
            page_type="collection",
            category_l1="Kitchen Cabinets",
            collection="Anna Natural Rift White Oak",
            title="Anna Natural Rift White Oak",
            is_active=True,
        )
    )
    session.add(
        CollectionCommerceProfile(
            category_l1="Kitchen Cabinets",
            collection_name="Anna Natural Rift White Oak",
            sample_master_sku="ANRWO-SD",
            is_active=True,
        )
    )
    session.flush()

    api = MagicMock()
    api.get_category_products.return_value = (200, [], None)
    api.assign_product_to_category.return_value = (200, {}, None)

    monkeypatch.setattr(
        "db.collection_landing_push._build_magento_api",
        lambda _session, _connection_id: (api, 4),
    )
    monkeypatch.setattr(
        "db.channel_catalog_provision._ensure_magento_category_path",
        lambda *_args, **_kwargs: 501,
    )
    monkeypatch.setattr(
        "db.collection_landing_push._upsert_taxonomy_channel_link_for_path",
        lambda *_args, **_kwargs: None,
    )
    monkeypatch.setattr(
        "db.channel_sku_mapping.mapping_by_master",
        lambda *_args, **_kwargs: {"ANRWO-SD": "ANRWO-SD"},
    )

    result = sync_magento_sample_hub(
        session,
        connection_id=4,
        dry_run=False,
        assign_products=True,
        create_missing_master=True,
    )
    assert result["master_ensure"]["intent_count"] == 1
    assert "ANRWO-SD" in (result["master_ensure"].get("created") or [])
    assert result["category_id"] == 501
    assert result["assigned"] == 1
    assert result["error_count"] == 0
    assert result["missing_master_skus"] == []
    api.assign_product_to_category.assert_called_once_with(501, "ANRWO-SD", position=0)
