from app.services.enrichment.merge import INFERRED_CONFIDENCE, merge_attributes


def existing(key, value, source="option", confidence=1.0):
    return {"key": key, "raw_value": value, "value": value, "unit": None,
            "source": source, "confidence": confidence}


def test_a_gap_is_filled():
    merged, conflicts = merge_attributes([], {"color": "white"})
    assert len(merged) == 1
    assert merged[0]["key"] == "color"
    assert merged[0]["source"] == "inferred"
    assert merged[0]["confidence"] == INFERRED_CONFIDENCE
    assert conflicts == 0


def test_a_merchant_value_is_never_overwritten():
    # If a Shopify variant option said white, the model does not get to change it.
    merged, conflicts = merge_attributes([existing("color", "white")],
                                         {"color": "cream"})
    colors = [a for a in merged if a["key"] == "color"]
    assert len(colors) == 1
    assert colors[0]["value"] == "white"
    assert colors[0]["source"] == "option"


def test_a_disagreement_is_counted():
    # A high conflict rate means the prompt is wrong, which is worth knowing.
    _, conflicts = merge_attributes([existing("color", "white")],
                                    {"color": "cream"})
    assert conflicts == 1


def test_agreement_is_not_a_conflict():
    _, conflicts = merge_attributes([existing("color", "white")],
                                    {"color": "white"})
    assert conflicts == 0


def test_inferred_values_are_marked_and_weighted_below_structured():
    merged, _ = merge_attributes([], {"material": "cotton"})
    assert merged[0]["confidence"] < 1.0


def test_scalar_only_fields_are_not_stored_as_attributes():
    # is_accessory and price_tier get columns; duplicating them as attributes
    # would inflate the attribute count that quality_score depends on.
    merged, _ = merge_attributes([], {"is_accessory": True, "price_tier": "mid",
                                      "color": "white"})
    assert {a["key"] for a in merged} == {"color"}


def test_key_features_become_one_attribute_each():
    merged, _ = merge_attributes([], {"key_features": ["waterproof", "vegan"]})
    features = sorted(a["value"] for a in merged if a["key"] == "feature")
    assert features == ["vegan", "waterproof"]


def test_result_is_deterministically_ordered():
    # A later phase hashes this list to decide whether to re-embed; an unstable
    # order would re-embed the whole catalog on every run.
    a, _ = merge_attributes([], {"material": "cotton", "color": "white"})
    b, _ = merge_attributes([], {"color": "white", "material": "cotton"})
    assert a == b


def test_existing_attributes_are_not_reordered_away():
    merged, _ = merge_attributes(
        [existing("size", "m"), existing("color", "white")], {"material": "cotton"})
    assert {a["key"] for a in merged} == {"size", "color", "material"}
