from analogai.deepthink.infrastructure.gateways.llm.gateway import LlmGateway
from analogai.deepthink.infrastructure.gateways.llm.llm_gateway_provider_factory import LlmGatewayProviderFactory
from analogai.deepthink.infrastructure.gateways.llm.enums.llm_provider import LlmProvider
from analogai.deepthink.infrastructure.prompts.builders.sentence_transformer_prompt_builder import (
    build_sentence_transformer_prompt,
)
from analogai.foundation.settings import config as app_config


def _resolve_provider(value: str | LlmProvider | None) -> LlmProvider | None:
    if value is None:
        return None
    if isinstance(value, LlmProvider):
        return value
    normalized = str(value).strip().lower().replace("-", "_")
    if not normalized:
        return None
    legacy_map = {
        "claude": LlmProvider.ANTHROPIC,
        "azureopenai": LlmProvider.AZURE_OPENAI,
        "xai": LlmProvider.XAI,
    }
    if normalized in legacy_map:
        return legacy_map[normalized]
    return LlmProvider(normalized)

def _load_notion_enrichment_prompt() -> str:
    from analogai.deepthink.features.notion_enrichment.prompt_loader import load_notion_enrichment_prompt
    return load_notion_enrichment_prompt()


def _configure_gateway_instance(
    gateway: LlmGateway,
    system_prompt: str,
) -> LlmGateway:
    gateway.set_system_prompt(system_prompt)
    return gateway


class EnabledLlmStrategy:

    def create_sentence_transformer(
        self,
        gateway_type: LlmProvider,
        gateway_instance: LlmGateway | None,
    ) -> LlmGateway:
        prompt = build_sentence_transformer_prompt()
        override_provider = _resolve_provider(
            app_config.get(
                "llm.preprocessing.provider",
                app_config.get("llm.sentence_transformer.provider"),
            )
        )
        override_model = app_config.get(
            "llm.preprocessing.model",
            app_config.get("llm.sentence_transformer.model"),
        )
        override_max_tokens = app_config.get(
            "llm.preprocessing.max_tokens",
            app_config.get("llm.sentence_transformer.max_tokens", 500),
        )
        if override_provider or override_model:
            return LlmGatewayProviderFactory.create_gateway(
                gateway_type=override_provider or gateway_type,
                model=override_model or None,
                system_prompt=prompt,
                max_tokens=override_max_tokens,
            )
        if gateway_instance is not None:
            return _configure_gateway_instance(gateway_instance, prompt)
        return LlmGatewayProviderFactory.create_gateway(
            gateway_type=gateway_type,
            system_prompt=prompt,
            max_tokens=override_max_tokens,
        )

    def create_notion_enrichment(
        self,
        gateway_type: LlmProvider,
        gateway_instance: LlmGateway | None,
    ) -> LlmGateway:
        prompt = _load_notion_enrichment_prompt()
        if gateway_instance is not None:
            return _configure_gateway_instance(gateway_instance, prompt)
        return LlmGatewayProviderFactory.create_gateway(
            gateway_type=gateway_type,
            system_prompt=prompt,
            max_tokens=500,
        )


class LlmGatewayFactory:
    _enabled_strategy = EnabledLlmStrategy()
    _default_gateway_type: LlmProvider | None = None
    _default_gateway_instance: LlmGateway | None = None

    @staticmethod
    def set_default_gateway_type(gateway_type: LlmProvider) -> None:
        LlmGatewayFactory._default_gateway_type = gateway_type

    @staticmethod
    def set_default_gateway_instance(gateway: LlmGateway | None) -> None:
        LlmGatewayFactory._default_gateway_instance = gateway

    @staticmethod
    def _get_gateway_type() -> LlmProvider:
        return (
            LlmGatewayFactory._default_gateway_type
            or LlmGatewayProviderFactory.get_default_gateway_type()
        )

    @staticmethod
    def _get_gateway_instance() -> LlmGateway | None:
        return LlmGatewayFactory._default_gateway_instance

    @staticmethod
    def _get_strategy():
        return LlmGatewayFactory._enabled_strategy

    @staticmethod
    def create_sentence_decomposer_and_transformer() -> LlmGateway:
        strategy = LlmGatewayFactory._get_strategy()
        gateway_type = LlmGatewayFactory._get_gateway_type()
        gateway_instance = LlmGatewayFactory._get_gateway_instance()
        return strategy.create_sentence_transformer(gateway_type, gateway_instance)

    @staticmethod
    def create_notion_enrichment() -> LlmGateway:
        strategy = LlmGatewayFactory._get_strategy()
        gateway_type = LlmGatewayFactory._get_gateway_type()
        gateway_instance = LlmGatewayFactory._get_gateway_instance()
        return strategy.create_notion_enrichment(gateway_type, gateway_instance)
