"""Tests for retriever integration with LDR API functions."""

from unittest.mock import Mock, patch

from langchain_core.retrievers import BaseRetriever, Document

from local_deep_research.api import (
    detailed_research,
    generate_report,
    quick_summary,
)

# Import retriever_registry from the same module path that the API functions use
# This ensures we're using the same registry instance


class SimpleRetriever(BaseRetriever):
    """Simple retriever for testing API integration."""

    content: str = "Test content"

    class Config:
        """Pydantic config."""

        arbitrary_types_allowed = True

    def _get_relevant_documents(self, query: str):
        return [
            Document(
                page_content=f"{self.content} for query: {query}",
                metadata={"title": f"Result for {query}", "source": "test"},
            )
        ]

    async def _aget_relevant_documents(self, query: str):
        return self._get_relevant_documents(query)


class TestAPIIntegration:
    """Test retriever integration with API functions."""

    def setup_method(self):
        """Clear registry before each test."""
        # Import the registry to ensure we're using the right instance
        from local_deep_research.web_search_engines.retriever_registry import (
            retriever_registry,
        )

        retriever_registry.clear()

    def teardown_method(self):
        """Clear registry after each test."""
        # Import the registry to ensure we're using the right instance
        from local_deep_research.web_search_engines.retriever_registry import (
            retriever_registry,
        )

        retriever_registry.clear()

    @patch("local_deep_research.api.research_functions._init_search_system")
    def test_quick_summary_with_single_retriever(self, mock_init):
        """Test quick_summary with a single retriever."""
        # Mock the search system
        mock_system = Mock()
        mock_system.analyze_topic.return_value = {
            "current_knowledge": "Summary based on retriever content",
            "findings": ["Finding 1", "Finding 2"],
            "iterations": 1,
            "questions": {},
            "all_links_of_system": [],
        }
        mock_init.return_value = mock_system

        # Create and use retriever
        retriever = SimpleRetriever(content="Test content")
        result = quick_summary(
            query="test query",
            retrievers={"test_kb": retriever},
            search_tool="test_kb",
        )

        # Verify result without checking registry state
        # The important thing is that the function works correctly
        assert "summary" in result
        assert result["summary"] == "Summary based on retriever content"

        # Verify that the search system was initialized with correct search_tool
        mock_init.assert_called_once()
        call_kwargs = mock_init.call_args[1]
        assert call_kwargs.get("search_tool") == "test_kb"

    @patch("local_deep_research.api.research_functions._init_search_system")
    def test_quick_summary_with_multiple_retrievers(self, mock_init):
        """Test quick_summary with multiple retrievers."""
        mock_system = Mock()
        mock_system.analyze_topic.return_value = {
            "current_knowledge": "Combined summary",
            "findings": [],
            "iterations": 1,
            "questions": {},
            "all_links_of_system": [],
        }
        mock_init.return_value = mock_system

        # Create multiple retrievers
        retrievers = {
            "kb1": SimpleRetriever(content="Knowledge base 1"),
            "kb2": SimpleRetriever(content="Knowledge base 2"),
            "kb3": SimpleRetriever(content="Knowledge base 3"),
        }

        quick_summary(
            query="multi retriever test",
            retrievers=retrievers,
            search_tool="kb1",
        )

        # Verify that the function works correctly without checking registry state
        # The search_tool="kb1" should work with the registered retrievers
        mock_init.assert_called_once()
        call_kwargs = mock_init.call_args[1]
        assert call_kwargs.get("search_tool") == "kb1"

    @patch("local_deep_research.api.research_functions._init_search_system")
    def test_detailed_research_with_retrievers(self, mock_init):
        """Test detailed_research with retrievers."""
        mock_system = Mock()
        mock_system.analyze_topic.return_value = {
            "current_knowledge": "Detailed analysis",
            "findings": ["Finding 1", "Finding 2", "Finding 3"],
            "iterations": 3,
            "questions": {"iteration_1": ["Q1", "Q2"]},
            "formatted_findings": "Formatted findings",
            "all_links_of_system": ["source1", "source2"],
        }
        mock_init.return_value = mock_system

        retriever = SimpleRetriever(content="Test content")
        result = detailed_research(
            query="detailed test",
            retrievers={"detail_kb": retriever},
            search_tool="detail_kb",
            iterations=3,
        )

        # Verify result structure
        assert result["query"] == "detailed test"
        assert result["summary"] == "Detailed analysis"
        assert len(result["findings"]) == 3
        assert result["metadata"]["search_tool"] == "detail_kb"
        assert result["metadata"]["iterations_requested"] == 3

    @patch("local_deep_research.api.research_functions._init_search_system")
    @patch(
        "local_deep_research.api.research_functions.IntegratedReportGenerator"
    )
    def test_generate_report_with_retrievers(
        self, mock_report_gen_class, mock_init
    ):
        """Test generate_report with retrievers."""
        # Mock system
        mock_system = Mock()
        mock_system.analyze_topic.return_value = {
            "findings": "initial findings"
        }
        mock_init.return_value = mock_system

        # Mock report generator
        mock_report_gen = Mock()
        mock_report_gen.generate_report.return_value = {
            "content": "# Report\nGenerated report content",
            "metadata": {"query": "report test"},
        }
        mock_report_gen_class.return_value = mock_report_gen

        retriever = SimpleRetriever(content="Test content")
        result = generate_report(
            query="report test",
            retrievers={"report_kb": retriever},
            search_tool="report_kb",
        )

        # Verify result without checking registry state
        assert "content" in result
        assert "# Report" in result["content"]

        # Verify that the search system was initialized with correct search_tool
        mock_init.assert_called_once()
        call_kwargs = mock_init.call_args[1]
        assert call_kwargs.get("search_tool") == "report_kb"

    def test_retriever_selection(self):
        """Test selecting specific retriever from multiple."""
        # This test actually runs the retriever to verify selection works
        retrievers = {
            "kb1": SimpleRetriever(content="Content 1"),
            "kb2": SimpleRetriever(content="Content 2"),
            "kb3": SimpleRetriever(content="Content 3"),
        }

        # Register all retrievers
        # Import the registry to ensure we're using the right instance
        from local_deep_research.web_search_engines.retriever_registry import (
            retriever_registry,
        )

        retriever_registry.register_multiple(retrievers)

        # Verify we can get specific retriever
        selected = retriever_registry.get("kb2")
        assert selected == retrievers["kb2"]

        # Verify it returns correct content
        docs = selected.invoke("test")
        assert "Content 2" in docs[0].page_content

    @patch("local_deep_research.api.research_functions._init_search_system")
    def test_research_id_generation(self, mock_init):
        """Test that research_id is generated if not provided."""
        mock_system = Mock()
        mock_system.analyze_topic.return_value = {
            "current_knowledge": "Summary",
            "findings": [],
            "iterations": 1,
            "questions": {},
            "all_links_of_system": [],
        }
        mock_init.return_value = mock_system

        quick_summary(
            query="test", retrievers={"test": SimpleRetriever(content="Test")}
        )

        # Should have generated a research_id (UUID format)
        assert mock_init.called

    def test_empty_retrievers_dict(self):
        """Test handling of empty retrievers dictionary."""
        # Should not crash with empty dict
        with patch(
            "local_deep_research.api.research_functions._init_search_system"
        ) as mock_init:
            mock_system = Mock()
            mock_system.analyze_topic.return_value = {
                "current_knowledge": "Summary",
                "findings": [],
                "iterations": 1,
                "questions": {},
                "all_links_of_system": [],
            }
            mock_init.return_value = mock_system

            quick_summary(
                query="test",
                retrievers={},  # Empty dict
                search_tool="searxng",  # Use regular search engine
            )

            # Verify that the search system was initialized with regular search engine
            mock_init.assert_called_once()
            call_kwargs = mock_init.call_args[1]
            assert call_kwargs.get("search_tool") == "searxng"
