from app.mapping import FieldKey
from app.matching import deduplicate_records, fill_missing_addresses, match_and_enrich, merge_fill
from app.models import CustomerRecord


def _rec(**values: object) -> CustomerRecord:
    return CustomerRecord(values=dict(values), row_index=values.get("_row", 1))  # type: ignore[arg-type]


def test_merge_does_not_overwrite_valid_values() -> None:
    target = _rec(**{FieldKey.ZIP: "24111", FieldKey.CITY: ""})
    source = _rec(**{FieldKey.ZIP: "24112", FieldKey.CITY: "Kiel"})
    merge_fill(target, source)
    assert target.get(FieldKey.ZIP) == "24111"
    assert target.get(FieldKey.CITY) == "Kiel"


def test_placeholder_is_replaced() -> None:
    target = _rec(**{FieldKey.STREET: "-", FieldKey.ZIP: "N/A"})
    source = _rec(**{FieldKey.STREET: "Russeer Weg 9", FieldKey.ZIP: "24111"})
    merge_fill(target, source)
    assert target.get(FieldKey.STREET) == "Russeer Weg 9"
    assert target.get(FieldKey.ZIP) == "24111"


def test_match_by_plate_and_vin() -> None:
    incoming = _rec(
        **{
            FieldKey.PLATE: "ki-sd221",
            FieldKey.VIN: "YV1XYZ123 ABC",
            FieldKey.STREET: "-",
        }
    )
    template = _rec(
        **{
            FieldKey.PLATE: "KI-SD 221",
            FieldKey.VIN: "YV1XYZ123ABC",
            FieldKey.STREET: "Russeer Weg 9",
        }
    )
    match_and_enrich([incoming], [template])
    assert incoming.match_status == "Kennzeichen + VIN"
    assert incoming.get(FieldKey.STREET) == "Russeer Weg 9"


def test_address_fallback_by_company() -> None:
    incomplete = _rec(
        **{
            FieldKey.COMPANY: "Condok GmbH",
            FieldKey.PLATE: "KI-CD 1",
            FieldKey.VIN: "YV1AAA",
        }
    )
    complete = _rec(
        **{
            FieldKey.COMPANY: "Condok GmbH",
            FieldKey.STREET: "Wellseedamm 12-14",
            FieldKey.ZIP: "24145",
            FieldKey.CITY: "Kiel",
            FieldKey.PLATE: "KI-CD 2",
            FieldKey.VIN: "YV1BBB",
        }
    )
    fill_missing_addresses([incomplete], [incomplete, complete])
    assert incomplete.get(FieldKey.STREET) == "Wellseedamm 12-14"
    assert incomplete.get(FieldKey.CITY) == "Kiel"


def test_duplicate_same_plate_different_vin_is_conflict() -> None:
    first = CustomerRecord(
        values={
            FieldKey.PLATE: "KI-XX 1",
            FieldKey.VIN: "YV1AAA",
            FieldKey.STREET: "A-Straße 1",
            FieldKey.ZIP: "24103",
            FieldKey.CITY: "Kiel",
        },
        row_index=2,
    )
    second = CustomerRecord(
        values={
            FieldKey.PLATE: "KI-XX 1",
            FieldKey.VIN: "YV1BBB",
            FieldKey.STREET: "B-Straße 2",
            FieldKey.ZIP: "24105",
            FieldKey.CITY: "Kiel",
        },
        row_index=3,
    )
    unique, conflicts = deduplicate_records([first, second])
    assert unique == []
    assert len(conflicts) == 1
    assert conflicts[0].conflict
