"""
Tests for advanced routes: Family Tree, Timeline, Concordance, and Study Guides.

These tests cover complex, user-facing features with multiple routes and data dependencies.
"""
import pytest


class TestFamilyTreeRoutes:
    """Tests for biblical family tree genealogy routes"""

    def test_family_tree_main_page(self, client):
        """Test main family tree page loads"""
        response = client.get("/family-tree")
        assert response.status_code == 200
        content = response.content.decode()
        assert "family" in content.lower() or "tree" in content.lower()

    def test_family_tree_has_generations(self, client):
        """Test family tree page displays generation information"""
        response = client.get("/family-tree")
        assert response.status_code == 200
        content = response.content.decode()
        # Should reference generations or genealogy
        assert "generation" in content.lower() or "genealogy" in content.lower()

    def test_family_tree_generation_page(self, client):
        """Test individual generation page loads"""
        # Test generation 1 (Adam/Eve)
        response = client.get("/family-tree/generation/1")
        assert response.status_code == 200
        content = response.content.decode()
        assert "generation" in content.lower()

    def test_family_tree_generation_adam(self, client):
        """Test generation 1 contains Adam"""
        response = client.get("/family-tree/generation/1")
        assert response.status_code == 200
        content = response.content.decode()
        assert "Adam" in content or "adam" in content.lower()

    def test_family_tree_invalid_generation(self, client):
        """Test non-existent generation returns 404"""
        response = client.get("/family-tree/generation/999")
        assert response.status_code == 404

    def test_family_tree_person_page(self, client):
        """Test individual person page loads"""
        # Test Adam's page
        response = client.get("/family-tree/person/i1")
        assert response.status_code in [200, 404]  # May or may not exist depending on GEDCOM data

        if response.status_code == 200:
            content = response.content.decode()
            # Should have person information
            assert len(content) > 100

    def test_family_tree_person_not_found(self, client):
        """Test non-existent person returns 404"""
        response = client.get("/family-tree/person/invalid-person-id-xyz")
        assert response.status_code == 404

    def test_family_tree_search_page(self, client):
        """Test family tree search page loads"""
        response = client.get("/family-tree/search")
        assert response.status_code == 200
        content = response.content.decode()
        assert "search" in content.lower()

    def test_family_tree_search_with_query(self, client):
        """Test family tree search with query parameter"""
        response = client.get("/family-tree/search?q=Adam")
        assert response.status_code in [200, 303]  # 303 if exact match redirects

        if response.status_code == 200:
            content = response.content.decode()
            assert "Adam" in content or "adam" in content.lower()

    def test_family_tree_search_empty_query(self, client):
        """Test family tree search with empty query"""
        response = client.get("/family-tree/search?q=")
        assert response.status_code == 200

    def test_family_tree_lineage_page(self, client):
        """Test Messianic lineage page loads"""
        response = client.get("/family-tree/lineage")
        assert response.status_code == 200
        content = response.content.decode()
        assert "lineage" in content.lower() or "messiah" in content.lower()

    def test_family_tree_lineage_svg(self, client):
        """Test Messianic lineage SVG generation"""
        response = client.get("/family-tree/lineage.svg")
        assert response.status_code == 200
        assert response.headers["content-type"] == "image/svg+xml"

        # Verify it's valid SVG
        content = response.content.decode()
        assert "<svg" in content
        assert "</svg>" in content

    def test_family_tree_descendants_page(self, client):
        """Test descendants view for a person"""
        # Test Adam's descendants
        response = client.get("/family-tree/person/i1/descendants")
        assert response.status_code in [200, 404]  # 404 if person not found

        if response.status_code == 200:
            content = response.content.decode()
            assert "descendants" in content.lower() or "descendant" in content.lower()

    def test_family_tree_descendants_invalid_person(self, client):
        """Test descendants view for non-existent person"""
        response = client.get("/family-tree/person/invalid-xyz/descendants")
        assert response.status_code == 404

    def test_family_tree_ancestors_page(self, client):
        """Test ancestors view for a person"""
        # Test Jesus's ancestors
        response = client.get("/family-tree/person/i42/ancestors")
        assert response.status_code in [200, 404]  # 404 if person not found

        if response.status_code == 200:
            content = response.content.decode()
            assert "ancestors" in content.lower() or "ancestor" in content.lower()

    def test_family_tree_ancestors_invalid_person(self, client):
        """Test ancestors view for non-existent person"""
        response = client.get("/family-tree/person/invalid-xyz/ancestors")
        assert response.status_code == 404

    def test_family_tree_navigation_links(self, client):
        """Test family tree pages have proper navigation"""
        response = client.get("/family-tree")
        assert response.status_code == 200
        content = response.content.decode()

        # Should have links to persons or generations
        assert "/family-tree/" in content


class TestBiblicalTimelineRoutes:
    """Tests for biblical timeline routes"""

    def test_timeline_page_loads(self, client):
        """Test biblical timeline page loads"""
        response = client.get("/biblical-timeline")
        assert response.status_code == 200
        content = response.content.decode()
        assert "timeline" in content.lower()

    def test_timeline_has_events(self, client):
        """Test timeline displays biblical events"""
        response = client.get("/biblical-timeline")
        assert response.status_code == 200
        content = response.content.decode()

        # Should contain references to major biblical events or periods
        assert (
            "creation" in content.lower() or
            "flood" in content.lower() or
            "abraham" in content.lower() or
            "exodus" in content.lower() or
            "christ" in content.lower()
        )

    def test_timeline_has_dates(self, client):
        """Test timeline includes chronological dates"""
        response = client.get("/biblical-timeline")
        assert response.status_code == 200
        content = response.content.decode()

        # Should have BC dates
        assert "BC" in content or "BCE" in content or "AM" in content

    def test_timeline_pdf_generation(self, client):
        """Test timeline PDF generation"""
        response = client.get("/biblical-timeline/pdf")

        # PDF generation might not be available
        assert response.status_code in [200, 500, 503]

        if response.status_code == 200:
            assert response.headers["content-type"] == "application/pdf"
            # Verify it's a PDF
            assert response.content[:4] == b'%PDF'

    def test_timeline_metadata(self, client):
        """Test timeline page has proper metadata"""
        response = client.get("/biblical-timeline")
        assert response.status_code == 200
        content = response.content.decode()

        # Should have HTML structure
        assert "<html" in content.lower()
        assert "<title>" in content


class TestStrongsRoutes:
    """Tests for Strong's Concordance routes"""

    def test_strongs_page_loads(self, client):
        """Test Strong's index page loads"""
        response = client.get("/strongs")
        assert response.status_code == 200
        content = response.content.decode()
        assert "strong" in content.lower()

    def test_strongs_has_search(self, client):
        """Test Strong's page has search functionality"""
        response = client.get("/strongs")
        assert response.status_code == 200
        content = response.content.decode()

        # Should have search input or form
        assert "search" in content.lower()

    def test_strongs_with_search_query(self, client):
        """Test Strong's with search query"""
        response = client.get("/strongs?q=love")
        assert response.status_code == 200
        content = response.content.decode()

        # Should display results for "love"
        assert "love" in content.lower()

    def test_strongs_entry_page(self, client):
        """Test Strong's entry page loads"""
        response = client.get("/strongs/G26")
        assert response.status_code == 200
        content = response.content.decode()

        # Should have agape (love)
        assert "agape" in content.lower() or "ἀγάπη" in content

    def test_strongs_hebrew_entry(self, client):
        """Test Hebrew Strong's entry page"""
        response = client.get("/strongs/H430")
        assert response.status_code == 200
        content = response.content.decode()

        # Should have Elohim (God)
        assert "elohim" in content.lower() or "אֱלֹהִים" in content

    def test_strongs_hebrew_index(self, client):
        """Test Hebrew Strong's index page"""
        response = client.get("/strongs/hebrew")
        assert response.status_code == 200
        content = response.content.decode()

        # Should have Hebrew entries
        assert "Hebrew" in content
        assert "H1" in content or "H2" in content

    def test_strongs_greek_index(self, client):
        """Test Greek Strong's index page"""
        response = client.get("/strongs/greek")
        assert response.status_code == 200
        content = response.content.decode()

        # Should have Greek entries
        assert "Greek" in content
        assert "G1" in content or "G2" in content

    def test_strongs_pagination(self, client):
        """Test Strong's index pagination"""
        response = client.get("/strongs/hebrew?page=2")
        assert response.status_code == 200
        content = response.content.decode()

        # Should show page 2
        assert "Page 2" in content or "page=1" in content

    def test_strongs_invalid_entry(self, client):
        """Test invalid Strong's number returns 404"""
        response = client.get("/strongs/X9999")
        assert response.status_code == 404


class TestStudyGuidesRoutes:
    """Tests for study guides routes"""

    def test_study_guides_index_loads(self, client):
        """Test study guides index page loads"""
        response = client.get("/study-guides")
        assert response.status_code == 200
        content = response.content.decode()
        assert "study" in content.lower() or "guide" in content.lower()

    def test_study_guides_has_categories(self, client):
        """Test study guides index has categories"""
        response = client.get("/study-guides")
        assert response.status_code == 200
        content = response.content.decode()

        # Should have study guide categories or links
        assert len(content) > 1000  # Substantial content

    def test_study_guides_has_links(self, client):
        """Test study guides index links to individual guides"""
        response = client.get("/study-guides")
        assert response.status_code == 200
        content = response.content.decode()

        # Should have links to individual study guides
        assert "/study-guides/" in content

    def test_study_guide_detail_page(self, client):
        """Test individual study guide detail page"""
        # Test a common study guide slug
        response = client.get("/study-guides/salvation")
        assert response.status_code in [200, 404]

        if response.status_code == 200:
            content = response.content.decode()
            assert "salvation" in content.lower()

    def test_study_guide_gospel(self, client):
        """Test gospel study guide"""
        response = client.get("/study-guides/gospel")
        assert response.status_code in [200, 404]

        if response.status_code == 200:
            content = response.content.decode()
            assert "gospel" in content.lower()

    def test_study_guide_prayer_faith(self, client):
        """Test prayer & faith study guide"""
        response = client.get("/study-guides/prayer-faith")
        assert response.status_code in [200, 404]

    def test_study_guide_invalid_slug(self, client):
        """Test non-existent study guide returns 404"""
        response = client.get("/study-guides/this-guide-does-not-exist")
        assert response.status_code == 404

    def test_study_guide_has_verses(self, client):
        """Test study guide pages include verse references"""
        response = client.get("/study-guides/salvation")

        if response.status_code == 200:
            content = response.content.decode()
            # Should have verse references or Bible links
            assert (
                "/book/" in content or
                "verse" in content.lower() or
                "chapter" in content.lower()
            )

    def test_study_guide_pdf_generation(self, client):
        """Test study guide PDF generation"""
        response = client.get("/study-guides/salvation/pdf")

        # PDF might not be available or guide might not exist
        assert response.status_code in [200, 404, 500, 503]

        if response.status_code == 200:
            assert response.headers["content-type"] == "application/pdf"
            # Verify it's a PDF
            assert response.content[:4] == b'%PDF'

    def test_study_guide_pdf_invalid_slug(self, client):
        """Test PDF for non-existent study guide returns error"""
        response = client.get("/study-guides/invalid-guide-xyz/pdf")
        # Should return 404 for invalid guide, or 503 if WeasyPrint not available
        assert response.status_code in [404, 503]

    def test_study_guide_navigation(self, client):
        """Test study guide pages have breadcrumbs/navigation"""
        response = client.get("/study-guides/salvation")

        if response.status_code == 200:
            content = response.content.decode()
            # Should have navigation back to study guides
            assert "/study-guides" in content or "study guide" in content.lower()


class TestAdvancedRoutesIntegration:
    """Integration tests across multiple advanced route types"""

    def test_all_major_pages_load(self, client):
        """Test all major advanced pages load successfully"""
        pages = [
            "/family-tree",
            "/biblical-timeline",
            "/strongs",
            "/study-guides",
        ]

        for page in pages:
            response = client.get(page)
            assert response.status_code == 200, f"Page {page} failed to load"

    def test_pages_have_html_structure(self, client):
        """Test pages have valid HTML structure"""
        pages = [
            "/family-tree",
            "/biblical-timeline",
            "/strongs",
            "/study-guides",
        ]

        for page in pages:
            response = client.get(page)
            if response.status_code == 200:
                content = response.content.decode()
                assert "<html" in content.lower()
                assert "<body" in content.lower()
                assert "</html>" in content.lower()

    def test_pages_have_titles(self, client):
        """Test pages have proper title tags"""
        pages = [
            "/family-tree",
            "/biblical-timeline",
            "/strongs",
            "/study-guides",
        ]

        for page in pages:
            response = client.get(page)
            if response.status_code == 200:
                content = response.content.decode()
                assert "<title>" in content.lower()

    def test_pages_return_html_content_type(self, client):
        """Test HTML pages return correct content type"""
        pages = [
            "/family-tree",
            "/biblical-timeline",
            "/strongs",
            "/study-guides",
        ]

        for page in pages:
            response = client.get(page)
            if response.status_code == 200:
                content_type = response.headers.get("content-type", "")
                assert "text/html" in content_type


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