from app.jobs.impute_collection_filter_attributes import impute_collection_filter_attributes
from db.models import MasterProduct, MasterProductAttributeValue


def _product(sku: str, collection: str) -> MasterProduct:
    return MasterProduct(
        sku=sku,
        name=sku,
        collection=collection,
        status="active",
        row_hash=sku,
        is_active=True,
    )


def test_impute_collection_filter_attributes_uses_pipeline_derived_values(catalog_intent_session):
    filled_1 = _product("ASW-B12", "Anna Snow White")
    filled_2 = _product("ASW-B15", "Anna Snow White")
    missing = _product("ASW-B18", "Anna Snow White")
    other = _product("OTHER-B12", "Other")
    catalog_intent_session.add_all([filled_1, filled_2, missing, other])
    catalog_intent_session.flush()
    catalog_intent_session.add_all(
        [
            MasterProductAttributeValue(
                product_id=filled_1.id,
                sku=filled_1.sku,
                attribute_code="cabinet_door_style",
                value="shaker",
            ),
            MasterProductAttributeValue(
                product_id=filled_2.id,
                sku=filled_2.sku,
                attribute_code="door_style",
                value="Shaker",
            ),
            MasterProductAttributeValue(
                product_id=other.id,
                sku=other.sku,
                attribute_code="door_style",
                value="Slab",
            ),
        ]
    )
    catalog_intent_session.commit()

    preview = impute_collection_filter_attributes(
        catalog_intent_session,
        attributes=["door_style"],
        min_coverage_pct=100,
        min_observed=2,
        dry_run=True,
    )

    assert preview["would_update"] == 1
    assert preview["suggestions"][0]["collection"] == "Anna Snow White"
    assert preview["suggestions"][0]["value"] == "Shaker"
    assert preview["suggestions"][0]["sample_missing_skus"] == ["ASW-B18"]

    applied = impute_collection_filter_attributes(
        catalog_intent_session,
        attributes=["door_style"],
        min_coverage_pct=100,
        min_observed=2,
        dry_run=False,
    )
    catalog_intent_session.commit()

    assert applied["updated"] == 1
    row = (
        catalog_intent_session.query(MasterProductAttributeValue)
        .filter_by(product_id=missing.id, attribute_code="door_style")
        .one()
    )
    assert row.value == "Shaker"
    assert row.source_label == "collection_filter_impute"


def test_impute_skips_polluted_suffix_only_collections_and_reports_clean_count(catalog_intent_session):
    short_1 = _product("PE-B12", "Plymouth Espresso")
    short_2 = _product("PE-B15", "Plymouth Espresso")
    full_1 = _product("PEM-B12", "Plymouth Espresso Maple")
    full_2 = _product("PEM-B15", "Plymouth Espresso Maple")
    full_missing = _product("PEM-B18", "Plymouth Espresso Maple")
    catalog_intent_session.add_all([short_1, short_2, full_1, full_2, full_missing])
    catalog_intent_session.flush()
    catalog_intent_session.add_all(
        [
            MasterProductAttributeValue(
                product_id=short_1.id,
                sku=short_1.sku,
                attribute_code="door_style",
                value="Slab",
            ),
            MasterProductAttributeValue(
                product_id=short_2.id,
                sku=short_2.sku,
                attribute_code="door_style",
                value="Slab",
            ),
            MasterProductAttributeValue(
                product_id=full_1.id,
                sku=full_1.sku,
                attribute_code="door_style",
                value="Shaker",
            ),
            MasterProductAttributeValue(
                product_id=full_2.id,
                sku=full_2.sku,
                attribute_code="door_style",
                value="Shaker",
            ),
        ]
    )
    catalog_intent_session.commit()

    preview = impute_collection_filter_attributes(
        catalog_intent_session,
        attributes=["door_style"],
        min_coverage_pct=100,
        min_observed=2,
        dry_run=True,
    )

    assert preview["raw_collection_count"] == 2
    assert preview["collection_count"] == 1
    assert preview["polluted_skipped_count"] == 1
    assert preview["would_update"] == 1
    assert [row["collection"] for row in preview["suggestions"]] == ["Plymouth Espresso Maple"]
