import json
from pathlib import Path

from analogai.deepthink.infrastructure.prompts.examples.sentence_transformer_examples import (
    get_enhanced_system_prompt,
)
from analogai.foundation.settings import config as app_config


def load_sentence_transformer_template() -> str:
    prompts_dir = Path(__file__).resolve().parents[1]
    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 load_prompt_schema(schema_name: str) -> str:
    prompts_dir = Path(__file__).resolve().parents[1] / "schemas"
    schema_path = prompts_dir / schema_name
    if not schema_path.exists():
        raise FileNotFoundError(f"Schema file not found: {schema_path}")
    return schema_path.read_text(encoding="utf-8")


def load_prompt_schema_json(schema_name: str) -> dict:
    schema_text = load_prompt_schema(schema_name)
    try:
        return json.loads(schema_text)
    except json.JSONDecodeError:
        return {}


def _schema_type_label(node: dict) -> str:
    if not isinstance(node, dict):
        return "unknown"
    if "type" in node:
        type_value = node.get("type")
        if isinstance(type_value, list):
            return " | ".join(str(item) for item in type_value)
        return str(type_value)
    if "enum" in node:
        return "enum"
    if "oneOf" in node:
        options = []
        for option in node.get("oneOf") or []:
            if isinstance(option, dict):
                if "$ref" in option:
                    options.append(option["$ref"].split("/")[-1])
                else:
                    options.append(_schema_type_label(option))
        return " | ".join(opt for opt in options if opt) or "oneOf"
    if "$ref" in node:
        return node["$ref"].split("/")[-1]
    if "items" in node:
        return f"array<{_schema_type_label(node.get('items') or {})}>"
    return "unknown"


def _format_intent_schema(schema_name: str, schema: dict) -> str:
    title = schema.get("title") or schema_name
    description = schema.get("description", "").strip()
    props = schema.get("properties") or {}
    required = set(schema.get("required") or [])
    lines = [f"{title}:" ]
    if description:
        lines.append(f"  {description}")
    for prop_name, prop_schema in props.items():
        if not isinstance(prop_schema, dict):
            continue
        type_label = _schema_type_label(prop_schema)
        prop_desc = prop_schema.get("description", "").strip()
        requirement = "required" if prop_name in required else "optional"
        line = f"  - {prop_name}: {type_label} ({requirement})"
        if prop_desc:
            line += f" — {prop_desc}"
        lines.append(line)
    return "\n".join(lines)


def build_intent_schema_block() -> str:
    intent_schema_files = [
        "making_statement.schema.json",
        "making_hypothetical_statement.schema.json",
        "making_notion_attribute_statement.schema.json",
    ]
    blocks = []
    for schema_name in intent_schema_files:
        schema = load_prompt_schema_json(schema_name)
        if not schema:
            continue
        blocks.append(_format_intent_schema(schema_name, schema))
    return "\n\n".join(blocks).strip()


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


def _time_specification_section() -> str:
    if not app_config.get("app.features.time_sensitive_transformations", False):
        return ""
    return """
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

"""


def _time_examples_section() -> str:
    return """
═══════════════════════════════════════════════════════════════════
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", "certainty": "certain"}
"It is snowing in London" → {"intent_type": "making_statement", "subject": "snow", "relationship_phrase": "is happening in", "object": "london", "location": "london", "time": "now", "certainty": "certain"}

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

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

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

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

"""


def build_sentence_transformer_prompt() -> str:
    from analogai.foundation.common.enums import RelationshipType  # type: ignore[import-not-found]

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

    time_field_description = _time_field_description()
    time_specification_section = _time_specification_section()
    time_examples_section = _time_examples_section()

    base_template = load_sentence_transformer_template()
    sentence_schema = load_prompt_schema("sentence_transformer.schema.json")
    intent_schemas_block = build_intent_schema_block()
    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)
        .replace("__SENTENCE_TRANSFORMER_SCHEMA__", sentence_schema)
        .replace("__INTENT_SCHEMAS__", intent_schemas_block)
    )

    return get_enhanced_system_prompt(base_instructions, num_examples=15)
