"""Shared fixtures for web services tests."""

import pytest
from unittest.mock import Mock, MagicMock, patch


@pytest.fixture(autouse=True)
def _allow_socket_subscribe():
    """Mock the chat-mode socket-subscribe ownership check.

    See the matching conftest in ``tests/web/services/conftest.py`` for
    full context. Pre-existing socket tests in this directory don't set
    up a Flask request context, so without this autouse fixture the new
    ``session.get("username")`` lookup in ``__handle_subscribe`` raises
    ``RuntimeError: Working outside of request context``.

    Tests in this directory import via ``local_deep_research.web...``
    (no ``src.`` prefix). Patch BOTH paths because Python may treat the
    two import paths as distinct module identities depending on how the
    package is installed.
    """
    # Resolve the module from whichever path is importable.
    try:
        from local_deep_research.web.services.socket_service import (
            SocketIOService,
        )

        module_path = "local_deep_research.web.services.socket_service"
    except ImportError:
        from src.local_deep_research.web.services.socket_service import (
            SocketIOService,
        )

        module_path = "src.local_deep_research.web.services.socket_service"

    with (
        patch(f"{module_path}.session", {"username": "test-owner"}),
        patch.object(SocketIOService, "_user_owns_research", return_value=True),
    ):
        yield


@pytest.fixture
def sample_markdown():
    """Sample markdown content for testing."""
    return """# Test Document

This is a test document with **bold** and *italic* text.

## Section 1

A paragraph with some content.

| Column 1 | Column 2 |
|----------|----------|
| Data 1   | Data 2   |

## Section 2

- Item 1
- Item 2
- Item 3

```python
def example():
    return "code block"
```
"""


@pytest.fixture
def simple_markdown():
    """Minimal markdown for basic tests."""
    return "# Hello World\n\nThis is a test."


@pytest.fixture
def markdown_with_special_chars():
    """Markdown with special characters."""
    return """# Special Characters

Testing: <>&"'
Unicode: café, naïve, 日本語
Symbols: © ® ™ € £ ¥
"""


@pytest.fixture
def sample_metadata():
    """Sample metadata for PDF generation."""
    return {
        "author": "Test Author",
        "date": "2024-01-15",
        "subject": "Test Subject",
    }


@pytest.fixture
def custom_css():
    """Custom CSS for PDF styling."""
    return """
    body {
        font-family: 'Times New Roman', serif;
        font-size: 12pt;
    }
    h1 {
        color: navy;
    }
    """


@pytest.fixture
def valid_pdf_bytes():
    """Generate valid minimal PDF bytes for testing extraction."""
    # This is a minimal valid PDF structure
    pdf_content = b"""%PDF-1.4
1 0 obj
<< /Type /Catalog /Pages 2 0 R >>
endobj
2 0 obj
<< /Type /Pages /Kids [3 0 R] /Count 1 >>
endobj
3 0 obj
<< /Type /Page /Parent 2 0 R /MediaBox [0 0 612 792]
   /Contents 4 0 R /Resources << /Font << /F1 5 0 R >> >> >>
endobj
4 0 obj
<< /Length 44 >>
stream
BT /F1 12 Tf 100 700 Td (Hello World) Tj ET
endstream
endobj
5 0 obj
<< /Type /Font /Subtype /Type1 /BaseFont /Helvetica >>
endobj
xref
0 6
0000000000 65535 f
0000000009 00000 n
0000000058 00000 n
0000000115 00000 n
0000000266 00000 n
0000000359 00000 n
trailer
<< /Size 6 /Root 1 0 R >>
startxref
434
%%EOF"""
    return pdf_content


@pytest.fixture
def invalid_pdf_bytes():
    """Invalid/corrupted PDF bytes."""
    return b"This is not a valid PDF file"


@pytest.fixture
def empty_file_bytes():
    """Empty file bytes."""
    return b""


@pytest.fixture
def mock_flask_app():
    """Mock Flask app for socket service testing."""
    app = Mock()
    app.config = {}
    return app


@pytest.fixture
def mock_socketio():
    """Mock SocketIO instance."""
    socketio = Mock()
    socketio.emit = Mock(return_value=None)
    socketio.on = Mock(return_value=lambda f: f)
    socketio.on_error = Mock(return_value=lambda f: f)
    socketio.on_error_default = Mock(return_value=lambda f: f)
    socketio.run = Mock()
    return socketio


@pytest.fixture
def mock_request():
    """Mock Flask request object."""
    request = Mock()
    request.sid = "test-session-id-123"
    return request


@pytest.fixture
def sample_research_id():
    """Sample research ID for testing."""
    return "research-abc-123"


@pytest.fixture
def sample_sources():
    """Sample sources for research sources service."""
    return [
        {
            "title": "Source 1",
            "url": "https://example.com/source1",
            "snippet": "This is the first source snippet.",
            "full_content": "Full content of source 1.",
        },
        {
            "link": "https://example.com/source2",  # Alternative key
            "name": "Source 2",  # Alternative key
            "snippet": "Second source snippet.",
        },
        {
            "title": "Source 3",
            "url": "https://example.com/source3",
            "snippet": "Third source with a very long snippet that should be truncated "
            * 50,
        },
    ]


@pytest.fixture
def mock_db_session():
    """Mock database session."""
    session = MagicMock()
    session.__enter__ = Mock(return_value=session)
    session.__exit__ = Mock(return_value=False)
    return session


@pytest.fixture
def mock_research_resource():
    """Mock ResearchResource model instance."""
    resource = Mock()
    resource.id = 1
    resource.research_id = "research-abc-123"
    resource.title = "Test Resource"
    resource.url = "https://example.com/resource"
    resource.content_preview = "Preview content"
    resource.source_type = "web"
    resource.resource_metadata = {"key": "value"}
    return resource
