"""
Tests for search page integration

Tests cover:
- Search page rendering
- Search results display
- Search box in navigation
- Empty state handling
- Error state handling
- Pagination controls
"""

import pytest
from pathlib import Path

from starpunk import create_app
from starpunk.notes import create_note


@pytest.fixture
def app(tmp_path):
    """Create test application with FTS5 enabled"""
    test_data_dir = tmp_path / "data"
    test_data_dir.mkdir(parents=True, exist_ok=True)

    test_config = {
        "TESTING": True,
        "DATABASE_PATH": test_data_dir / "starpunk.db",
        "DATA_PATH": test_data_dir,
        "NOTES_PATH": test_data_dir / "notes",
        "SESSION_SECRET": "test-secret-key",
        "ADMIN_ME": "https://test.example.com",
        "SITE_URL": "https://example.com",
        "SITE_NAME": "Test Blog",
        "DEV_MODE": False,
    }
    app = create_app(config=test_config)
    return app


@pytest.fixture
def client(app):
    """Create test client"""
    return app.test_client()


@pytest.fixture
def test_notes(app):
    """Create test notes for searching"""
    with app.app_context():
        notes = []

        for i in range(5):
            note = create_note(
                content=f"# Test Note {i}\n\nThis is test content about topic {i}.",
                published=True
            )
            notes.append(note)

        return notes


def test_search_page_renders(client):
    """Test that search page renders without errors"""
    response = client.get("/search")
    assert response.status_code == 200
    assert b"Search Results" in response.data


def test_search_page_shows_empty_state(client):
    """Test that search page shows empty state without query"""
    response = client.get("/search")
    assert response.status_code == 200
    assert b"Enter search terms" in response.data or b"Search" in response.data


def test_search_page_displays_results(client, test_notes):
    """Test that search page displays results"""
    response = client.get("/search?q=test")
    assert response.status_code == 200

    # Should show query and results
    assert b"test" in response.data.lower()
    assert b"Test Note" in response.data


def test_search_page_displays_result_count(client, test_notes):
    """Test that search page displays result count"""
    response = client.get("/search?q=test")
    assert response.status_code == 200

    # Should show "Found X results"
    assert b"Found" in response.data or b"result" in response.data.lower()


def test_search_page_handles_no_results(client, test_notes):
    """Test that search page handles no results gracefully"""
    response = client.get("/search?q=nonexistent")
    assert response.status_code == 200

    # Should show "no results" message
    assert b"No results" in response.data or b"didn't match" in response.data


def test_search_page_preserves_query(client, test_notes):
    """Test that search page preserves query in search box"""
    response = client.get("/search?q=python")
    assert response.status_code == 200

    # Search form should have the query pre-filled
    assert b'value="python"' in response.data


def test_search_page_shows_pagination(client, test_notes):
    """Test that search page shows pagination controls when appropriate"""
    response = client.get("/search?q=test")
    assert response.status_code == 200

    # May or may not show pagination depending on result count
    # Just verify page renders without error


def test_search_page_pagination_links(client, test_notes):
    """Test that pagination links work correctly"""
    # Get second page
    response = client.get("/search?q=test&offset=20")
    assert response.status_code == 200

    # Should render without error
    assert b"Search Results" in response.data


def test_search_box_in_navigation(client):
    """Test that search box appears in navigation on all pages"""
    # Check on homepage
    response = client.get("/")
    assert response.status_code == 200
    assert b'type="search"' in response.data
    assert b'name="q"' in response.data
    assert b'action="/search"' in response.data


def test_search_box_preserves_query_on_results_page(client, test_notes):
    """Test that search box preserves query on results page"""
    response = client.get("/search?q=test")
    assert response.status_code == 200

    # Navigation search box should also have the query
    # (There are two search forms: one in nav, one on the page)
    assert response.data.count(b'value="test"') >= 1


def test_search_page_escapes_html_in_query(client):
    """Test that search page escapes HTML in query display"""
    response = client.get("/search?q=<script>alert('xss')</script>")
    assert response.status_code == 200

    # Should not contain unescaped script tag
    assert b"<script>alert('xss')</script>" not in response.data
    # Should contain escaped version
    assert b"&lt;script&gt;" in response.data or b"alert" in response.data


def test_search_page_shows_excerpt_with_highlighting(client, test_notes):
    """Test that search page shows excerpts with highlighting"""
    response = client.get("/search?q=test")
    assert response.status_code == 200

    # Should contain <mark> tags for highlighting (from FTS5 snippet)
    # or at least show the excerpt
    assert b"Test" in response.data


def test_search_page_shows_note_dates(client, test_notes):
    """Test that search page shows note publication dates"""
    response = client.get("/search?q=test")
    assert response.status_code == 200

    # Should contain time element with datetime
    assert b"<time" in response.data


def test_search_page_links_to_notes(client, test_notes):
    """Test that search results link to individual notes"""
    response = client.get("/search?q=test")
    assert response.status_code == 200

    # Should contain links to /notes/
    assert b'href="/notes/' in response.data


def test_search_form_validation(client):
    """Test that search form has proper HTML5 validation"""
    response = client.get("/search")
    assert response.status_code == 200

    # Should have minlength and maxlength attributes
    assert b"minlength" in response.data
    assert b"maxlength" in response.data
    assert b"required" in response.data


def test_search_page_handles_offset_param(client, test_notes):
    """Test that search page handles offset parameter"""
    response = client.get("/search?q=test&offset=1")
    assert response.status_code == 200

    # Should render without error
    assert b"Search Results" in response.data


def test_search_page_shows_error_when_fts_unavailable(client, app):
    """Test that search page shows error message when FTS5 is unavailable"""
    # This test would require mocking has_fts_table to return False
    # For now, just verify the error handling path exists
    response = client.get("/search?q=test")
    assert response.status_code == 200
    # Page should render even if FTS is unavailable
