from __future__ import annotations

from typing import Optional

from analogai.deepthink.infrastructure.gateways.llm.gateway import LlmGateway
from analogai.deepthink.infrastructure.gateways.llm.llm_gateway_provider_factory import LlmGatewayProviderFactory
from analogai.deepthink.startup.extensions_service_factory import ExtensionsServiceFactory
from analogai.deepthink.features.question_answering.question_prompt_builder import QuestionPromptBuilder
from analogai.deepthink.features.question_answering.question_answering_service import QuestionAnsweringService
import analogai.deepthink.config as app_config


def create_question_answering_service(
    domain_service_factory,
    llm_gateway_instance: Optional[LlmGateway] = None,
    similarity_cutoff: Optional[float] = None,
) -> QuestionAnsweringService:
    if similarity_cutoff is None:
        similarity_cutoff = app_config.SIMILARITY_CUTOFF
    use_vector_search = app_config.USE_VECTOR_SEARCH
    belief_query_service = ExtensionsServiceFactory(domain_service_factory).get_belief_query_service()
    notion_service = domain_service_factory.get_notion_service()
    prompt_builder = QuestionPromptBuilder()
    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_query_service=belief_query_service,
        notion_service=notion_service,
        llm_gateway=llm_gateway,
        synthesizer_gateway=synthesizer_gateway,
        prompt_builder=prompt_builder,
        max_entity_depth=app_config.QUESTION_ANSWERING_MAX_ENTITY_DEPTH,
        similarity_cutoff=similarity_cutoff,
        use_vector_search=use_vector_search,
    )
