"""
RapidSearch strategy implementation.
"""

from typing import Dict

from loguru import logger

from ...citation_handler import CitationHandler

# Model and search should be provided by AdvancedSearchSystem
from ...utilities.search_utilities import extract_links_from_search_results
from ..findings.repository import FindingsRepository
from ..knowledge.standard_knowledge import StandardKnowledge
from ..questions.standard_question import StandardQuestionGenerator
from .base_strategy import BaseSearchStrategy


class RapidSearchStrategy(BaseSearchStrategy):
    """
    Rapid search strategy that only analyzes snippets and performs
    a single synthesis step at the end, optimized for speed.
    """

    def __init__(
        self,
        search,
        model,
        citation_handler=None,
        all_links_of_system=None,
        settings_snapshot=None,
    ):
        """Initialize with optional dependency injection for testing."""
        super().__init__(
            all_links_of_system=all_links_of_system,
            settings_snapshot=settings_snapshot,
        )
        self.search = search
        self.model = model
        self.progress_callback = None
        # Note: questions_by_iteration is already initialized by parent class

        # Use provided citation_handler or create one
        self.citation_handler = citation_handler or CitationHandler(
            self.model, settings_snapshot=settings_snapshot
        )

        # Initialize components
        self.question_generator = StandardQuestionGenerator(self.model)
        self.knowledge_generator = StandardKnowledge(self.model)
        self.findings_repository = FindingsRepository(self.model)

    def analyze_topic(self, query: str) -> Dict:
        """
        RapidSearch implementation that collects snippets, avoids intermediate
        synthesis, and only performs a final synthesis at the end.
        """
        logger.info(f"Starting rapid research on topic: {query}")

        findings = []
        all_search_results = []
        collected_snippets = []
        section_links = []

        self._update_progress(
            "Initializing rapid research system",
            5,
            {"phase": "init", "strategy": "rapid"},
        )

        # Check if search engine is available
        if not self._validate_search_engine():
            return {
                "findings": [],
                "iterations": 0,
                "questions": {},
                "formatted_findings": "Error: Unable to conduct research without a search engine.",
                "current_knowledge": "",
                "error": "No search engine available",
            }

        # Step 1: Initial search for the main query
        self._update_progress(
            "Performing initial search for main query",
            10,
            {"phase": "search", "iteration": 1},
        )

        try:
            initial_results = self.search.run(query)

            if not initial_results:
                self._update_progress(
                    "No initial results found",
                    15,
                    {"phase": "search_complete", "result_count": 0},
                )
                initial_results = []
            else:
                self._update_progress(
                    f"Found {len(initial_results)} initial results",
                    15,
                    {
                        "phase": "search_complete",
                        "result_count": len(initial_results),
                    },
                )

            # Extract snippets and links
            for result in initial_results:
                if "snippet" in result:
                    collected_snippets.append(
                        {
                            "text": result["snippet"],
                            "source": result.get("title", "Unknown Source"),
                            "link": result.get("link", ""),
                            "query": query,
                        }
                    )

            # Extract and save links
            initial_links = extract_links_from_search_results(initial_results)
            self.all_links_of_system.extend(initial_links)
            section_links.extend(initial_links)
            all_search_results.extend(initial_results)

            # No findings added here - just collecting data

        except Exception:
            logger.exception("SEARCH ERROR: Error during initial search")
            self._update_progress(
                "Error during initial search",
                15,
                {"phase": "search_error", "error": "Search error"},
            )
            initial_results = []

        # Step 2: Generate a few follow-up questions (optional, can be skipped for ultimate speed)
        self._update_progress(
            "Generating follow-up questions",
            25,
            {"phase": "question_generation"},
        )

        questions = self.question_generator.generate_questions(
            current_knowledge="",  # No knowledge accumulation in rapid mode
            query=query,
            questions_per_iteration=3,  # Fewer questions for speed
            questions_by_iteration={},
        )

        self.questions_by_iteration[0] = questions
        logger.info(f"Generated questions: {questions}")

        # Step 3: Process follow-up questions
        question_count = len(questions)
        for q_idx, question in enumerate(questions):
            question_progress = 30 + ((q_idx + 1) / question_count * 40)

            self._update_progress(
                f"Searching for: {question}",
                int(question_progress),
                {"phase": "search", "question_index": q_idx + 1},
            )

            try:
                search_results = self.search.run(question)

                if not search_results:
                    self._update_progress(
                        f"No results found for question: {question}",
                        int(question_progress + 2),
                        {"phase": "search_complete", "result_count": 0},
                    )
                    continue

                self._update_progress(
                    f"Found {len(search_results)} results for question: {question}",
                    int(question_progress + 5),
                    {
                        "phase": "search_complete",
                        "result_count": len(search_results),
                    },
                )

                # Extract snippets only
                for result in search_results:
                    if "snippet" in result:
                        collected_snippets.append(
                            {
                                "text": result["snippet"],
                                "source": result.get("title", "Unknown Source"),
                                "link": result.get("link", ""),
                                "query": question,
                            }
                        )

                # Extract and save links
                links = extract_links_from_search_results(search_results)
                self.all_links_of_system.extend(links)
                section_links.extend(links)
                all_search_results.extend(search_results)

                # No findings added here - just collecting data

            except Exception:
                logger.exception("SEARCH ERROR: Error during search")
                self._update_progress(
                    "Error during search",
                    int(question_progress + 2),
                    {"phase": "search_error", "error": "Search error"},
                )

        # Step 4: Perform a single final synthesis with all collected snippets using the citation handler
        self._update_progress(
            "Synthesizing all collected information",
            80,
            {"phase": "final_synthesis"},
        )

        try:
            # Use citation handler for the final analysis
            # First, we need a stub of current knowledge

            # Use the citation handler to analyze the results
            result = self.citation_handler.analyze_initial(
                query, all_search_results
            )

            if result:
                synthesized_content = result["content"]

                # Create a synthesis finding
                finding = {
                    "phase": "Final synthesis",
                    "content": synthesized_content,
                    "question": query,
                    "search_results": all_search_results,
                    "documents": result.get("documents", []),
                }
                findings.append(finding)

                # Transfer questions to the repository
                self.findings_repository.set_questions_by_iteration(
                    self.questions_by_iteration
                )

                # Format the findings with search questions and sources
                formatted_findings = (
                    self.findings_repository.format_findings_to_text(
                        findings, synthesized_content
                    )
                )

                # Also add to the repository
                self.findings_repository.add_documents(
                    result.get("documents", [])
                )
            else:
                # Fallback if citation handler fails
                synthesized_content = (
                    "Error: Failed to synthesize results with citation handler."
                )
                formatted_findings = synthesized_content
                finding = {
                    "phase": "Error",
                    "content": synthesized_content,
                    "question": query,
                    "search_results": all_search_results,
                    "documents": [],
                }
                findings.append(finding)

        except Exception as e:
            error_msg = f"Error synthesizing final answer: {e!s}"
            logger.exception(error_msg)
            synthesized_content = f"Error generating synthesis: {e!s}"
            formatted_findings = f"Error: {e!s}"
            finding = {
                "phase": "Error",
                "content": synthesized_content,
                "question": query,
                "search_results": all_search_results,
                "documents": [],
            }
            findings.append(finding)

        self._update_progress("Research complete", 100, {"phase": "complete"})

        return {
            "findings": findings,
            "iterations": 1,  # Always 1 iteration in rapid mode
            "questions": self.questions_by_iteration,
            "formatted_findings": formatted_findings,
            "current_knowledge": synthesized_content,
        }
