from mints_prep.naming.evidence_number import check_evidence_sequence, match_evidence_number


def test_simple_match(config):
    m = match_evidence_number("甲001 売買契約書原本.pdf", config.evidence_number)
    assert m is not None
    assert m.symbol == "甲"
    assert m.subletter == ""
    assert m.number == "001"
    assert m.branch_from is None
    assert m.title == "売買契約書原本"
    assert m.evidence_number_label == "甲001"


def test_defendant_subletter_match(config):
    # 準備の手引29頁の原文どおり、正式な表記は半角英字（例：「乙A001 領収書」）
    m = match_evidence_number("乙A001 陳述書.pdf", config.evidence_number)
    assert m is not None
    assert m.symbol == "乙"
    assert m.subletter == "A"
    assert m.number == "001"


def test_defendant_subletter_match_accepts_fullwidth_too(config):
    # 正式表記は半角だが、全角で入力されたファイルも証拠番号処理の対象外に
    # 誤判定しないよう、判定自体は全角も寛容に受理する
    m = match_evidence_number("乙Ａ001 陳述書.pdf", config.evidence_number)
    assert m is not None
    assert m.subletter == "Ａ"


def test_branch_range_hyphen(config):
    m = match_evidence_number("甲001-1~20 領収書.pdf", config.evidence_number)
    assert m is not None
    assert m.branch_from == "1"
    assert m.branch_to == "20"
    assert m.evidence_number_label == "甲001-1~20"


def test_branch_range_underscore_fullwidth_tilde(config):
    # FAQ表記「甲001_1〜3」（アンダースコア＋全角チルダ）も受理する
    m = match_evidence_number("甲001_1〜3.pdf", config.evidence_number)
    assert m is not None
    assert m.branch_from == "1"
    assert m.branch_to == "3"


def test_single_branch_no_range(config):
    m = match_evidence_number("甲001-2.pdf", config.evidence_number)
    assert m is not None
    assert m.branch_from == "2"
    assert m.branch_to is None
    assert m.evidence_number_label == "甲001-2"


def test_no_match_for_non_evidence_filename(config):
    m = match_evidence_number("準備書面（案）.docx", config.evidence_number)
    assert m is None


def test_no_match_when_number_wrong_digit_count(config):
    # 2桁は半角3桁の要件に合致しない
    m = match_evidence_number("甲01 契約書.pdf", config.evidence_number)
    assert m is None


def test_sequence_check_detects_gap(config):
    filenames = ["甲001 契約書.pdf", "甲003 領収書.pdf"]
    findings = check_evidence_sequence(filenames, config.evidence_number)
    assert len(findings) == 1
    assert findings[0].symbol_key == "甲"
    assert findings[0].missing_numbers == (2,)
    assert findings[0].duplicate_numbers == ()


def test_sequence_check_no_gap_when_consecutive(config):
    filenames = ["甲001 契約書.pdf", "甲002 領収書.pdf", "甲003 陳述書.pdf"]
    findings = check_evidence_sequence(filenames, config.evidence_number)
    assert findings == ()


def test_sequence_check_branch_files_count_as_one_number(config):
    # 甲001-1〜3は親番号（甲001）単位で1つと数えるため、甲002が欠番となる
    filenames = ["甲001-1 領収書1.pdf", "甲001-2 領収書2.pdf", "甲001-3 領収書3.pdf", "甲003 陳述書.pdf"]
    findings = check_evidence_sequence(filenames, config.evidence_number)
    assert len(findings) == 1
    assert findings[0].missing_numbers == (2,)
    assert findings[0].duplicate_numbers == ()


def test_sequence_check_detects_duplicate_same_number_no_branch(config):
    filenames = ["甲001 契約書.pdf", "甲001 別の契約書.pdf"]
    findings = check_evidence_sequence(filenames, config.evidence_number)
    assert len(findings) == 1
    assert findings[0].duplicate_numbers == (1,)
    assert findings[0].missing_numbers == ()


def test_sequence_check_branch_group_not_flagged_as_duplicate(config):
    # 枝番違いは正当な結合対象であり、重複ではない
    filenames = ["甲001-1 領収書1.pdf", "甲001-2 領収書2.pdf"]
    findings = check_evidence_sequence(filenames, config.evidence_number)
    assert findings == ()


def test_sequence_check_independent_series_per_symbol(config):
    # 符号（甲・乙）ごとに独立した連番系列として扱うため、甲002の欠番が乙側に影響しない
    filenames = ["甲001 契約書.pdf", "甲003 領収書.pdf", "乙A001 陳述書.pdf", "乙A002 陳述書2.pdf"]
    findings = check_evidence_sequence(filenames, config.evidence_number)
    assert len(findings) == 1
    assert findings[0].symbol_key == "甲"


def test_sequence_check_ignores_non_matching_filenames(config):
    filenames = ["甲001 契約書.pdf", "準備書面（案）.docx"]
    findings = check_evidence_sequence(filenames, config.evidence_number)
    assert findings == ()
