"""
Tests for comma-separated skip-range reference parsing in parse_reference().

Covers:
  1. Lectionary comma refs: Exodus, Deuteronomy, Wisdom, Sirach, Psalms
  2. Acts comma ref (28:16-20, 30-31)
  3. Backward compat: simple refs, ranges, Song of Solomon, chapter-only
  4. Single-chapter books with comma refs
  5. Invalid/edge cases
"""

from accordance_parser.canon import (
    parse_reference,
    ReferenceResult,
)

# =============================================================================
# 1. Lectionary comma-separated skip-ranges
# =============================================================================

def test_exodus_34_4_6_8_9():
    """'Exodus 34:4-6, 8-9' → book_osis=Exod, ch=34, verses 4,5,6,8,9"""
    r = parse_reference("Exodus 34:4-6, 8-9")
    assert r is not None
    assert r.book_osis == "Exod"
    assert r.chapter == 34
    assert r.verse == 4
    assert r.end_verse == 9
    assert r.verse_list == [4, 5, 6, 8, 9]


def test_deuteronomy_8_2_3_14_16():
    """'Deuteronomy 8:2-3, 14-16' → book_osis=Deut, ch=8"""
    r = parse_reference("Deuteronomy 8:2-3, 14-16")
    assert r is not None
    assert r.book_osis == "Deut"
    assert r.chapter == 8
    assert r.verse == 2
    assert r.end_verse == 16
    assert r.verse_list == [2, 3, 14, 15, 16]


def test_wisdom_2_12_17_20():
    """'Wisdom 2:12, 17-20' → book_osis=Wis, ch=2"""
    r = parse_reference("Wisdom 2:12, 17-20")
    assert r is not None
    assert r.book_osis == "Wis"
    assert r.chapter == 2
    assert r.verse == 12
    assert r.end_verse == 20
    assert r.verse_list == [12, 17, 18, 19, 20]


def test_sirach_3_2_6_12_14():
    """'Sirach 3:2-6, 12-14' → book_osis=Sir, ch=3"""
    r = parse_reference("Sirach 3:2-6, 12-14")
    assert r is not None
    assert r.book_osis == "Sir"
    assert r.chapter == 3
    assert r.verse == 2
    assert r.end_verse == 14
    assert r.verse_list == [2, 3, 4, 5, 6, 12, 13, 14]


def test_psalms_68_10_11_20_21():
    """'Psalms 68:10-11, 20-21' → book_osis=Ps, ch=68"""
    r = parse_reference("Psalms 68:10-11, 20-21")
    assert r is not None
    assert r.book_osis == "Ps"
    assert r.chapter == 68
    assert r.verse == 10
    assert r.end_verse == 21
    assert r.verse_list == [10, 11, 20, 21]


# =============================================================================
# 2. Acts comma ref
# =============================================================================

def test_acts_28_16_20_30_31():
    """'Acts 28:16-20, 30-31' → book_osis=Acts, ch=28"""
    r = parse_reference("Acts 28:16-20, 30-31")
    assert r is not None
    assert r.book_osis == "Acts"
    assert r.chapter == 28
    assert r.verse == 16
    assert r.end_verse == 31
    assert r.verse_list == [16, 17, 18, 19, 20, 30, 31]


# =============================================================================
# 3. Backward compatibility: simple refs
# =============================================================================

def test_simple_ref_still_works():
    """'Genesis 1:1' → still parses, verse_list=None"""
    r = parse_reference("Genesis 1:1")
    assert r is not None
    assert r.book_osis == "Gen"
    assert r.chapter == 1
    assert r.verse == 1
    assert r.end_verse is None
    assert r.verse_list is None  # Backward compat: not set for simple refs


def test_range_ref_still_works():
    """'John 3:16-18' → still parses, verse_list=None"""
    r = parse_reference("John 3:16-18")
    assert r is not None
    assert r.book_osis == "John"
    assert r.chapter == 3
    assert r.verse == 16
    assert r.end_verse == 18
    assert r.verse_list is None


def test_song_of_solomon_still_works():
    """'Song of Solomon 1:1' → still parses (no false comma-split)"""
    r = parse_reference("Song of Solomon 1:1")
    assert r is not None
    assert r.book_osis == "Song"
    assert r.chapter == 1
    assert r.verse == 1
    assert r.end_verse is None
    assert r.verse_list is None


def test_chapter_only_still_works():
    """'Psalm 119' → chapter-only, still parses"""
    r = parse_reference("Psalm 119")
    assert r is not None
    assert r.book_osis == "Ps"
    assert r.chapter == 119
    assert r.verse is None
    assert r.end_verse is None
    assert r.verse_list is None


def test_numbered_book_still_works():
    """'1 Samuel 3:4' → numbered book, still parses"""
    r = parse_reference("1 Samuel 3:4")
    assert r is not None
    assert r.book_osis == "1Sam"
    assert r.chapter == 3
    assert r.verse == 4
    assert r.end_verse is None
    assert r.verse_list is None


def test_single_chapter_no_colon_still_works():
    """'Jude 4' → single-chapter book, no colon"""
    r = parse_reference("Jude 4")
    assert r is not None
    assert r.book_osis == "Jude"
    assert r.chapter == 1
    assert r.verse == 4
    assert r.end_verse is None
    assert r.verse_list is None


def test_single_chapter_with_colon_still_works():
    """'Jude 1:4' → single-chapter book, explicit colon"""
    r = parse_reference("Jude 1:4")
    assert r is not None
    assert r.book_osis == "Jude"
    assert r.chapter == 1
    assert r.verse == 4
    assert r.end_verse is None
    assert r.verse_list is None


def test_en_dash_range_still_works():
    """En-dash (U+2013) ranges still parse"""
    r = parse_reference("Genesis 1:1\u20133")
    assert r is not None
    assert r.book_osis == "Gen"
    assert r.chapter == 1
    assert r.verse == 1
    assert r.end_verse == 3


def test_em_dash_range_still_works():
    """Em-dash (U+2014) ranges still parse"""
    r = parse_reference("Genesis 1:1\u20143")
    assert r is not None
    assert r.book_osis == "Gen"
    assert r.chapter == 1
    assert r.verse == 1
    assert r.end_verse == 3


def test_abbreviated_book_still_works():
    """Abbreviated book names still work"""
    r = parse_reference("1cor 13:4")
    assert r is not None
    assert r.book_osis == "1Cor"
    assert r.chapter == 13
    assert r.verse == 4


def test_deuterocanonical_still_works():
    """Deuterocanonical simple refs still work"""
    r = parse_reference("Tobit 1:1")
    assert r is not None
    assert r.book_osis == "Tob"
    assert r.chapter == 1
    assert r.verse == 1


# =============================================================================
# 4. Single-chapter books with comma refs
# =============================================================================

def test_jude_comma_range():
    """'Jude 4-5, 7-8' → single-chapter book, no colon, comma ref"""
    r = parse_reference("Jude 4-5, 7-8")
    assert r is not None
    assert r.book_osis == "Jude"
    assert r.chapter == 1
    assert r.verse == 4
    assert r.end_verse == 8
    assert r.verse_list == [4, 5, 7, 8]


def test_jude_explicit_chapter_comma_range():
    """'Jude 1:4-5, 7-8' → explicit colon, comma ref"""
    r = parse_reference("Jude 1:4-5, 7-8")
    assert r is not None
    assert r.book_osis == "Jude"
    assert r.chapter == 1
    assert r.verse == 4
    assert r.end_verse == 8
    assert r.verse_list == [4, 5, 7, 8]


def test_obadiah_comma_range():
    """'Obadiah 15-17, 20-21' → single-chapter book"""
    r = parse_reference("Obadiah 15-17, 20-21")
    assert r is not None
    assert r.book_osis == "Obad"
    assert r.chapter == 1
    assert r.verse == 15
    assert r.end_verse == 21
    assert r.verse_list == [15, 16, 17, 20, 21]


# =============================================================================
# 5. Edge cases: invalid / semicolons / no-book
# =============================================================================

def test_invalid_returns_none():
    """Invalid refs still return None"""
    assert parse_reference("") is None
    assert parse_reference("not a reference") is None
    assert parse_reference("nonexistentbook 1:1") is None


def test_semicolon_different_chapters():
    """Semicolons where chapter changes: return first segment only."""
    # "Acts 22:30; 23:6-11" — ch22 v30, ch23 v6-11 differ → first segment only
    result = parse_reference("Acts 22:30; 23:6-11")
    assert result is not None
    assert result.book_osis == "Acts"
    assert result.chapter == 22
    assert result.verse == 30
    assert result.end_verse is None
    assert result.verse_list is None


def test_comma_inside_book_name():
    """'Song of Solomon' contains no comma — won't trigger comma-split.
    But test that a contrived case with comma in book name is handled."""
    # There are no book names with commas, so this is purely defensive.
    # A ref like "Foo, Bar 1:1" would split on comma, but "Foo, Bar"
    # wouldn't resolve to a book so it would return None gracefully.
    result = parse_reference("Foo, Bar 1:1")
    # Either None (if 'Foo' doesn't resolve) or something if by chance
    # 'Foo' matches. We just assert no crash.
    assert result is None or isinstance(result, ReferenceResult)
