"""
Test candidate exploration classes.
"""

import pytest
from loguru import logger
from unittest.mock import Mock


class TestExplorerImports:
    """Test that explorer classes can be imported."""

    def test_base_explorer_import(self):
        """Test BaseCandidateExplorer import."""
        from local_deep_research.advanced_search_system.candidate_exploration.base_explorer import (
            BaseCandidateExplorer,
            ExplorationStrategy,
            ExplorationResult,
        )

        assert BaseCandidateExplorer is not None
        assert ExplorationStrategy is not None
        assert ExplorationResult is not None

    def test_adaptive_explorer_import(self):
        """Test AdaptiveExplorer import."""
        try:
            from local_deep_research.advanced_search_system.candidate_exploration.adaptive_explorer import (
                AdaptiveExplorer,
            )

            assert AdaptiveExplorer is not None
        except ImportError as e:
            pytest.skip(f"AdaptiveExplorer not available: {e}")

    def test_constraint_guided_explorer_import(self):
        """Test ConstraintGuidedExplorer import."""
        try:
            from local_deep_research.advanced_search_system.candidate_exploration.constraint_guided_explorer import (
                ConstraintGuidedExplorer,
            )

            assert ConstraintGuidedExplorer is not None
        except ImportError as e:
            pytest.skip(f"ConstraintGuidedExplorer not available: {e}")

    def test_diversity_explorer_import(self):
        """Test DiversityExplorer import."""
        try:
            from local_deep_research.advanced_search_system.candidate_exploration.diversity_explorer import (
                DiversityExplorer,
            )

            assert DiversityExplorer is not None
        except ImportError as e:
            pytest.skip(f"DiversityExplorer not available: {e}")

    def test_parallel_explorer_import(self):
        """Test ParallelExplorer import."""
        try:
            from local_deep_research.advanced_search_system.candidate_exploration.parallel_explorer import (
                ParallelExplorer,
            )

            assert ParallelExplorer is not None
        except ImportError as e:
            pytest.skip(f"ParallelExplorer not available: {e}")

    def test_progressive_explorer_import(self):
        """Test ProgressiveExplorer import."""
        try:
            from local_deep_research.advanced_search_system.candidate_exploration.progressive_explorer import (
                ProgressiveExplorer,
            )

            assert ProgressiveExplorer is not None
        except ImportError as e:
            pytest.skip(f"ProgressiveExplorer not available: {e}")


class TestExplorationStrategy:
    """Test ExplorationStrategy enum."""

    def test_strategy_values_exist(self):
        """Test that common strategy values exist."""
        from local_deep_research.advanced_search_system.candidate_exploration.base_explorer import (
            ExplorationStrategy,
        )

        assert ExplorationStrategy.BREADTH_FIRST is not None
        assert ExplorationStrategy.DEPTH_FIRST is not None
        assert ExplorationStrategy.CONSTRAINT_GUIDED is not None
        assert ExplorationStrategy.DIVERSITY_FOCUSED is not None
        assert ExplorationStrategy.ADAPTIVE is not None

    def test_strategy_string_values(self):
        """Test that strategies have string values."""
        from local_deep_research.advanced_search_system.candidate_exploration.base_explorer import (
            ExplorationStrategy,
        )

        assert ExplorationStrategy.BREADTH_FIRST.value == "breadth_first"
        assert ExplorationStrategy.DEPTH_FIRST.value == "depth_first"


class TestExplorationResult:
    """Test ExplorationResult dataclass."""

    def test_result_creation(self):
        """Test ExplorationResult creation."""
        from local_deep_research.advanced_search_system.candidate_exploration.base_explorer import (
            ExplorationResult,
            ExplorationStrategy,
        )
        from local_deep_research.advanced_search_system.candidates.base_candidate import (
            Candidate,
        )

        result = ExplorationResult(
            candidates=[Candidate(name="Test")],
            total_searched=10,
            unique_candidates=1,
            exploration_paths=["query1", "query2"],
            metadata={"test": "data"},
            elapsed_time=5.5,
            strategy_used=ExplorationStrategy.ADAPTIVE,
        )

        assert len(result.candidates) == 1
        assert result.total_searched == 10
        assert result.unique_candidates == 1
        assert len(result.exploration_paths) == 2
        assert result.elapsed_time == 5.5


class TestAdaptiveExplorer:
    """Test AdaptiveExplorer functionality."""

    def test_instantiation(self, mock_llm):
        """Test that AdaptiveExplorer can be instantiated."""
        try:
            from local_deep_research.advanced_search_system.candidate_exploration.adaptive_explorer import (
                AdaptiveExplorer,
            )

            mock_search = Mock()
            mock_search.run = Mock(return_value=[])

            explorer = AdaptiveExplorer(
                model=mock_llm,
                search_engine=mock_search,
                max_candidates=10,
                max_search_time=30.0,
            )

            assert explorer is not None
            assert explorer.model == mock_llm
            assert explorer.max_candidates == 10
            logger.info("AdaptiveExplorer instantiated successfully")

        except ImportError as e:
            pytest.skip(f"AdaptiveExplorer not available: {e}")

    def test_explore_basic(self, mock_llm):
        """Test basic exploration."""
        try:
            from local_deep_research.advanced_search_system.candidate_exploration.adaptive_explorer import (
                AdaptiveExplorer,
            )

            mock_search = Mock()
            mock_search.run = Mock(
                return_value=[
                    {
                        "title": "Result 1",
                        "snippet": "Test content about entity X",
                    },
                    {
                        "title": "Result 2",
                        "snippet": "More content about entity Y",
                    },
                ]
            )

            explorer = AdaptiveExplorer(
                model=mock_llm,
                search_engine=mock_search,
                max_candidates=5,
                max_search_time=10.0,
            )

            result = explorer.explore("Find test entities")

            assert result is not None
            assert hasattr(result, "candidates")
            assert hasattr(result, "total_searched")
            logger.info(
                f"Exploration found {len(result.candidates)} candidates"
            )

        except ImportError as e:
            pytest.skip(f"AdaptiveExplorer not available: {e}")
        except Exception as e:
            logger.warning(f"Exploration failed: {e}")
            pytest.skip(f"Exploration has issues: {e}")


class TestConstraintGuidedExplorer:
    """Test ConstraintGuidedExplorer functionality."""

    def test_instantiation(self, mock_llm):
        """Test instantiation."""
        try:
            from local_deep_research.advanced_search_system.candidate_exploration.constraint_guided_explorer import (
                ConstraintGuidedExplorer,
            )

            mock_search = Mock()
            mock_search.run = Mock(return_value=[])

            explorer = ConstraintGuidedExplorer(
                model=mock_llm,
                search_engine=mock_search,
            )

            assert explorer is not None
            logger.info("ConstraintGuidedExplorer instantiated")

        except ImportError as e:
            pytest.skip(f"ConstraintGuidedExplorer not available: {e}")

    def test_explore_with_constraints(self, mock_llm):
        """Test exploration with constraints."""
        try:
            from local_deep_research.advanced_search_system.candidate_exploration.constraint_guided_explorer import (
                ConstraintGuidedExplorer,
            )
            from local_deep_research.advanced_search_system.constraints.base_constraint import (
                Constraint,
                ConstraintType,
            )

            mock_search = Mock()
            mock_search.run = Mock(
                return_value=[
                    {"title": "Result", "snippet": "Content"},
                ]
            )

            explorer = ConstraintGuidedExplorer(
                model=mock_llm,
                search_engine=mock_search,
                max_candidates=5,
                max_search_time=10.0,
            )

            constraints = [
                Constraint(
                    value="Must be recent",
                    type=ConstraintType.TEMPORAL,
                    weight=1.0,
                ),
            ]

            result = explorer.explore("Find entity", constraints=constraints)

            assert result is not None
            logger.info("Constraint-guided exploration completed")

        except ImportError as e:
            pytest.skip(f"Required classes not available: {e}")
        except Exception as e:
            logger.warning(f"Test failed: {e}")
            pytest.skip(f"Test has issues: {e}")


class TestDiversityExplorer:
    """Test DiversityExplorer functionality."""

    def test_instantiation(self, mock_llm):
        """Test instantiation."""
        try:
            from local_deep_research.advanced_search_system.candidate_exploration.diversity_explorer import (
                DiversityExplorer,
            )

            mock_search = Mock()
            mock_search.run = Mock(return_value=[])

            explorer = DiversityExplorer(
                model=mock_llm,
                search_engine=mock_search,
            )

            assert explorer is not None
            logger.info("DiversityExplorer instantiated")

        except ImportError as e:
            pytest.skip(f"DiversityExplorer not available: {e}")


class TestProgressiveExplorer:
    """Test ProgressiveExplorer functionality."""

    def test_instantiation(self, mock_llm):
        """Test instantiation."""
        try:
            from local_deep_research.advanced_search_system.candidate_exploration.progressive_explorer import (
                ProgressiveExplorer,
            )

            mock_search = Mock()
            mock_search.run = Mock(return_value=[])

            explorer = ProgressiveExplorer(
                model=mock_llm,
                search_engine=mock_search,
            )

            assert explorer is not None
            logger.info("ProgressiveExplorer instantiated")

        except ImportError as e:
            pytest.skip(f"ProgressiveExplorer not available: {e}")


class TestParallelExplorer:
    """Test ParallelExplorer functionality."""

    def test_instantiation(self, mock_llm):
        """Test instantiation."""
        try:
            from local_deep_research.advanced_search_system.candidate_exploration.parallel_explorer import (
                ParallelExplorer,
            )

            mock_search = Mock()
            mock_search.run = Mock(return_value=[])

            explorer = ParallelExplorer(
                model=mock_llm,
                search_engine=mock_search,
            )

            assert explorer is not None
            logger.info("ParallelExplorer instantiated")

        except ImportError as e:
            pytest.skip(f"ParallelExplorer not available: {e}")


class TestExplorerHelperMethods:
    """Test explorer helper methods."""

    def test_should_continue_exploration(self, mock_llm):
        """Test _should_continue_exploration method."""
        try:
            from local_deep_research.advanced_search_system.candidate_exploration.adaptive_explorer import (
                AdaptiveExplorer,
            )
            import time

            mock_search = Mock()
            explorer = AdaptiveExplorer(
                model=mock_llm,
                search_engine=mock_search,
                max_candidates=10,
                max_search_time=5.0,
            )

            start_time = time.time()

            # Should continue with few candidates and fresh start
            assert explorer._should_continue_exploration(start_time, 2) is True

            # Should stop when candidate limit reached
            assert (
                explorer._should_continue_exploration(start_time, 15) is False
            )

        except ImportError as e:
            pytest.skip(f"AdaptiveExplorer not available: {e}")

    def test_deduplicate_candidates(self, mock_llm):
        """Test _deduplicate_candidates method."""
        try:
            from local_deep_research.advanced_search_system.candidate_exploration.adaptive_explorer import (
                AdaptiveExplorer,
            )
            from local_deep_research.advanced_search_system.candidates.base_candidate import (
                Candidate,
            )

            mock_search = Mock()
            explorer = AdaptiveExplorer(
                model=mock_llm,
                search_engine=mock_search,
            )

            candidates = [
                Candidate(name="Entity A"),
                Candidate(name="Entity B"),
                Candidate(name="entity a"),  # Duplicate (case insensitive)
                Candidate(name="Entity C"),
            ]

            unique = explorer._deduplicate_candidates(candidates)

            # Should remove the duplicate
            assert len(unique) == 3
            logger.info(f"Deduplication: {len(candidates)} -> {len(unique)}")

        except ImportError as e:
            pytest.skip(f"Required classes not available: {e}")

    def test_execute_search(self, mock_llm):
        """Test _execute_search method."""
        try:
            from local_deep_research.advanced_search_system.candidate_exploration.adaptive_explorer import (
                AdaptiveExplorer,
            )

            mock_search = Mock()
            mock_search.run = Mock(
                return_value=[
                    {"title": "Result 1", "snippet": "Content 1"},
                    {"title": "Result 2", "snippet": "Content 2"},
                ]
            )

            explorer = AdaptiveExplorer(
                model=mock_llm,
                search_engine=mock_search,
            )

            result = explorer._execute_search("test query")

            assert result is not None
            assert "results" in result
            assert len(result["results"]) == 2
            assert "test query" in explorer.explored_queries

        except ImportError as e:
            pytest.skip(f"AdaptiveExplorer not available: {e}")

    def test_execute_search_handles_errors(self, mock_llm):
        """Test that _execute_search handles errors gracefully."""
        try:
            from local_deep_research.advanced_search_system.candidate_exploration.adaptive_explorer import (
                AdaptiveExplorer,
            )

            mock_search = Mock()
            mock_search.run = Mock(side_effect=Exception("Search error"))

            explorer = AdaptiveExplorer(
                model=mock_llm,
                search_engine=mock_search,
            )

            result = explorer._execute_search("test query")

            # Should handle error gracefully
            assert result is not None
            assert "results" in result
            assert len(result["results"]) == 0

        except ImportError as e:
            pytest.skip(f"AdaptiveExplorer not available: {e}")
