"""Unit tests for the re-analysis impact diff — WS2 / task #201.

`_snapshot` + `_impact_diff` are pure functions (no DB) that produce the
before↔after summary surfaced to the chair after a merging re-analysis. They
must report per-party argument titles added/removed and the shift in the
priority ("recommendation balance") mix, and set ``changed`` correctly.
"""

from __future__ import annotations

from legal_mcp.tools.legal_arguments import _impact_diff, _snapshot


def _arg(party, title, priority="substantive"):
    return {"party": party, "argument_title": title, "priority": priority}


def test_no_change_is_flagged_false():
    args = [_arg("appellant", "זכות עמידה"), _arg("committee", "שיהוי")]
    snap = _snapshot(args)
    diff = _impact_diff(snap, snap)
    assert diff["changed"] is False
    assert diff["total_before"] == diff["total_after"] == 2
    # Every party entry reports changed=False.
    assert all(p["changed"] is False for p in diff["by_party"])


def test_added_argument_detected():
    before = _snapshot([_arg("appellant", "זכות עמידה")])
    after = _snapshot([_arg("appellant", "זכות עמידה"), _arg("appellant", "תחולת תמא 38")])
    diff = _impact_diff(before, after)
    assert diff["changed"] is True
    assert diff["total_before"] == 1
    assert diff["total_after"] == 2
    appellant = next(p for p in diff["by_party"] if p["party"] == "appellant")
    assert appellant["added_arguments"] == ["תחולת תמא 38"]
    assert appellant["removed_arguments"] == []
    assert appellant["party_he"] == "עוררים"


def test_removed_argument_detected():
    before = _snapshot([_arg("committee", "שיהוי"), _arg("committee", "סמכות")])
    after = _snapshot([_arg("committee", "שיהוי")])
    diff = _impact_diff(before, after)
    committee = next(p for p in diff["by_party"] if p["party"] == "committee")
    assert committee["removed_arguments"] == ["סמכות"]
    assert committee["count_before"] == 2
    assert committee["count_after"] == 1
    assert diff["changed"] is True


def test_priority_mix_shift_is_a_change():
    # Same title, but priority moved threshold -> substantive: the recommendation
    # balance shifted, so the chair must see a change even with identical titles.
    before = _snapshot([_arg("appellant", "סמכות", priority="threshold")])
    after = _snapshot([_arg("appellant", "סמכות", priority="substantive")])
    diff = _impact_diff(before, after)
    appellant = next(p for p in diff["by_party"] if p["party"] == "appellant")
    assert appellant["added_arguments"] == []
    assert appellant["removed_arguments"] == []
    assert appellant["priority_before"] == {"threshold": 1}
    assert appellant["priority_after"] == {"substantive": 1}
    assert appellant["changed"] is True
    assert diff["changed"] is True


def test_new_party_appears():
    before = _snapshot([_arg("appellant", "זכות עמידה")])
    after = _snapshot([_arg("appellant", "זכות עמידה"), _arg("respondent", "מענה")])
    diff = _impact_diff(before, after)
    parties = {p["party"] for p in diff["by_party"]}
    assert parties == {"appellant", "respondent"}
    respondent = next(p for p in diff["by_party"] if p["party"] == "respondent")
    assert respondent["count_before"] == 0
    assert respondent["count_after"] == 1
    assert respondent["added_arguments"] == ["מענה"]
