"""
Prompt Utilities — ALL prompts from Langfuse.
System prompt + Tool prompts, single source of truth.

Cache strategy:
- SDK cache TTL = 300s (5 min) — giảm HTTP calls tới Langfuse
- Langfuse server có cache riêng phía nó
- Gọi force_refresh_prompts() khi cần update tức thì
- Graph hash-check giữ chain cache ổn định
"""

import logging
from datetime import datetime

from langfuse import Langfuse

logger = logging.getLogger(__name__)

LANGFUSE_SYSTEM_PROMPT_NAME = "canifa-stylist-system-prompt"

# Cache 5 phút — balance giữa update nhanh vs performance
# Gọi force_refresh_prompts() nếu cần update ngay lập tức
CACHE_TTL = 300

LANGFUSE_TOOL_PROMPT_MAP = {
    "brand_knowledge_tool": "canifa-tool-brand-knowledge",
    "check_is_stock": "canifa-tool-check-stock",
    "data_retrieval_tool": "canifa-tool-data-retrieval",
    "promotion_canifa_tool": "canifa-tool-promotion",
    "store_search_tool": "canifa-tool-store-search",
}

_langfuse_client: Langfuse | None = None

def _get_langfuse() -> Langfuse:
    global _langfuse_client
    if _langfuse_client is None:
        _langfuse_client = Langfuse()
    return _langfuse_client


def get_system_prompt() -> str:
    """System prompt với ngày hiện tại đã inject."""
    lf = _get_langfuse()
    prompt = lf.get_prompt(LANGFUSE_SYSTEM_PROMPT_NAME, label="production", cache_ttl_seconds=CACHE_TTL)
    return prompt.compile(date_str=datetime.now().strftime("%d/%m/%Y"))


def get_system_prompt_template() -> str:
    """Template chưa replace date_str — dùng cho ChatPromptTemplate.

    Langfuse SDK `.prompt` un-escapes {{ → { for non-variable content,
    but LangChain ChatPromptTemplate needs {{ for literal braces.
    So we re-escape ALL { } first, then convert only {{date_str}} → {date_str}.
    """
    lf = _get_langfuse()
    prompt = lf.get_prompt(LANGFUSE_SYSTEM_PROMPT_NAME, label="production", cache_ttl_seconds=CACHE_TTL)
    # 1) Re-escape all curly braces for LangChain (literal { → {{, } → }})
    raw = prompt.prompt.replace("{", "{{").replace("}", "}}")
    # 2) Convert only the date_str variable back to LangChain format
    #    After step 1, {{date_str}} became {{{{date_str}}}} → convert to {date_str}
    return raw.replace("{{{{date_str}}}}", "{date_str}")


def read_tool_prompt(filename: str, default_prompt: str = "") -> str:
    """Read tool prompt from Langfuse."""
    name_key = filename.replace(".txt", "")
    langfuse_name = LANGFUSE_TOOL_PROMPT_MAP.get(name_key)
    if not langfuse_name:
        logger.warning(f"⚠️ No Langfuse mapping for tool prompt '{name_key}'")
        return default_prompt

    lf = _get_langfuse()
    prompt = lf.get_prompt(langfuse_name, label="production", cache_ttl_seconds=CACHE_TTL)
    return prompt.prompt


def write_tool_prompt(filename: str, content: str) -> bool:
    """Push tool prompt to Langfuse as new version."""
    name_key = filename.replace(".txt", "")
    langfuse_name = LANGFUSE_TOOL_PROMPT_MAP.get(name_key)
    if not langfuse_name:
        logger.error(f"No Langfuse mapping for '{name_key}'")
        return False

    lf = _get_langfuse()
    lf.create_prompt(
        name=langfuse_name,
        prompt=content,
        labels=["production"],
        tags=["canifa", "tool-prompt"],
        type="text",
    )
    logger.info(f"✅ Tool prompt '{name_key}' pushed to Langfuse")
    return True


def list_tool_prompts() -> list[str]:
    """List available tool prompt names."""
    return sorted(LANGFUSE_TOOL_PROMPT_MAP.keys())


def force_refresh_prompts() -> str:
    """Force refresh ALL prompt caches by fetching with cache_ttl=0.
    Call this after updating prompts on Langfuse to take effect immediately.
    Returns the new system prompt template (LangChain-ready).
    """
    lf = _get_langfuse()

    # 1) Force refresh system prompt (bypasses SDK cache)
    prompt = lf.get_prompt(LANGFUSE_SYSTEM_PROMPT_NAME, label="production", cache_ttl_seconds=0)
    logger.info(f"🔄 Force refreshed system prompt: {LANGFUSE_SYSTEM_PROMPT_NAME} (v{prompt.version}, {len(prompt.prompt):,} chars)")
    raw = prompt.prompt.replace("{", "{{").replace("}", "}}")
    new_template = raw.replace("{{{{date_str}}}}", "{date_str}")

    # 2) Force refresh all tool prompts
    for name_key, langfuse_name in LANGFUSE_TOOL_PROMPT_MAP.items():
        try:
            lf.get_prompt(langfuse_name, label="production", cache_ttl_seconds=0)
            logger.info(f"🔄 Force refreshed tool prompt: {name_key}")
        except Exception as e:
            logger.warning(f"⚠️ Failed to refresh tool prompt '{name_key}': {e}")

    logger.info(f"✅ All prompts force refreshed (version: {prompt.version})")
    return new_template
