from __future__ import annotations

from typing import Optional

from analogai.foundation.settings import config as infra_config
from analogai.deepthink.infrastructure.gateways.llm.gateway import LlmGateway
from analogai.foundation.common.logging.app_logger import app_logger
from analogai.deepthink.infrastructure.gateways.llm.llm_gateway_provider_factory import LlmGatewayProviderFactory
from analogai.deepthink.messaging.question_answering.qa_synthesizer_prompt_composer import (
    QASynthesizerPromptComposer,
)
from analogai.deepthink.messaging.question_answering.question_answering_service import (
    QuestionAnsweringService,
)
from analogai.deepthink.messaging.question_answering.adapters.fact_search_adapter import FactSearchAdapter
from analogai.deepthink.messaging.fact.enums.fact_search_mode import FactSearchMode


def create_question_answering_service(
    domain_service_factory,
    llm_gateway_instance: Optional[LlmGateway] = None,
    fact_context_assembler=None,
    fact_context_service=None,
    fact_service=None,
) -> QuestionAnsweringService:
    fact_similarity_cutoff = infra_config.get(
        "FACT_SIMILARITY_CUTOFF",
        infra_config.get("vector.cutoff", 0.25),
    )
    use_vector_search = bool(
        infra_config.get(
            "USE_VECTOR_SEARCH",
            infra_config.get("vector.enabled", True),
        )
    )
    search_mode = (
        FactSearchMode.VECTOR_THEN_TEXT
        if use_vector_search
        else FactSearchMode.TEXT_ONLY
    )
    belief_service = domain_service_factory.get_belief_service()
    notion_service = domain_service_factory.get_notion_service()
    fact_retriever = None
    if fact_service is not None:
        fact_retriever = FactSearchAdapter(
            fact_service=fact_service,
            top_k=5,
            similarity_cutoff=fact_similarity_cutoff,
            search_mode=search_mode,
        )
    retriever_label = type(fact_retriever).__name__ if fact_retriever is not None else "none"
    app_logger.debug(
        "[QA Factory] fact_retriever=%s",
        retriever_label,
    )
    prompt_builder = QASynthesizerPromptComposer()
    system_prompt = prompt_builder.build_system_prompt()

    if llm_gateway_instance is not None:
        llm_gateway_instance.set_system_prompt(system_prompt)
        llm_gateway = llm_gateway_instance
    else:
        llm_gateway = LlmGatewayProviderFactory.create_gateway(
            system_prompt=system_prompt,
            max_tokens=300,
        )

    synthesizer_gateway = LlmGatewayProviderFactory.create_gateway(
        system_prompt="",
        max_tokens=200,
    )

    return QuestionAnsweringService(
        belief_service=belief_service,
        notion_service=notion_service,
        llm_gateway=llm_gateway,
        synthesizer_gateway=synthesizer_gateway,
        fact_context_assembler=fact_context_assembler,
        fact_context_service=fact_context_service,
        prompt_builder=prompt_builder,
        fact_retriever=fact_retriever,
    )
