"""
Test export formats (PDF, LaTeX, Markdown) for research reports

⚠️ IMPORTANT: THESE ARE REAL INTEGRATION TESTS ⚠️

These tests run against a REAL running LDR server and perform ACTUAL operations.
They use Puppeteer for authentication and pytest for test execution and validation.
"""

import time
import pytest


@pytest.mark.skip(
    reason="Timing out in CI - research takes too long with OLLAMA model"
)
def test_export_latex(auth_session, base_url):
    """Test exporting research report as LaTeX"""
    session, csrf_token = auth_session

    # First, start a simple research
    research_data = {
        "query": f"Test LaTeX export {time.time()}",
        "search_engine": "auto",
        "model": "gemma3n:e2b",
        "model_provider": "OLLAMA",
        "mode": "quick",
        "iterations": 1,
        "questions_per_iteration": 1,
    }

    response = session.post(
        f"{base_url}/api/start_research", json=research_data
    )
    if response.status_code not in [200, 201, 202]:
        print(f"Error response: {response.status_code}")
        print(f"Response body: {response.text}")
    assert response.status_code in [200, 201, 202]
    research_id = response.json()["research_id"]

    # Wait for research to complete
    print(f"Started research {research_id}, waiting for completion...")
    max_wait = 60  # Maximum wait time in seconds
    wait_interval = 2
    elapsed = 0

    while elapsed < max_wait:
        status_response = session.get(
            f"{base_url}/api/research/{research_id}/status"
        )
        if status_response.status_code == 200:
            status_data = status_response.json()
            if status_data.get("status") == "completed":
                print(f"Research completed after {elapsed} seconds")
                break
        time.sleep(wait_interval)
        elapsed += wait_interval
    else:
        print(f"Research did not complete within {max_wait} seconds")

    # Additional wait to ensure report is saved
    time.sleep(2)  # allow: unmarked-sleep

    # Try to export as LaTeX
    export_response = session.post(
        f"{base_url}/api/v1/research/{research_id}/export/latex"
    )

    # Check response
    assert export_response.status_code == 200, (
        f"LaTeX export failed: {export_response.text}"
    )

    # Check content type
    content_type = export_response.headers.get("Content-Type", "")
    assert (
        "text/plain" in content_type or "application/x-latex" in content_type
    ), f"Unexpected content type: {content_type}"

    # Check that we got actual LaTeX content
    content = export_response.text
    assert len(content) > 100, f"LaTeX content too short: {len(content)} bytes"

    # Check for LaTeX markers
    assert "\\documentclass" in content or "\\begin{document}" in content, (
        "No LaTeX document structure found"
    )

    # Check filename in Content-Disposition
    content_disposition = export_response.headers.get("Content-Disposition", "")
    assert ".tex" in content_disposition, (
        f"Expected .tex file in Content-Disposition: {content_disposition}"
    )

    print(f"✓ LaTeX export successful - {len(content)} bytes")
    print(f"  First 200 chars: {content[:200]}...")


def test_export_pdf_via_javascript(auth_session, base_url):
    """Test PDF export (generated client-side via JavaScript)"""
    session, csrf_token = auth_session

    # First, start a simple research
    research_data = {
        "query": f"Test PDF export {time.time()}",
        "search_engine": "auto",
        "model": "gemma3n:e2b",
        "model_provider": "OLLAMA",
        "mode": "quick",
        "iterations": 1,
        "questions_per_iteration": 1,
    }

    response = session.post(
        f"{base_url}/api/start_research", json=research_data
    )
    assert response.status_code in [200, 201, 202]
    research_id = response.json()["research_id"]

    # Wait for research to complete
    print(f"Started research {research_id}, waiting for completion...")
    max_wait = 60  # Maximum wait time in seconds
    wait_interval = 2
    elapsed = 0

    while elapsed < max_wait:
        status_response = session.get(
            f"{base_url}/api/research/{research_id}/status"
        )
        if status_response.status_code == 200:
            status_data = status_response.json()
            if status_data.get("status") == "completed":
                print(f"Research completed after {elapsed} seconds")
                break
        time.sleep(wait_interval)
        elapsed += wait_interval
    else:
        print(f"Research did not complete within {max_wait} seconds")

    # Additional wait to ensure report is saved
    time.sleep(2)  # allow: unmarked-sleep

    # Get the research report content
    report_response = session.get(f"{base_url}/api/report/{research_id}")
    assert report_response.status_code == 200

    report_data = report_response.json()
    assert "content" in report_data, "No content in report"

    content = report_data.get("content", "")
    assert len(content) > 100, (
        f"Report content too short for PDF: {len(content)} bytes"
    )

    print(
        f"✓ Report has content suitable for PDF export - {len(content)} bytes"
    )

    # Note: PDF generation happens client-side via jsPDF
    # We can't test the actual PDF generation here, but we've verified the content exists


def test_export_markdown(auth_session, base_url):
    """Test exporting research report as Markdown"""
    session, csrf_token = auth_session

    # First, start a simple research
    research_data = {
        "query": f"Test Markdown export {time.time()}",
        "search_engine": "auto",
        "model": "gemma3n:e2b",
        "model_provider": "OLLAMA",
        "mode": "quick",
        "iterations": 1,
        "questions_per_iteration": 1,
    }

    response = session.post(
        f"{base_url}/api/start_research", json=research_data
    )
    assert response.status_code in [200, 201, 202]
    research_id = response.json()["research_id"]

    # Wait for research to complete
    print(f"Started research {research_id}, waiting for completion...")
    max_wait = 60  # Maximum wait time in seconds
    wait_interval = 2
    elapsed = 0

    while elapsed < max_wait:
        status_response = session.get(
            f"{base_url}/api/research/{research_id}/status"
        )
        if status_response.status_code == 200:
            status_data = status_response.json()
            if status_data.get("status") == "completed":
                print(f"Research completed after {elapsed} seconds")
                break
        time.sleep(wait_interval)
        elapsed += wait_interval
    else:
        print(f"Research did not complete within {max_wait} seconds")

    # Additional wait to ensure report is saved
    time.sleep(2)  # allow: unmarked-sleep

    # Get the markdown directly from the report API
    report_response = session.get(f"{base_url}/api/report/{research_id}")
    assert report_response.status_code == 200

    report_data = report_response.json()

    # Check for markdown content
    markdown_content = report_data.get("content") or report_data.get(
        "markdown", ""
    )
    assert len(markdown_content) > 100, (
        f"Markdown content too short: {len(markdown_content)} bytes"
    )

    # Check for markdown markers
    assert "#" in markdown_content or "##" in markdown_content, (
        "No markdown headers found"
    )

    print(f"✓ Markdown export successful - {len(markdown_content)} bytes")
    print(f"  First 200 chars: {markdown_content[:200]}...")


def test_export_empty_research(auth_session, base_url):
    """Test that export fails gracefully for non-existent research"""
    session, csrf_token = auth_session

    fake_research_id = "00000000-0000-0000-0000-000000000000"

    # Try LaTeX export
    latex_response = session.post(
        f"{base_url}/api/v1/research/{fake_research_id}/export/latex"
    )
    assert latex_response.status_code in [404, 500], (
        f"Expected error for non-existent research, got {latex_response.status_code}"
    )

    # Try getting report
    report_response = session.get(f"{base_url}/api/report/{fake_research_id}")
    assert report_response.status_code in [404, 500], (
        f"Expected error for non-existent research, got {report_response.status_code}"
    )


def test_export_quarto(auth_session, base_url):
    """Test exporting research report as Quarto"""
    session, csrf_token = auth_session

    # First, start a simple research
    research_data = {
        "query": f"Test Quarto export {time.time()}",
        "search_engine": "auto",
        "model": "gemma3n:e2b",
        "model_provider": "OLLAMA",
        "mode": "quick",
        "iterations": 1,
        "questions_per_iteration": 1,
    }

    response = session.post(
        f"{base_url}/api/start_research", json=research_data
    )
    assert response.status_code in [200, 201, 202]
    research_id = response.json()["research_id"]

    # Wait for research to complete
    print(f"Started research {research_id}, waiting for completion...")
    max_wait = 60  # Maximum wait time in seconds
    wait_interval = 2
    elapsed = 0

    while elapsed < max_wait:
        status_response = session.get(
            f"{base_url}/api/research/{research_id}/status"
        )
        if status_response.status_code == 200:
            status_data = status_response.json()
            if status_data.get("status") == "completed":
                print(f"Research completed after {elapsed} seconds")
                break
        time.sleep(wait_interval)
        elapsed += wait_interval
    else:
        print(f"Research did not complete within {max_wait} seconds")

    # Additional wait to ensure report is saved
    time.sleep(2)  # allow: unmarked-sleep

    # Try to export as Quarto
    export_response = session.post(
        f"{base_url}/api/v1/research/{research_id}/export/quarto"
    )

    # Check response
    assert export_response.status_code == 200, (
        f"Quarto export failed: {export_response.text}"
    )

    # Check content
    content = export_response.text
    assert len(content) > 100, f"Quarto content too short: {len(content)} bytes"

    # Check for Quarto/markdown markers
    assert "---" in content or "#" in content, (
        "No Quarto/markdown structure found"
    )

    print(f"✓ Quarto export successful - {len(content)} bytes")


def test_export_ris(auth_session, base_url):
    """Test exporting research report as RIS (for Zotero)"""
    session, csrf_token = auth_session

    # First, start a simple research
    research_data = {
        "query": f"Test RIS export {time.time()}",
        "search_engine": "auto",
        "model": "gemma3n:e2b",
        "model_provider": "OLLAMA",
        "mode": "quick",
        "iterations": 1,
        "questions_per_iteration": 1,
    }

    response = session.post(
        f"{base_url}/api/start_research", json=research_data
    )
    assert response.status_code in [200, 201, 202]
    research_id = response.json()["research_id"]

    # Wait for research to complete
    print(f"Started research {research_id}, waiting for completion...")
    max_wait = 60  # Maximum wait time in seconds
    wait_interval = 2
    elapsed = 0

    while elapsed < max_wait:
        status_response = session.get(
            f"{base_url}/api/research/{research_id}/status"
        )
        if status_response.status_code == 200:
            status_data = status_response.json()
            if status_data.get("status") == "completed":
                print(f"Research completed after {elapsed} seconds")
                break
        time.sleep(wait_interval)
        elapsed += wait_interval
    else:
        print(f"Research did not complete within {max_wait} seconds")

    # Additional wait to ensure report is saved
    time.sleep(2)  # allow: unmarked-sleep

    # Try to export as RIS
    export_response = session.post(
        f"{base_url}/api/v1/research/{research_id}/export/ris"
    )

    # Check response
    assert export_response.status_code == 200, (
        f"RIS export failed: {export_response.text}"
    )

    # Check content
    content = export_response.text

    # If content is empty, it might be because there are no sources yet
    # Let's check the actual report first
    report_response = session.get(f"{base_url}/api/report/{research_id}")
    if report_response.status_code == 200:
        report_data = report_response.json()
        report_content = report_data.get("content") or report_data.get(
            "markdown", ""
        )
        print(
            f"Report has {len(report_content)} chars, checking for sources..."
        )
        if (
            "## Sources" not in report_content
            and "## References" not in report_content
        ):
            print(
                "Warning: No sources section found in report, skipping RIS content check"
            )
            # For quick mode with 1 iteration, there might not be sources yet
            # Just check that we got a valid response (even if empty)
            assert export_response.status_code == 200
            return

    assert len(content) > 50, f"RIS content too short: {len(content)} bytes"

    # Check for RIS format markers
    assert "TY  -" in content, "No RIS type marker found"
    assert "ER  -" in content, "No RIS end record marker found"

    print(f"✓ RIS export successful - {len(content)} bytes")


if __name__ == "__main__":
    # Run specific test if needed
    import pytest

    pytest.main([__file__, "-v", "-s"])
