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

Reads from:
- agent/system_prompt.txt  (system prompt)
- agent/tool_prompts/*.txt (tool prompts)
"""

import logging
import os
from datetime import datetime

logger = logging.getLogger(__name__)

# Paths
_BASE_DIR = os.path.dirname(os.path.abspath(__file__))
_SYSTEM_PROMPT_PATH = os.path.join(_BASE_DIR, "system_prompt.txt")
_TOOL_PROMPTS_DIR = os.path.join(_BASE_DIR, "tool_prompts")

# In-memory cache
_system_prompt_cache: str | None = None
_tool_prompt_cache: dict[str, str] = {}


def _read_file(path: str) -> str:
    """Read a text file and return its content."""
    with open(path, "r", encoding="utf-8") as f:
        return f.read()


def get_system_prompt() -> str:
    """System prompt với ngày hiện tại đã inject."""
    template = _get_system_prompt_raw()
    return template.replace("{{date_str}}", datetime.now().strftime("%d/%m/%Y"))


def _get_system_prompt_raw() -> str:
    """Read raw system prompt from file (cached)."""
    global _system_prompt_cache
    if _system_prompt_cache is None:
        _system_prompt_cache = _read_file(_SYSTEM_PROMPT_PATH)
        logger.info(f"📄 System prompt loaded from {_SYSTEM_PROMPT_PATH} ({len(_system_prompt_cache):,} chars)")
    return _system_prompt_cache


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

    LangChain ChatPromptTemplate needs {{ for literal braces.
    So we re-escape ALL { } first, then convert only {{date_str}} → {date_str}.
    """
    raw = _get_system_prompt_raw()
    # 1) Re-escape all curly braces for LangChain (literal { → {{, } → }})
    escaped = raw.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 escaped.replace("{{{{date_str}}}}", "{date_str}")


def read_tool_prompt(filename: str, default_prompt: str = "") -> str:
    """Read tool prompt from local file."""
    name_key = filename.replace(".txt", "")

    if name_key in _tool_prompt_cache:
        return _tool_prompt_cache[name_key]

    txt_path = os.path.join(_TOOL_PROMPTS_DIR, f"{name_key}.txt")
    if not os.path.isfile(txt_path):
        logger.warning(f"⚠️ Tool prompt file not found: {txt_path}")
        return default_prompt

    content = _read_file(txt_path)
    _tool_prompt_cache[name_key] = content
    logger.info(f"📄 Tool prompt loaded: {name_key} ({len(content):,} chars)")
    return content


def write_tool_prompt(filename: str, content: str) -> bool:
    """Write tool prompt to local file."""
    name_key = filename.replace(".txt", "")
    txt_path = os.path.join(_TOOL_PROMPTS_DIR, f"{name_key}.txt")

    try:
        with open(txt_path, "w", encoding="utf-8") as f:
            f.write(content)
        # Invalidate cache
        _tool_prompt_cache.pop(name_key, None)
        logger.info(f"✅ Tool prompt written: {txt_path}")
        return True
    except Exception as e:
        logger.error(f"❌ Failed to write tool prompt '{name_key}': {e}")
        return False


def list_tool_prompts() -> list[str]:
    """List available tool prompt names."""
    if not os.path.isdir(_TOOL_PROMPTS_DIR):
        return []
    return sorted(
        f.replace(".txt", "")
        for f in os.listdir(_TOOL_PROMPTS_DIR)
        if f.endswith(".txt")
    )


def force_refresh_prompts() -> str:
    """Force refresh ALL prompt caches by re-reading files.
    Returns the new system prompt template (LangChain-ready).
    """
    global _system_prompt_cache
    _system_prompt_cache = None
    _tool_prompt_cache.clear()

    # Re-read system prompt
    template = get_system_prompt_template()
    logger.info(f"🔄 All prompts force refreshed from local files ({len(template):,} chars)")

    # Pre-load all tool prompts
    for name in list_tool_prompts():
        read_tool_prompt(name)

    return template
