"""
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

from config import USE_LANGFUSE_PROMPTS

logger = logging.getLogger(__name__)

LANGFUSE_SYSTEM_PROMPT_NAME = "canifa-stylist-system-prompt"

# Cache vĩnh viễn (24h) — chỉ refresh khi gọi force_refresh_prompts()
# Trước đó là 300s (5 phút), giờ giữ prompt trong RAM luôn
CACHE_TTL = 86400  # 24 hours — practically permanent

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."""
    if not USE_LANGFUSE_PROMPTS:
        logger.info("ℹ️ Using local system prompt fallback (USE_LANGFUSE_PROMPTS=False)")
        # Cần fallback system prompt ở đây nếu có local
        # Tạm thời trả về rỗng, app sẽ crash hoặc báo lỗi logic nếu không có
        return ""
        
    lf = _get_langfuse()
    try:
        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"))
    except Exception as e:
        logger.warning(f"⚠️ Failed to fetch system prompt from Langfuse: {e}. Using local fallback.")
        return ""


def get_system_prompt_template() -> str:
    """Template chưa replace date_str — dùng cho ChatPromptTemplate."""
    if not USE_LANGFUSE_PROMPTS:
        logger.info("ℹ️ Using local system prompt template (USE_LANGFUSE_PROMPTS=False)")
        # Hiện tại agent/prompt_module/stylist_pro_prompts.py chứa các prompt local
        try:
            from agent.prompt_module.stylist_pro_prompts import STYLIST_PRO_RESPONDER_PROMPT
            return STYLIST_PRO_RESPONDER_PROMPT
        except ImportError:
            return ""

    lf = _get_langfuse()
    try:
        prompt = lf.get_prompt(LANGFUSE_SYSTEM_PROMPT_NAME, label="production", cache_ttl_seconds=CACHE_TTL)
        raw = prompt.prompt.replace("{", "{{").replace("}", "}}")
        return raw.replace("{{{{date_str}}}}", "{date_str}")
    except Exception as e:
        logger.warning(f"⚠️ Failed to fetch system prompt template from Langfuse: {e}. Using local fallback.")
        try:
            from agent.prompt_module.stylist_pro_prompts import STYLIST_PRO_RESPONDER_PROMPT
            return STYLIST_PRO_RESPONDER_PROMPT
        except ImportError:
            return ""


def read_tool_prompt(filename: str, default_prompt: str = "") -> str:
    """Read tool prompt from Langfuse."""
    name_key = filename.replace(".txt", "")
    
    if not USE_LANGFUSE_PROMPTS:
        logger.info(f"ℹ️ Using local tool prompt for '{name_key}' (USE_LANGFUSE_PROMPTS=False)")
        return default_prompt

    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()
    try:
        prompt = lf.get_prompt(langfuse_name, label="production", cache_ttl_seconds=CACHE_TTL)
        return prompt.prompt
    except Exception as e:
        logger.warning(f"⚠️ Failed to fetch tool prompt '{langfuse_name}' from Langfuse: {e}. Falling back to default.")
        return default_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
