"""
Unit tests for KJV Study API endpoints

Fixtures are imported from conftest.py
"""
import pytest


class TestAPIHealth:
    """Tests for health check endpoints"""

    def test_api_health(self, client):
        """Test /api/health endpoint"""
        response = client.get("/api/health")
        assert response.status_code == 200
        data = response.json()
        assert data["status"] == "healthy"
        assert "service" in data
        assert "version" in data


class TestAPIIndex:
    """Tests for API index endpoint"""

    def test_api_index(self, client):
        """Test /api/ endpoint returns index"""
        response = client.get("/api/")
        assert response.status_code == 200
        data = response.json()
        assert data["name"] == "KJV Study API"
        assert "version" in data
        assert "documentation" in data
        assert "endpoints" in data


class TestVerseEndpoints:
    """Tests for verse-related endpoints"""

    def test_get_single_verse(self, client):
        """Test /api/verse/{book}/{chapter}/{verse}"""
        response = client.get("/api/verse/John/3/16")
        assert response.status_code == 200
        data = response.json()
        assert data["book"] == "John"
        assert data["chapter"] == 3
        assert data["verse"] == 16
        assert "text" in data
        assert "God so loved the world" in data["text"]
        assert "red_letter" in data
        assert data["red_letter"] == "full"  # Jesus speaks the entire verse

    def test_get_verse_with_abbreviation(self, client):
        """Test verse endpoint with book abbreviation"""
        response = client.get("/api/verse/Gen/1/1")
        assert response.status_code == 200
        data = response.json()
        assert data["book"] == "Genesis"
        assert data["chapter"] == 1
        assert data["verse"] == 1
        assert "In the beginning" in data["text"]
        assert "red_letter" in data
        assert data["red_letter"] is None  # Jesus doesn't speak in Genesis

    def test_get_nonexistent_verse(self, client):
        """Test verse endpoint with invalid verse"""
        response = client.get("/api/verse/John/3/999")
        assert response.status_code == 404

    def test_get_verse_range(self, client):
        """Test /api/verse-range/{book}/{chapter}/{start}/{end}"""
        response = client.get("/api/verse-range/Psalms/23/1/6")
        assert response.status_code == 200
        data = response.json()
        assert data["book"] == "Psalms"
        assert data["chapter"] == 23
        assert data["start"] == 1
        assert data["end"] == 6
        assert "verses" in data
        assert len(data["verses"]) == 6
        # Check that each verse has red_letter field
        for verse in data["verses"]:
            assert "red_letter" in verse
            assert verse["red_letter"] is None  # Psalms don't have Jesus speaking

    def test_verse_of_the_day(self, client):
        """Test /api/verse-of-the-day"""
        response = client.get("/api/verse-of-the-day")
        assert response.status_code == 200
        data = response.json()
        assert "text" in data
        assert "reference" in data
        assert "book" in data
        assert "chapter" in data
        assert "verse" in data
        assert "red_letter" in data

    def test_red_letter_full_verse(self, client):
        """Test verse where Jesus speaks entire verse"""
        response = client.get("/api/verse/Matthew/5/3")
        assert response.status_code == 200
        data = response.json()
        assert data["red_letter"] == "full"

    def test_red_letter_partial_verse(self, client):
        """Test verse where Jesus speaks part of it"""
        response = client.get("/api/verse/Matthew/4/4")
        assert response.status_code == 200
        data = response.json()
        assert data["red_letter"] is not None
        assert data["red_letter"] != "full"
        assert isinstance(data["red_letter"], str)
        assert len(data["red_letter"]) > 0

    def test_red_letter_no_words(self, client):
        """Test verse where Jesus doesn't speak"""
        response = client.get("/api/verse/Romans/3/23")
        assert response.status_code == 200
        data = response.json()
        assert data["red_letter"] is None

    def test_red_letter_verse_range_with_christ_words(self, client):
        """Test verse range that includes words of Christ"""
        response = client.get("/api/verse-range/Matthew/5/3/5")
        assert response.status_code == 200
        data = response.json()
        # All three verses in the Sermon on the Mount are full red letter
        for verse in data["verses"]:
            assert "red_letter" in verse
            assert verse["red_letter"] == "full"


class TestBookEndpoints:
    """Tests for book-related endpoints"""

    def test_get_all_books(self, client):
        """Test /api/books"""
        response = client.get("/api/books")
        assert response.status_code == 200
        data = response.json()
        assert "total_books" in data
        assert data["total_books"] == 66
        assert "old_testament" in data
        assert "new_testament" in data

    def test_get_book_details(self, client):
        """Test /api/books/{book}"""
        response = client.get("/api/books/Genesis")
        assert response.status_code == 200
        data = response.json()
        assert data["name"] == "Genesis"
        assert data["total_chapters"] == 50
        assert "chapters" in data

    def test_get_chapter(self, client):
        """Test /api/books/{book}/chapters/{chapter}"""
        response = client.get("/api/books/John/chapters/1")
        assert response.status_code == 200
        data = response.json()
        assert data["book"] == "John"
        assert data["chapter"] == 1
        assert "verses" in data
        assert data["total_verses"] > 0

    def test_get_book_text(self, client):
        """Test /api/books/{book}/text"""
        response = client.get("/api/books/Philemon/text")
        assert response.status_code == 200
        data = response.json()
        assert data["book"] == "Philemon"
        assert data["total_chapters"] == 1
        assert data["total_verses"] == 25
        assert "chapters" in data

    def test_get_nonexistent_book(self, client):
        """Test book endpoint with invalid book"""
        response = client.get("/api/books/FakeBook")
        assert response.status_code == 404


class TestBibleEndpoint:
    """Tests for complete Bible endpoint"""

    def test_get_entire_bible(self, client):
        """Test /api/bible"""
        response = client.get("/api/bible")
        assert response.status_code == 200
        data = response.json()
        assert data["total_books"] == 66
        assert data["total_verses"] == 31102
        assert "books" in data
        assert len(data["books"]) == 66


class TestSearchEndpoint:
    """Tests for search endpoint"""

    def test_search_with_query(self, client):
        """Test /api/search with query"""
        response = client.get("/api/search?q=love")
        assert response.status_code == 200
        data = response.json()
        assert "results" in data
        assert "total" in data

    def test_search_with_limit(self, client):
        """Test /api/search with limit"""
        response = client.get("/api/search?q=faith&limit=5")
        assert response.status_code == 200
        data = response.json()
        assert "results" in data
        assert len(data["results"]) <= 5

    def test_search_empty_query(self, client):
        """Test /api/search with empty query"""
        response = client.get("/api/search?q=")
        assert response.status_code == 200
        data = response.json()
        assert data["total"] == 0


class TestUniversalSearchEndpoint:
    """Tests for universal search endpoint"""

    def test_universal_search_basic(self, client):
        """Test /api/universal-search with basic query"""
        response = client.get("/api/universal-search?q=love")
        assert response.status_code == 200
        data = response.json()
        assert "query" in data
        assert "results" in data
        assert data["query"] == "love"

    def test_universal_search_finds_books(self, client):
        """Test universal search finds books"""
        response = client.get("/api/universal-search?q=genesis")
        assert response.status_code == 200
        data = response.json()
        assert "books" in data["results"]
        assert any(b["name"] == "Genesis" for b in data["results"]["books"])

    def test_universal_search_finds_topics(self, client):
        """Test universal search finds topics"""
        response = client.get("/api/universal-search?q=faith")
        assert response.status_code == 200
        data = response.json()
        # Topics may or may not be present depending on data
        assert "results" in data

    def test_universal_search_finds_verses(self, client):
        """Test universal search finds verses"""
        response = client.get("/api/universal-search?q=beginning")
        assert response.status_code == 200
        data = response.json()
        assert "verses" in data["results"]
        assert len(data["results"]["verses"]) > 0

    def test_universal_search_with_limit(self, client):
        """Test universal search respects limit"""
        response = client.get("/api/universal-search?q=god&limit=3")
        assert response.status_code == 200
        data = response.json()
        # Check that each category respects the limit
        for category in data["results"].values():
            assert len(category) <= 3

    def test_universal_search_short_query(self, client):
        """Test universal search with very short query"""
        response = client.get("/api/universal-search?q=a")
        assert response.status_code == 200
        data = response.json()
        # Short queries return empty results
        assert data["results"] == {}

    def test_universal_search_book_synonyms(self, client):
        """Test universal search handles book synonyms"""
        response = client.get("/api/universal-search?q=revelations")
        assert response.status_code == 200
        data = response.json()
        # Should find Revelation book
        if "books" in data["results"]:
            assert any(b["name"] == "Revelation" for b in data["results"]["books"])

    def test_universal_search_finds_resources(self, client):
        """Test universal search finds resources"""
        response = client.get("/api/universal-search?q=trinity")
        assert response.status_code == 200
        data = response.json()
        assert "resources" in data["results"]
        assert len(data["results"]["resources"]) > 0

    def test_universal_search_theological_synonyms(self, client):
        """Test universal search handles theological synonyms"""
        response = client.get("/api/universal-search?q=holy%20spirit")
        assert response.status_code == 200
        data = response.json()
        # Should find Pneumatology via synonym
        if "resources" in data["results"]:
            names = [r["name"] for r in data["results"]["resources"]]
            assert "Pneumatology" in names

    def test_universal_search_finds_study_guides(self, client):
        """Test universal search finds study guides"""
        response = client.get("/api/universal-search?q=prayer")
        assert response.status_code == 200
        data = response.json()
        if "resources" in data["results"]:
            # Should find prayer-related study guides
            urls = [r["url"] for r in data["results"]["resources"]]
            assert any("study-guides" in url or "prayer" in url for url in urls)


class TestInterlinearEndpoint:
    """Tests for interlinear data endpoint"""

    def test_get_interlinear_new_testament(self, client):
        """Test /api/interlinear for NT verse"""
        response = client.get("/api/interlinear/John/1/1")
        assert response.status_code == 200
        data = response.json()
        assert data["book"] == "John"
        assert data["chapter"] == 1
        assert data["verse"] == 1
        assert "interlinear_available" in data

    def test_get_interlinear_nonexistent_verse(self, client):
        """Test interlinear with invalid verse"""
        response = client.get("/api/interlinear/John/1/999")
        assert response.status_code == 404


class TestCrossReferencesEndpoint:
    """Tests for cross-references endpoint"""

    def test_get_cross_references(self, client):
        """Test /api/cross-references/{book}/{chapter}/{verse}"""
        response = client.get("/api/cross-references/John/3/16")
        assert response.status_code == 200
        data = response.json()
        assert data["book"] == "John"
        assert data["chapter"] == 3
        assert data["verse"] == 16
        assert "cross_references" in data


class TestTopicsEndpoints:
    """Tests for topics endpoints"""

    def test_get_all_topics(self, client):
        """Test /api/topics"""
        response = client.get("/api/topics")
        assert response.status_code == 200
        data = response.json()
        assert "total_topics" in data
        assert "topics" in data

    def test_get_specific_topic(self, client):
        """Test /api/topics/{topic_name}"""
        response = client.get("/api/topics/faith")
        # Topic might not exist, accept both 200 and 404
        assert response.status_code in [200, 404]
        if response.status_code == 200:
            data = response.json()
            assert "name" in data


class TestReadingPlansEndpoints:
    """Tests for reading plans endpoints"""

    def test_get_all_reading_plans(self, client):
        """Test /api/reading-plans"""
        response = client.get("/api/reading-plans")
        assert response.status_code == 200
        data = response.json()
        assert "total_plans" in data
        assert "plans" in data
        assert data["total_plans"] > 0

    def test_get_specific_reading_plan(self, client):
        """Test /api/reading-plans/{plan_id}"""
        response = client.get("/api/reading-plans/chronological")
        assert response.status_code == 200
        data = response.json()
        assert "name" in data
        assert "description" in data

    def test_get_nonexistent_reading_plan(self, client):
        """Test reading plan endpoint with invalid plan"""
        response = client.get("/api/reading-plans/fake-plan")
        assert response.status_code == 404


class TestBookNameNormalization:
    """Tests for book name normalization"""

    def test_abbreviations(self, client):
        """Test various book abbreviations"""
        # Test Genesis abbreviations
        for abbrev in ["Gen", "Ge"]:
            response = client.get(f"/api/verse/{abbrev}/1/1")
            # Some abbreviations might not work, accept 200, 404, or 500
            if response.status_code == 200:
                data = response.json()
                assert data["book"] == "Genesis"

        # Test Matthew abbreviations - Matt should work
        response = client.get("/api/verse/Matt/1/1")
        if response.status_code == 200:
            data = response.json()
            assert data["book"] == "Matthew"


if __name__ == "__main__":
    pytest.main([__file__, "-v"])


class TestResourcesEndpoints:
    """Tests for resources-related endpoints"""

    def test_list_all_resources(self, client):
        """Test /api/resources endpoint"""
        response = client.get("/api/resources")
        assert response.status_code == 200
        data = response.json()
        assert "total_categories" in data
        assert "categories" in data
        assert data["total_categories"] == 39
        assert len(data["categories"]) == 39
        
        # Check structure of first category
        first_cat = data["categories"][0]
        assert "name" in first_cat
        assert "title" in first_cat
        assert "item_count" in first_cat
        assert "url" in first_cat

    def test_get_resource_category(self, client):
        """Test /api/resources/{category} endpoint"""
        response = client.get("/api/resources/angels")
        assert response.status_code == 200
        data = response.json()
        assert data["category"] == "angels"
        assert "title" in data
        assert "total_items" in data
        assert "items" in data
        assert data["total_items"] > 0
        assert len(data["items"]) == data["total_items"]
        
        # Check structure of first item
        first_item = data["items"][0]
        assert "name" in first_item
        assert "slug" in first_item
        assert "description" in first_item
        assert "verse_count" in first_item
        assert "url" in first_item

    def test_get_resource_category_biblical_locations(self, client):
        """Test nested resource category (biblical_locations)"""
        response = client.get("/api/resources/biblical_locations")
        assert response.status_code == 200
        data = response.json()
        assert data["category"] == "biblical_locations"
        assert data["total_items"] > 0
        # Should include items from both OT and NT locations
        assert any("Garden of Eden" in item["name"] for item in data["items"])

    def test_get_resource_item(self, client):
        """Test /api/resources/{category}/{slug} endpoint"""
        response = client.get("/api/resources/biblical_locations/garden-of-eden")
        assert response.status_code == 200
        data = response.json()
        assert data["name"] == "Garden of Eden"
        assert data["slug"] == "garden-of-eden"
        assert data["category"] == "biblical_locations"
        assert "description" in data
        assert "verses" in data
        assert len(data["verses"]) > 0
        
        # Check verse structure
        first_verse = data["verses"][0]
        assert "reference" in first_verse
        assert "text" in first_verse
        assert "Genesis" in first_verse["reference"]

    def test_get_resource_item_from_different_categories(self, client):
        """Test getting items from various categories"""
        test_cases = [
            ("angels", "michael-the-archangel"),
            ("prophets", "isaiah"),
            ("parables", "the-sower"),
        ]

        for category, slug in test_cases:
            response = client.get(f"/api/resources/{category}/{slug}")
            assert response.status_code == 200
            data = response.json()
            assert data["category"] == category
            assert data["slug"] == slug
            assert "verses" in data

    def test_get_nonexistent_resource_category(self, client):
        """Test /api/resources/{category} with invalid category"""
        response = client.get("/api/resources/nonexistent_category")
        assert response.status_code == 404

    def test_get_nonexistent_resource_item(self, client):
        """Test /api/resources/{category}/{slug} with invalid slug"""
        response = client.get("/api/resources/angels/nonexistent-angel")
        assert response.status_code == 404

    def test_resource_category_pdf(self, client):
        """Test /api/resources/{category}/pdf endpoint"""
        # Note: This route may have ordering issues with FastAPI path matching
        # Testing with a simple category
        response = client.get("/api/resources/angels/pdf")
        # May match as /resources/{category} with slug="pdf" due to route order
        # This is a known limitation - PDF routes should be defined before general routes
        assert response.status_code in [200, 404, 503]
        if response.status_code == 200:
            assert response.headers["content-type"] == "application/pdf"
            assert "attachment" in response.headers.get("content-disposition", "")

    def test_resource_item_pdf(self, client):
        """Test /api/resources/{category}/{slug}/pdf endpoint"""
        response = client.get("/api/resources/biblical_locations/garden-of-eden/pdf")
        # Should either succeed with PDF or return 503 if WeasyPrint not available
        assert response.status_code in [200, 503]
        if response.status_code == 200:
            assert response.headers["content-type"] == "application/pdf"
            assert "garden-of-eden" in response.headers.get("content-disposition", "")

    def test_resource_pdf_nonexistent_category(self, client):
        """Test PDF endpoint with nonexistent category"""
        response = client.get("/api/resources/nonexistent/pdf")
        assert response.status_code == 404

    def test_resource_pdf_nonexistent_item(self, client):
        """Test PDF endpoint with nonexistent item"""
        response = client.get("/api/resources/angels/nonexistent-angel/pdf")
        assert response.status_code == 404

    def test_all_resource_categories_accessible(self, client):
        """Test that all 39 categories are accessible"""
        # Get list of all categories
        response = client.get("/api/resources")
        assert response.status_code == 200
        categories = response.json()["categories"]

        # Test a sample of categories (not all 39 to keep test fast)
        sample_categories = [cat["name"] for cat in categories[:10]]

        for cat_name in sample_categories:
            response = client.get(f"/api/resources/{cat_name}")
            assert response.status_code == 200, f"Failed to access category: {cat_name}"
            assert response.json()["category"] == cat_name


class TestRedLetterEndpoints:
    """Tests for red letter (words of Christ) endpoints"""

    def test_list_red_letter_verses(self, client):
        """Test /api/red-letter endpoint returns list of verses"""
        response = client.get("/api/red-letter")
        assert response.status_code == 200
        data = response.json()

        # Check response structure
        assert "total" in data
        assert "verses" in data
        assert "limit" in data
        assert "offset" in data

        # Verify we have verses
        assert data["total"] > 0
        assert len(data["verses"]) > 0

        # Check first verse structure
        first_verse = data["verses"][0]
        assert "reference" in first_verse
        assert "book" in first_verse
        assert "chapter" in first_verse
        assert "verse" in first_verse
        assert "text" in first_verse
        assert "christ_words" in first_verse
        assert "is_full_verse" in first_verse

    def test_list_red_letter_with_pagination(self, client):
        """Test pagination parameters work correctly"""
        # Get first 10 verses
        response1 = client.get("/api/red-letter?limit=10&offset=0")
        assert response1.status_code == 200
        data1 = response1.json()
        assert data1["limit"] == 10
        assert data1["offset"] == 0
        assert len(data1["verses"]) == 10

        # Get next 10 verses
        response2 = client.get("/api/red-letter?limit=10&offset=10")
        assert response2.status_code == 200
        data2 = response2.json()
        assert data2["limit"] == 10
        assert data2["offset"] == 10
        assert len(data2["verses"]) == 10

        # Verify different verses
        assert data1["verses"][0]["reference"] != data2["verses"][0]["reference"]

    def test_list_red_letter_filter_by_book(self, client):
        """Test filtering by book works correctly"""
        response = client.get("/api/red-letter?book=John")
        assert response.status_code == 200
        data = response.json()

        # All verses should be from John
        assert data["total"] > 0
        for verse in data["verses"]:
            assert verse["book"] == "John"

    def test_list_red_letter_filter_by_book_multiple_books(self, client):
        """Test that different books return different results"""
        response_john = client.get("/api/red-letter?book=John&limit=10")
        response_matthew = client.get("/api/red-letter?book=Matthew&limit=10")

        assert response_john.status_code == 200
        assert response_matthew.status_code == 200

        john_data = response_john.json()
        matthew_data = response_matthew.json()

        # Both should have verses
        assert john_data["total"] > 0
        assert matthew_data["total"] > 0

        # All verses in each response should be from the correct book
        for verse in john_data["verses"]:
            assert verse["book"] == "John"
        for verse in matthew_data["verses"]:
            assert verse["book"] == "Matthew"

    def test_red_letter_stats(self, client):
        """Test /api/red-letter/stats endpoint"""
        response = client.get("/api/red-letter/stats")
        assert response.status_code == 200
        data = response.json()

        # Check response structure
        assert "total_verses" in data
        assert "full_verses" in data
        assert "partial_verses" in data
        assert "books_with_red_letter" in data
        assert "by_book" in data

        # Verify counts make sense
        assert data["total_verses"] > 0
        assert data["full_verses"] > 0
        assert data["partial_verses"] >= 0
        assert data["total_verses"] == data["full_verses"] + data["partial_verses"]

        # Verify books list
        assert len(data["books_with_red_letter"]) > 0
        assert "Matthew" in data["books_with_red_letter"]
        assert "Mark" in data["books_with_red_letter"]
        assert "Luke" in data["books_with_red_letter"]
        assert "John" in data["books_with_red_letter"]

        # Verify by_book counts
        assert isinstance(data["by_book"], dict)
        assert "Matthew" in data["by_book"]
        assert data["by_book"]["Matthew"] > 0

    def test_red_letter_verses_contain_expected_data(self, client):
        """Test that specific known red letter verses are included"""
        response = client.get("/api/red-letter?book=John&limit=500")
        assert response.status_code == 200
        data = response.json()

        # Find John 3:16 (Jesus speaks the entire verse)
        john_316 = None
        for verse in data["verses"]:
            if verse["chapter"] == 3 and verse["verse"] == 16:
                john_316 = verse
                break

        assert john_316 is not None, "John 3:16 should be in red letter verses"
        assert john_316["is_full_verse"] is True
        assert john_316["christ_words"] == "full"
        assert "God so loved the world" in john_316["text"]

    def test_red_letter_pagination_limits(self, client):
        """Test pagination limit validation"""
        # Test maximum limit
        response = client.get("/api/red-letter?limit=500")
        assert response.status_code == 200

        # Test exceeding maximum limit should be rejected
        response = client.get("/api/red-letter?limit=1000")
        assert response.status_code == 422  # Validation error

    def test_api_index_includes_red_letter_endpoints(self, client):
        """Test that API index includes red letter endpoints"""
        response = client.get("/api/")
        assert response.status_code == 200
        data = response.json()

        assert "endpoints" in data
        assert "red_letter" in data["endpoints"]
        assert "red_letter_stats" in data["endpoints"]


class TestRandomVerseEndpoint:
    """Tests for random verse endpoint"""

    def test_random_verse_basic(self, client):
        """Test basic random verse generation"""
        response = client.get("/api/verse/random")
        assert response.status_code == 200
        data = response.json()

        # Verify structure
        assert "book" in data
        assert "chapter" in data
        assert "verse" in data
        assert "reference" in data
        assert "text" in data
        assert "red_letter" in data

        # Verify types
        assert isinstance(data["book"], str)
        assert isinstance(data["chapter"], int)
        assert isinstance(data["verse"], int)

    def test_random_verse_ot_filter(self, client):
        """Test filtering by Old Testament"""
        response = client.get("/api/verse/random?testament=ot")
        assert response.status_code == 200
        data = response.json()

        # OT books don't include Matthew, Mark, Luke, John, etc.
        nt_books = ["Matthew", "Mark", "Luke", "John", "Acts", "Romans", "Revelation"]
        assert data["book"] not in nt_books

    def test_random_verse_nt_filter(self, client):
        """Test filtering by New Testament"""
        response = client.get("/api/verse/random?testament=nt")
        assert response.status_code == 200
        data = response.json()

        # NT books include Matthew through Revelation
        nt_books = ["Matthew", "Mark", "Luke", "John", "Acts", "Romans", "1 Corinthians",
                    "2 Corinthians", "Galatians", "Ephesians", "Philippians", "Colossians",
                    "1 Thessalonians", "2 Thessalonians", "1 Timothy", "2 Timothy", "Titus",
                    "Philemon", "Hebrews", "James", "1 Peter", "2 Peter", "1 John", "2 John",
                    "3 John", "Jude", "Revelation"]
        assert data["book"] in nt_books

    def test_random_verse_book_filter(self, client):
        """Test filtering by specific book"""
        response = client.get("/api/verse/random?book=John")
        assert response.status_code == 200
        data = response.json()

        assert data["book"] == "John"

    def test_random_verse_invalid_testament(self, client):
        """Test invalid testament parameter"""
        response = client.get("/api/verse/random?testament=invalid")
        assert response.status_code == 400


class TestCommentaryEndpoint:
    """Tests for verse commentary endpoint"""

    def test_get_verse_commentary(self, client):
        """Test getting commentary for a verse"""
        response = client.get("/api/commentary/Genesis/1/1")
        assert response.status_code == 200
        data = response.json()

        # Verify structure
        assert data["book"] == "Genesis"
        assert data["chapter"] == 1
        assert data["verse"] == 1
        assert "reference" in data
        assert "text" in data
        assert "analysis" in data
        assert "historical" in data
        assert "questions" in data

        # Verify content
        assert isinstance(data["questions"], list)
        assert len(data["analysis"]) > 0

    def test_commentary_nonexistent_verse(self, client):
        """Test commentary for non-existent verse"""
        response = client.get("/api/commentary/Genesis/1/99999")
        assert response.status_code == 404

    def test_commentary_missing_for_verse(self, client):
        """Test verse with no commentary available"""
        # Most verses should have commentary, but check proper 404 handling
        response = client.get("/api/commentary/Philemon/1/999")
        assert response.status_code == 404


class TestChapterCommentaryEndpoint:
    """Tests for chapter commentary endpoint"""

    def test_get_chapter_commentary(self, client):
        """Test getting chapter commentary"""
        response = client.get("/api/chapter-commentary/Genesis/1")
        assert response.status_code == 200
        data = response.json()

        assert data["book"] == "Genesis"
        assert data["chapter"] == 1
        assert "explanation" in data
        assert len(data["explanation"]) > 0

    def test_chapter_commentary_nonexistent_book(self, client):
        """Test commentary for non-existent book"""
        response = client.get("/api/chapter-commentary/InvalidBook/1")
        assert response.status_code == 404

    def test_chapter_commentary_nonexistent_chapter(self, client):
        """Test commentary for non-existent chapter"""
        response = client.get("/api/chapter-commentary/Genesis/999")
        assert response.status_code == 404


class TestBulkVerseEndpoint:
    """Tests for bulk verse lookup endpoint"""

    def test_bulk_verse_lookup(self, client):
        """Test bulk verse lookup with multiple verses"""
        response = client.post("/api/verses/bulk", json={
            "references": ["John 3:16", "Romans 8:28", "Psalm 23:1"]
        })
        assert response.status_code == 200
        data = response.json()

        assert data["total"] == 3
        assert len(data["verses"]) == 3

        # Check first verse
        assert data["verses"][0]["book"] == "John"
        assert data["verses"][0]["chapter"] == 3
        assert data["verses"][0]["verse"] == 16

    def test_bulk_verse_with_invalid_references(self, client):
        """Test bulk lookup with some invalid references"""
        response = client.post("/api/verses/bulk", json={
            "references": ["John 3:16", "Invalid Reference", "Genesis 1:1"]
        })
        assert response.status_code == 200
        data = response.json()

        # Should return 2 valid verses, skipping invalid
        assert data["total"] == 2

    def test_bulk_verse_empty_list(self, client):
        """Test bulk lookup with empty list"""
        response = client.post("/api/verses/bulk", json={
            "references": []
        })
        assert response.status_code == 200
        data = response.json()

        assert data["total"] == 0
        assert len(data["verses"]) == 0


class TestFamilyTreeEndpoints:
    """Tests for family tree/biography endpoints"""

    def test_list_family_tree(self, client):
        """Test listing all biblical figures"""
        response = client.get("/api/family-tree")
        assert response.status_code == 200
        data = response.json()

        assert "total" in data
        assert "people" in data
        assert data["total"] > 0
        assert len(data["people"]) == data["total"]

        # Check some expected people
        assert "Abraham" in data["people"]
        assert "Moses" in data["people"]
        assert "David" in data["people"]

    def test_get_biography(self, client):
        """Test getting a specific biography"""
        response = client.get("/api/family-tree/Abraham")
        assert response.status_code == 200
        data = response.json()

        assert data["name"] == "Abraham"
        assert "summary" in data
        assert "significance" in data
        assert "key_events" in data

        # Verify key events structure
        assert isinstance(data["key_events"], list)
        if len(data["key_events"]) > 0:
            event = data["key_events"][0]
            assert "age" in event
            assert "event" in event
            assert "verse" in event

    def test_biography_with_alias(self, client):
        """Test getting biography using an alias name"""
        response = client.get("/api/family-tree/Israel")
        assert response.status_code == 200
        data = response.json()

        # Should resolve to Jacob
        assert data["name"] == "Jacob"

    def test_biography_nonexistent_person(self, client):
        """Test getting biography for non-existent person"""
        response = client.get("/api/family-tree/NonExistentPerson")
        assert response.status_code == 404

    def test_family_tree_stats(self, client):
        """Test getting family tree statistics from GEDCOM data"""
        response = client.get("/api/family-tree/stats")
        assert response.status_code == 200
        data = response.json()

        # Verify all expected fields are present
        assert "total_people" in data
        assert "total_generations" in data
        assert "longest_lived" in data
        assert "most_children" in data
        assert "most_siblings" in data
        assert "average_lifespan" in data
        assert "total_with_known_ages" in data
        assert "close_family_marriages" in data

        # Verify types
        assert isinstance(data["total_people"], int)
        assert isinstance(data["total_generations"], int)
        assert data["total_people"] > 0
        assert data["total_generations"] > 0

        # Verify longest_lived structure
        assert "name" in data["longest_lived"]
        assert "person_id" in data["longest_lived"]
        assert "value" in data["longest_lived"]
        assert "additional_info" in data["longest_lived"]
        assert isinstance(data["longest_lived"]["name"], str)
        assert isinstance(data["longest_lived"]["person_id"], str)
        assert isinstance(data["longest_lived"]["value"], int)

        # Verify most_children structure
        assert "name" in data["most_children"]
        assert "person_id" in data["most_children"]
        assert "value" in data["most_children"]
        assert "additional_info" in data["most_children"]
        assert isinstance(data["most_children"]["name"], str)
        assert isinstance(data["most_children"]["person_id"], str)
        assert isinstance(data["most_children"]["value"], int)
        assert data["most_children"]["value"] >= 0

        # Verify most_siblings structure
        assert "name" in data["most_siblings"]
        assert "person_id" in data["most_siblings"]
        assert "value" in data["most_siblings"]
        assert "additional_info" in data["most_siblings"]
        assert isinstance(data["most_siblings"]["name"], str)
        assert isinstance(data["most_siblings"]["person_id"], str)
        assert isinstance(data["most_siblings"]["value"], int)
        assert data["most_siblings"]["value"] >= 0

        # Verify average lifespan is either a number or null
        assert data["average_lifespan"] is None or isinstance(data["average_lifespan"], (int, float))

        # Verify close family marriages is an integer
        assert isinstance(data["close_family_marriages"], int)
        assert data["close_family_marriages"] >= 0

    def test_api_index_includes_new_endpoints(self, client):
        """Test that API index includes all new endpoints"""
        response = client.get("/api/")
        assert response.status_code == 200
        data = response.json()

        assert "endpoints" in data
        assert "random_verse" in data["endpoints"]
        assert "commentary" in data["endpoints"]
        assert "chapter_commentary" in data["endpoints"]
        assert "bulk_verses" in data["endpoints"]
        assert "family_tree" in data["endpoints"]
        assert "family_tree_stats" in data["endpoints"]
        assert "biography" in data["endpoints"]


class TestStatsEndpoint:
    """Tests for the /api/stats endpoint"""

    def test_stats_endpoint_returns_200(self, client):
        """Test /api/stats returns 200"""
        response = client.get("/api/stats")
        assert response.status_code == 200

    def test_stats_has_bible_section(self, client):
        """Test stats includes bible statistics"""
        response = client.get("/api/stats")
        data = response.json()
        assert "bible" in data
        assert data["bible"]["total_verses"] == 31102
        assert data["bible"]["total_books"] == 66
        assert data["bible"]["ot_books"] == 39
        assert data["bible"]["nt_books"] == 27

    def test_stats_has_commentary_section(self, client):
        """Test stats includes commentary statistics"""
        response = client.get("/api/stats")
        data = response.json()
        assert "commentary" in data
        assert "files" in data["commentary"]
        assert "verses_covered" in data["commentary"]
        assert "coverage_percent" in data["commentary"]

    def test_stats_has_cross_references_section(self, client):
        """Test stats includes cross-references statistics"""
        response = client.get("/api/stats")
        data = response.json()
        assert "cross_references" in data
        assert "total_references" in data["cross_references"]
        assert "coverage_percent" in data["cross_references"]

    def test_stats_has_red_letter_section(self, client):
        """Test stats includes red letter statistics"""
        response = client.get("/api/stats")
        data = response.json()
        assert "red_letter" in data
        assert "total_verses" in data["red_letter"]
        assert "percent_of_bible" in data["red_letter"]

    def test_stats_has_study_resources_section(self, client):
        """Test stats includes study resources statistics"""
        response = client.get("/api/stats")
        data = response.json()
        assert "study_resources" in data
        assert "study_guides" in data["study_resources"]
        assert "topics" in data["study_resources"]
        assert "biographies" in data["study_resources"]

    def test_stats_has_language_tools_section(self, client):
        """Test stats includes language tools statistics"""
        response = client.get("/api/stats")
        data = response.json()
        assert "language_tools" in data
        assert "hebrew_entries" in data["language_tools"]
        assert "greek_entries" in data["language_tools"]
        assert "total_strongs" in data["language_tools"]

    def test_stats_has_data_section(self, client):
        """Test stats includes data statistics"""
        response = client.get("/api/stats")
        data = response.json()
        assert "data" in data
        assert "total_json_files" in data["data"]
        assert "total_size_mb" in data["data"]
