"""
Fixtures for search engine tests.
"""

import pytest
from unittest.mock import Mock


@pytest.fixture
def mock_settings_snapshot():
    """Create a mock settings snapshot for testing."""
    return {
        "rate_limiting.enabled": {"value": True, "ui_element": "checkbox"},
        "rate_limiting.profile": {
            "value": "balanced",
            "ui_element": "dropdown",
        },
        "rate_limiting.memory_window": {"value": 100, "ui_element": "number"},
        "rate_limiting.exploration_rate": {
            "value": 0.1,
            "ui_element": "number",
        },
        "rate_limiting.learning_rate": {"value": 0.3, "ui_element": "number"},
        "rate_limiting.decay_per_day": {"value": 0.95, "ui_element": "number"},
    }


# ============================================================================
# HTTP Response Helpers
# ============================================================================


class MockResponse:
    """Mock HTTP response class for testing."""

    def __init__(
        self, json_data=None, text_data=None, status_code=200, headers=None
    ):
        self._json_data = json_data
        self._text_data = text_data or (str(json_data) if json_data else "")
        self.status_code = status_code
        self.headers = headers or {}
        self.ok = 200 <= status_code < 300

    def json(self):
        if self._json_data is None:
            raise ValueError("No JSON data")
        return self._json_data

    @property
    def text(self):
        return self._text_data

    @property
    def content(self):
        return self._text_data.encode("utf-8")

    def raise_for_status(self):
        if not self.ok:
            from requests.exceptions import HTTPError

            raise HTTPError(f"HTTP {self.status_code}")


@pytest.fixture
def mock_response_factory():
    """Factory for creating mock HTTP responses."""

    def create_response(
        json_data=None, text_data=None, status_code=200, headers=None
    ):
        return MockResponse(json_data, text_data, status_code, headers)

    return create_response


@pytest.fixture
def mock_rate_limit_response(mock_response_factory):
    """Create a mock 429 rate limit response."""
    return mock_response_factory(
        json_data={"error": "Rate limit exceeded"},
        status_code=429,
        headers={"Retry-After": "60"},
    )


@pytest.fixture
def mock_server_error_response(mock_response_factory):
    """Create a mock 500 server error response."""
    return mock_response_factory(
        json_data={"error": "Internal server error"}, status_code=500
    )


@pytest.fixture
def mock_llm():
    """Create a mock LLM for testing."""
    llm = Mock()
    llm.invoke.return_value = Mock(content="Test response")
    return llm


@pytest.fixture
def mock_search_results():
    """Create mock search results."""
    return [
        {
            "title": "Test Result 1",
            "link": "https://example.com/result1",
            "snippet": "This is the first test result snippet.",
            "source": "test_engine",
        },
        {
            "title": "Test Result 2",
            "link": "https://example.com/result2",
            "snippet": "This is the second test result snippet.",
            "source": "test_engine",
        },
    ]


@pytest.fixture
def mock_wikipedia_response():
    """Create mock Wikipedia response."""
    return {
        "title": "Test Article",
        "summary": "This is a test article summary from Wikipedia.",
        "url": "https://en.wikipedia.org/wiki/Test_Article",
    }


@pytest.fixture
def mock_arxiv_paper():
    """Create mock arXiv paper response."""
    return {
        "id": "2301.12345",
        "title": "A Test Paper on Machine Learning",
        "authors": ["John Doe", "Jane Smith"],
        "summary": "This paper presents a novel approach to machine learning.",
        "pdf_url": "https://arxiv.org/pdf/2301.12345.pdf",
        "published": "2023-01-15",
    }


@pytest.fixture
def mock_pubmed_article():
    """Create mock PubMed article response."""
    return {
        "pmid": "12345678",
        "title": "A Clinical Study on Treatment Efficacy",
        "authors": ["Dr. Smith", "Dr. Jones"],
        "abstract": "This study examines the efficacy of a novel treatment.",
        "journal": "Journal of Medical Research",
        "pub_date": "2023-06-01",
    }


@pytest.fixture
def mock_http_session():
    """Create a mock HTTP session for testing."""
    session = Mock()
    response = Mock()
    response.status_code = 200
    response.json.return_value = {"results": []}
    response.text = '{"results": []}'
    session.get.return_value = response
    session.post.return_value = response
    return session


# ============================================================================
# PubMed-specific fixtures
# ============================================================================


@pytest.fixture
def mock_pubmed_esearch_response():
    """Mock PubMed ESearch API response."""
    return MockResponse(
        json_data={
            "esearchresult": {
                "count": "2",
                "retmax": "10",
                "retstart": "0",
                "idlist": ["12345678", "87654321"],
                "translationstack": [],
                "querytranslation": "machine learning[All Fields]",
            }
        }
    )


@pytest.fixture
def mock_pubmed_efetch_xml():
    """Mock PubMed EFetch XML response."""
    return MockResponse(
        text_data="""<?xml version="1.0" ?>
<!DOCTYPE PubmedArticleSet PUBLIC "-//NLM//DTD PubMedArticle, 1st January 2023//EN" "https://dtd.nlm.nih.gov/ncbi/pubmed/out/pubmed_230101.dtd">
<PubmedArticleSet>
    <PubmedArticle>
        <MedlineCitation Status="MEDLINE" Owner="NLM">
            <PMID Version="1">12345678</PMID>
            <Article PubModel="Print">
                <ArticleTitle>Machine Learning in Medicine: A Review</ArticleTitle>
                <Abstract>
                    <AbstractText>This review examines the application of machine learning in medical diagnostics.</AbstractText>
                </Abstract>
                <AuthorList CompleteYN="Y">
                    <Author ValidYN="Y">
                        <LastName>Smith</LastName>
                        <ForeName>John</ForeName>
                    </Author>
                </AuthorList>
            </Article>
        </MedlineCitation>
    </PubmedArticle>
</PubmedArticleSet>"""
    )


# ============================================================================
# ArXiv-specific fixtures
# ============================================================================


@pytest.fixture
def mock_arxiv_atom_response():
    """Mock arXiv Atom feed response."""
    return MockResponse(
        text_data="""<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title type="html">ArXiv Query: search_query=all:machine+learning</title>
  <id>http://arxiv.org/api/test</id>
  <opensearch:totalResults xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/">100</opensearch:totalResults>
  <opensearch:startIndex xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/">0</opensearch:startIndex>
  <entry>
    <id>http://arxiv.org/abs/2301.12345v1</id>
    <title>Deep Learning for Natural Language Processing</title>
    <summary>We present a novel approach to NLP using deep neural networks.</summary>
    <author><name>Jane Doe</name></author>
    <author><name>John Smith</name></author>
    <link href="http://arxiv.org/abs/2301.12345v1" rel="alternate" type="text/html"/>
    <link title="pdf" href="http://arxiv.org/pdf/2301.12345v1" rel="related" type="application/pdf"/>
    <arxiv:primary_category xmlns:arxiv="http://arxiv.org/schemas/atom" term="cs.CL"/>
    <published>2023-01-15T00:00:00Z</published>
  </entry>
</feed>"""
    )


# ============================================================================
# Semantic Scholar-specific fixtures
# ============================================================================


@pytest.fixture
def mock_semantic_scholar_response(mock_response_factory):
    """Mock Semantic Scholar API response."""
    return mock_response_factory(
        json_data={
            "total": 100,
            "offset": 0,
            "data": [
                {
                    "paperId": "abc123",
                    "title": "Advances in Machine Learning",
                    "abstract": "This paper surveys recent advances in machine learning algorithms.",
                    "year": 2023,
                    "citationCount": 150,
                    "authors": [
                        {"authorId": "1", "name": "Alice Johnson"},
                        {"authorId": "2", "name": "Bob Wilson"},
                    ],
                    "url": "https://www.semanticscholar.org/paper/abc123",
                    "externalIds": {"DOI": "10.1234/example"},
                },
                {
                    "paperId": "def456",
                    "title": "Neural Networks: A Comprehensive Guide",
                    "abstract": "A comprehensive guide to neural network architectures.",
                    "year": 2022,
                    "citationCount": 200,
                    "authors": [{"authorId": "3", "name": "Carol Brown"}],
                    "url": "https://www.semanticscholar.org/paper/def456",
                    "externalIds": {"ArXiv": "2201.00001"},
                },
            ],
        }
    )


# ============================================================================
# GitHub-specific fixtures
# ============================================================================


@pytest.fixture
def mock_github_search_response(mock_response_factory):
    """Mock GitHub Search API response."""
    return mock_response_factory(
        json_data={
            "total_count": 50,
            "incomplete_results": False,
            "items": [
                {
                    "id": 1,
                    "name": "awesome-ml",
                    "full_name": "user/awesome-ml",
                    "html_url": "https://github.com/user/awesome-ml",
                    "description": "A curated list of machine learning resources",
                    "stargazers_count": 1500,
                    "language": "Python",
                    "updated_at": "2023-12-01T00:00:00Z",
                },
                {
                    "id": 2,
                    "name": "ml-toolkit",
                    "full_name": "org/ml-toolkit",
                    "html_url": "https://github.com/org/ml-toolkit",
                    "description": "Machine learning toolkit for Python",
                    "stargazers_count": 800,
                    "language": "Python",
                    "updated_at": "2023-11-15T00:00:00Z",
                },
            ],
        }
    )


@pytest.fixture
def mock_github_code_search_response(mock_response_factory):
    """Mock GitHub Code Search API response."""
    return mock_response_factory(
        json_data={
            "total_count": 25,
            "incomplete_results": False,
            "items": [
                {
                    "name": "model.py",
                    "path": "src/model.py",
                    "sha": "abc123",
                    "url": "https://api.github.com/repos/user/repo/contents/src/model.py",
                    "html_url": "https://github.com/user/repo/blob/main/src/model.py",
                    "repository": {
                        "full_name": "user/repo",
                        "html_url": "https://github.com/user/repo",
                    },
                }
            ],
        }
    )


# ============================================================================
# DuckDuckGo-specific fixtures
# ============================================================================


@pytest.fixture
def mock_ddg_response():
    """Mock DuckDuckGo search results (from duckduckgo_search library format)."""
    return [
        {
            "title": "Introduction to Machine Learning | Example Site",
            "href": "https://example.com/ml-intro",
            "body": "A comprehensive introduction to machine learning concepts and algorithms.",
        },
        {
            "title": "Machine Learning Tutorial - Learn ML",
            "href": "https://learn-ml.example.org/tutorial",
            "body": "Step-by-step tutorial on building your first machine learning model.",
        },
        {
            "title": "ML Best Practices",
            "href": "https://blog.example.com/ml-best-practices",
            "body": "Learn the best practices for implementing machine learning in production.",
        },
    ]


# ============================================================================
# Brave Search-specific fixtures
# ============================================================================


@pytest.fixture
def mock_brave_search_response(mock_response_factory):
    """Mock Brave Search API response."""
    return mock_response_factory(
        json_data={
            "type": "search",
            "query": {"original": "machine learning"},
            "web": {
                "results": [
                    {
                        "title": "Machine Learning - Wikipedia",
                        "url": "https://en.wikipedia.org/wiki/Machine_learning",
                        "description": "Machine learning is a branch of artificial intelligence.",
                        "age": "2 days ago",
                    },
                    {
                        "title": "What is Machine Learning? - IBM",
                        "url": "https://www.ibm.com/topics/machine-learning",
                        "description": "Machine learning is a form of AI that enables systems to learn.",
                        "age": "1 week ago",
                    },
                ],
                "count": 2,
            },
        }
    )


# ============================================================================
# Guardian-specific fixtures
# ============================================================================


@pytest.fixture
def mock_guardian_response(mock_response_factory):
    """Mock Guardian API response."""
    return mock_response_factory(
        json_data={
            "response": {
                "status": "ok",
                "total": 100,
                "startIndex": 1,
                "pageSize": 10,
                "currentPage": 1,
                "pages": 10,
                "results": [
                    {
                        "id": "technology/2023/dec/01/ai-article",
                        "type": "article",
                        "webTitle": "AI is transforming the world",
                        "webUrl": "https://www.theguardian.com/technology/2023/dec/01/ai-article",
                        "apiUrl": "https://content.guardianapis.com/technology/2023/dec/01/ai-article",
                        "webPublicationDate": "2023-12-01T10:00:00Z",
                        "sectionName": "Technology",
                    },
                    {
                        "id": "science/2023/nov/28/ml-research",
                        "type": "article",
                        "webTitle": "New machine learning breakthrough",
                        "webUrl": "https://www.theguardian.com/science/2023/nov/28/ml-research",
                        "apiUrl": "https://content.guardianapis.com/science/2023/nov/28/ml-research",
                        "webPublicationDate": "2023-11-28T14:30:00Z",
                        "sectionName": "Science",
                    },
                ],
            }
        }
    )
