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.settings import config as app_config
from pathlib import Path


# Grammar correction is currently disabled.
# def _load_grammar_prompt() -> str:
#     prompts_dir = Path(__file__).resolve().parents[2] / "prompts"
#     prompt_path = prompts_dir / "grammar_prompt.txt"
#     if not prompt_path.exists():
#         raise FileNotFoundError(f"Prompt file not found: {prompt_path}")
#     with open(prompt_path, 'r', encoding='utf-8') as f:
#         return f.read()


def _load_sentence_transformer_prompt_template() -> str:
    prompts_dir = Path(__file__).resolve().parents[2] / "prompts"
    prompt_path = prompts_dir / "sentence_transformer_prompt.txt"
    if not prompt_path.exists():
        raise FileNotFoundError(f"Prompt file not found: {prompt_path}")
    return prompt_path.read_text(encoding="utf-8")


def _build_sentence_transformer_prompt() -> str:
    from analogai.deepthink.infrastructure.gateways.llm.providers.sentence_transformer_examples import get_enhanced_system_prompt
    from analogai.foundation.common.enums import RelationshipType

    relationship_list = "\n".join([f"  - {rel_type.value}" for rel_type in RelationshipType])

    if app_config.get("app.features.time_sensitive_transformations", False):
        time_field_description = '"today|tomorrow|yesterday|now|currently|right now|...",  // string (optional) - temporal modifier, MUST specify for time-sensitive statements'
    else:
        time_field_description = '"today|tomorrow|yesterday|...",      // string (optional) - temporal modifier'

    time_specification_section = ""
    time_examples_section = ""

    if app_config.get("app.features.time_sensitive_transformations", False):
        time_specification_section = """
TIME SPECIFICATION: For time-sensitive statements, ALWAYS specify a time modifier:
  - Weather, traffic, status conditions → "now" or "right now" or "currently"
    Examples: "There is rain in Paris" → time: "now"
              "The shop is open" → time: "currently"
  - Stock prices, market moves, crypto → "today" or "this week"
    Examples: "Nvidia stock has risen" → time: "today"
              "Bitcoin is volatile" → time: "this week"
  - Sports scores, live events → "right now" or "live" or "currently"
    Examples: "PSG is winning" → time: "right now"
              "The match is ongoing" → time: "currently"
  - Immediate/urgent situations → "right now" or "now"
    Examples: "Someone is knocking" → time: "right now"
              "The alarm is ringing" → time: "now"
  
  Time-sensitive categories requiring time specification:
  • Current weather conditions (rain, snow, temperature, etc.)
  • Traffic or transit status
  • Business status (open/closed, busy, available)
  • Live sports scores and events
  • Financial market data (stock prices, crypto, forex)
  • Immediate actions or events happening at this moment
  • Status of services or systems

"""
    time_examples_section = """
═══════════════════════════════════════════════════════════════════
TIME-SENSITIVE STATEMENT EXAMPLES
═══════════════════════════════════════════════════════════════════

WEATHER CONDITIONS:
"There is rain in Paris" → {{"intent_type": "making_statement", "subject": "rain", "relationship_phrase": "exists in", "object": "paris", "location": "paris", "time": "now", "probability": 1.0}}
"It is snowing in London" → {{"intent_type": "making_statement", "subject": "snow", "relationship_phrase": "is happening in", "object": "london", "location": "london", "time": "now", "probability": 1.0}}

BUSINESS STATUS:
"The shop is open" → {{"intent_type": "making_statement", "subject": "shop", "relationship_phrase": "is", "object": "open", "time": "currently", "probability": 1.0}}
"The restaurant is busy" → {{"intent_type": "making_statement", "subject": "restaurant", "relationship_phrase": "is", "object": "busy", "time": "currently", "probability": 1.0}}

FINANCIAL MARKETS:
"Nvidia stock has risen" → {{"intent_type": "making_statement", "subject": "nvidia stock", "relationship_phrase": "has", "object": "risen", "time": "today", "probability": 1.0}}
"Bitcoin is volatile" → {{"intent_type": "making_statement", "subject": "bitcoin", "relationship_phrase": "is", "object": "volatile", "time": "this week", "probability": 1.0}}

LIVE SPORTS:
"PSG is winning" → {{"intent_type": "making_statement", "subject": "psg", "relationship_phrase": "is", "object": "winning", "time": "right now", "probability": 1.0}}
"The match is ongoing" → {{"intent_type": "making_statement", "subject": "match", "relationship_phrase": "is", "object": "ongoing", "time": "currently", "probability": 1.0}}

IMMEDIATE EVENTS:
"Someone is knocking" → {{"intent_type": "making_statement", "subject": "someone", "relationship_phrase": "is", "object": "knocking", "time": "right now", "probability": 1.0}}
"The alarm is ringing" → {{"intent_type": "making_statement", "subject": "alarm", "relationship_phrase": "is", "object": "ringing", "time": "now", "probability": 1.0}}

"""

    base_template = _load_sentence_transformer_prompt_template()
    base_instructions = (
        base_template
        .replace("__RELATIONSHIP_LIST__", relationship_list)
        .replace("__TIME_FIELD_DESCRIPTION__", time_field_description)
        .replace("__TIME_SPECIFICATION_SECTION__", time_specification_section)
        .replace("__TIME_EXAMPLES_SECTION__", time_examples_section)
    )

    return get_enhanced_system_prompt(base_instructions, num_examples=15)


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()
        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,
        )

    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)
