from backend.agents.base import AgentScope
from backend.agents.linker import build_link_scopes


def _sheet(number, page, level, assertions):
    return {"sheet_number": number, "page_number": page,
            "discipline": "Structural", "level": level,
            "assertions": assertions}


def _assertion(id_, ref=None, tag=None, level=None):
    return {"id": id_, "attribute": "stud_pack_size", "value": "(5) 2x6",
            "source_text": "(5) 2x6 STUD PACK",
            "location_key": {"detail_reference": ref, "tag": tag,
                             "level": level}}


def test_xref_scope_joins_same_detail_reference_across_levels():
    sheets = [
        _sheet("S101", 10, "foundation", [_assertion("a1", ref="A/S205")]),
        _sheet("S205", 20, "roof", [_assertion("a2", ref="A/S205")]),
        _sheet("S401", 30, "roof", [_assertion("a3", ref="A/S205")]),
    ]
    scopes = build_link_scopes(sheets)
    xref = [s for s in scopes if s.scope_id.startswith("xref:")]
    assert xref, "expected a cross-level detail-reference scope"
    ids = {a["id"] for s in xref for a in s.payload["assertions"]}
    assert ids == {"a1", "a2", "a3"}


def test_xref_scope_requires_two_distinct_sheets():
    sheets = [
        _sheet("S401", 30, "roof", [_assertion("a1", ref="A/S205"),
                                    _assertion("a2", ref="A/S205")]),
    ]
    scopes = build_link_scopes(sheets)
    assert not [s for s in scopes if s.scope_id.startswith("xref:")]


def test_xref_scope_joins_shared_member_tag():
    sheets = [
        _sheet("S102", 5, "roof", [_assertion("a1", tag="HSS16X4X5/8")]),
        _sheet("S401", 30, "unknown", [_assertion("a2", tag="HSS16X4X5/8")]),
    ]
    scopes = build_link_scopes(sheets)
    xref = [s for s in scopes if s.scope_id.startswith("xref:")]
    assert xref


def test_xref_scope_joins_single_letter_member_mark():
    # W-shapes (W12X26) are the most common steel marks and have one leading letter
    sheets = [
        _sheet("S102", 5, "roof", [_assertion("a1", tag="W12X26")]),
        _sheet("S401", 30, "unknown", [_assertion("a2", tag="W12X26")]),
    ]
    scopes = build_link_scopes(sheets)
    xref = [s for s in scopes if s.scope_id.startswith("xref:")]
    assert xref, "single-letter member marks (W12X26) must join xref scopes"


def test_xref_scope_rechecks_sheet_diversity_after_cap(monkeypatch):
    from backend import config
    monkeypatch.setattr(config, "AGENT_LINK_MAX_ASSERTIONS", 2)
    sheets = [
        _sheet("S401", 30, "roof", [_assertion("a1", ref="A/S205"),
                                    _assertion("a2", ref="A/S205")]),
        _sheet("S205", 20, "roof", [_assertion("a3", ref="A/S205")]),
    ]
    scopes = build_link_scopes(sheets)
    xref = [s for s in scopes if s.scope_id.startswith("xref:")]
    for scope in xref:
        sheets_in_scope = {a["sheet_number"] for a in scope.payload["assertions"]}
        assert len(sheets_in_scope) >= 2, \
            "capped xref scope must still span two sheets"
