from unittest.mock import patch

from backend.agents.base import AgentScope, AgentUsage

from backend.agents.verifier import (
    EvidenceVerifierAgent, apply_verdicts, select_findings,
)


def _finding(sev="critical", issue_id="i1", sheets=("S401",), cluster_key=None):
    f = {"issue_id": issue_id, "severity": sev, "confidence": "high",
         "source_stage": "constructability", "sheets": list(sheets),
         "description": "HSS16x4 on (2) 2x6 STUD PACK is unbuildable",
         "evidence": [{"sheet": "S401", "source_text": "(2) 2x6 STUD PACK",
                       "asserted_value": "3-inch width"}]}
    if cluster_key:
        f["cluster_key"] = cluster_key
    return f


def test_select_findings_by_severity_and_dispute():
    findings = [_finding("critical"), _finding("low", "i2"),
                _finding("medium", "i3", cluster_key="c9")]
    clusters = [{"key": "c9", "disputed_attributes": [{"attribute": "a"}]}]
    selected = select_findings(findings, clusters, max_checks=20,
                               severities={"critical", "high"})
    assert [f["issue_id"] for f in selected] == ["i1", "i3"]


def test_select_findings_respects_cap():
    findings = [_finding("critical", f"i{n}") for n in range(30)]
    selected = select_findings(findings, [], max_checks=5,
                               severities={"critical"})
    assert len(selected) == 5


def test_run_attaches_verdicts_and_marks_refuted():
    agent = EvidenceVerifierAgent(usage=AgentUsage())
    scope = AgentScope(scope_id="verify:0", payload={
        "finding_index": 0,
        "finding": _finding(),
        "images_b64": ["QUJD"],
    })
    verdicts = {"verdicts": [
        {"sheet": "S401", "source_text": "(2) 2x6 STUD PACK",
         "verdict": "corrected", "actual_text": "(5) 2x6 STUD PACK",
         "notes": "callout reads (5)"},
    ]}
    with patch("backend.agents.verifier.call_json", return_value=verdicts):
        result = agent.run(scope)
    assert not result.error
    artifact = result.artifacts[0]
    assert artifact["finding_index"] == 0
    assert artifact["status"] == "refuted"      # no evidence confirmed
    assert artifact["verdicts"][0]["actual_text"] == "(5) 2x6 STUD PACK"


def test_apply_verdicts_annotates_and_suppresses():
    from backend.agents.base import AgentResult
    findings = [_finding("critical", "i1"), _finding("high", "i2")]
    results = [AgentResult(scope_id="verify:0", artifacts=[
        {"finding_index": 0, "status": "refuted", "verdicts": []},
        {"finding_index": 1, "status": "confirmed", "verdicts": []},
    ])]
    suppressed = apply_verdicts(findings, results)
    assert suppressed == [findings[0]]
    assert findings[0]["verification"]["status"] == "refuted"
    assert findings[1]["verification"]["status"] == "confirmed"
