"""Tests for condensr.parser module."""

import pytest

from condensr.parser import (
    Chapter,
    detect_chapters,
    extract_chapter_text,
    extract_full_text,
    get_book_title,
)


class TestDetectChaptersFromTOC:
    def test_returns_chapters_from_toc(self, pdf_with_toc):
        chapters = detect_chapters(pdf_with_toc)
        assert len(chapters) == 3
        assert chapters[0].title == "Introduction"
        assert chapters[1].title == "Methods"
        assert chapters[2].title == "Conclusion"

    def test_chapter_page_boundaries(self, pdf_with_toc):
        chapters = detect_chapters(pdf_with_toc)
        # Introduction: pages 0-1 (TOC says page 1, next starts page 3 → 0-indexed: 0 to 1)
        assert chapters[0].start_page == 0
        assert chapters[0].end_page == 1
        # Methods: pages 2-3
        assert chapters[1].start_page == 2
        assert chapters[1].end_page == 3
        # Conclusion: page 4 (last page)
        assert chapters[2].start_page == 4
        assert chapters[2].end_page == 4


class TestDetectChaptersFromHeadings:
    def test_detects_large_font_headings(self, pdf_with_headings):
        chapters = detect_chapters(pdf_with_headings)
        assert len(chapters) >= 2
        titles = [c.title for c in chapters]
        assert any("Beginning" in t for t in titles)
        assert any("Middle" in t for t in titles)


class TestDetectChaptersEmpty:
    def test_returns_empty_list_when_no_chapters(self, pdf_no_chapters):
        chapters = detect_chapters(pdf_no_chapters)
        assert chapters == []


class TestValidation:
    def test_encrypted_pdf_raises_error(self, pdf_encrypted):
        with pytest.raises(ValueError, match="password-protected"):
            detect_chapters(pdf_encrypted)

    def test_no_text_pdf_raises_error(self, pdf_no_text):
        with pytest.raises(ValueError, match="No text content found"):
            detect_chapters(pdf_no_text)


class TestExtractText:
    def test_extract_chapter_text(self, pdf_with_toc):
        chapters = detect_chapters(pdf_with_toc)
        text = extract_chapter_text(pdf_with_toc, chapters[0])
        assert "introduction" in text.lower()
        assert len(text) > 50

    def test_extract_full_text(self, pdf_with_toc):
        text = extract_full_text(pdf_with_toc)
        assert "introduction" in text.lower()
        assert "methods" in text.lower()
        assert "conclusion" in text.lower()


class TestChapterFiltering:
    """Tests for chapter list filtering (level restriction + blocklist)."""

    def test_excludes_level2_subchapters(self, pdf_with_toc_and_subchapters):
        chapters = detect_chapters(pdf_with_toc_and_subchapters)
        titles = [c.title for c in chapters]
        assert titles == ["Chapter One", "Chapter Two", "Chapter Three"]

    def test_excludes_meta_chapters(self, pdf_with_meta_chapters):
        chapters = detect_chapters(pdf_with_meta_chapters)
        titles = [c.title for c in chapters]
        assert titles == ["Chapter One", "Chapter Two"]

    def test_excludes_french_meta_chapters(self, pdf_with_meta_chapters_fr):
        chapters = detect_chapters(pdf_with_meta_chapters_fr)
        titles = [c.title for c in chapters]
        assert titles == ["Chapitre Premier", "Chapitre Deux"]

    def test_preserves_superstring_titles(self, pdf_with_superstring_titles):
        chapters = detect_chapters(pdf_with_superstring_titles)
        titles = [c.title for c in chapters]
        assert titles == [
            "Notes on the Revolution",
            "A Dedication to Craft",
            "The Copyright Wars",
        ]

    def test_page_boundaries_after_filtering(self, pdf_with_meta_chapters):
        chapters = detect_chapters(pdf_with_meta_chapters)
        # TOC: TITLE PAGE(p0), COPYRIGHT(p1), DEDICATION(p2), CONTENTS(p3),
        #       Chapter One(p4), Chapter Two(p5), ABOUT THE AUTHORS(p6)
        # Chapter One: starts at p4, next entry is Chapter Two at p5 → end = p4
        assert chapters[0].start_page == 4
        assert chapters[0].end_page == 4
        # Chapter Two: starts at p5, next entry is ABOUT THE AUTHORS at p6 → end = p5
        # (ABOUT THE AUTHORS pages are excluded, not absorbed)
        assert chapters[1].start_page == 5
        assert chapters[1].end_page == 5

    def test_toc_level_2_includes_subchapters(self, pdf_with_toc_and_subchapters):
        chapters = detect_chapters(pdf_with_toc_and_subchapters, toc_level=2)
        titles = [c.title for c in chapters]
        assert titles == [
            "Chapter One", "Section 1.1", "Section 1.2",
            "Chapter Two", "Section 2.1",
            "Chapter Three",
        ]

    def test_toc_level_2_still_filters_blocklist(self, pdf_with_meta_chapters):
        chapters = detect_chapters(pdf_with_meta_chapters, toc_level=2)
        titles = [c.title for c in chapters]
        assert titles == ["Chapter One", "Chapter Two"]

    def test_toc_level_default_is_1(self, pdf_with_toc_and_subchapters):
        chapters = detect_chapters(pdf_with_toc_and_subchapters)
        titles = [c.title for c in chapters]
        assert titles == ["Chapter One", "Chapter Two", "Chapter Three"]


class TestGetBookTitle:
    def test_returns_metadata_title(self, pdf_with_metadata_title):
        title = get_book_title(pdf_with_metadata_title)
        assert title == "The Great Book"

    def test_falls_back_to_filename(self, pdf_no_chapters):
        title = get_book_title(pdf_no_chapters)
        assert title == "Plain Book"
