"""提示词管理器"""

import socket
from pathlib import Path
from time import strftime
from typing import Dict

from app.core.config import settings
from app.log import logger
from app.schemas import (
    ChannelCapability,
    ChannelCapabilities,
    MessageChannel,
    ChannelCapabilityManager,
)
from app.utils.system import SystemUtils


class PromptManager:
    """
    提示词管理器
    """

    def __init__(self, prompts_dir: str = None):
        if prompts_dir is None:
            self.prompts_dir = Path(__file__).parent
        else:
            self.prompts_dir = Path(prompts_dir)
        self.prompts_cache: Dict[str, str] = {}

    def load_prompt(self, prompt_name: str) -> str:
        """
        加载指定的提示词
        """
        if prompt_name in self.prompts_cache:
            return self.prompts_cache[prompt_name]

        prompt_file = self.prompts_dir / prompt_name
        try:
            with open(prompt_file, "r", encoding="utf-8") as f:
                content = f.read().strip()
            # 缓存提示词
            self.prompts_cache[prompt_name] = content
            logger.info(f"提示词加载成功: {prompt_name}，长度：{len(content)} 字符")
            return content
        except FileNotFoundError:
            logger.error(f"提示词文件不存在: {prompt_file}")
            raise
        except Exception as e:
            logger.error(f"加载提示词失败: {prompt_name}, 错误: {e}")
            raise

    def get_agent_prompt(self, channel: str = None) -> str:
        """
        获取智能体提示词
        :param channel: 消息渠道（Telegram、微信、Slack等）
        :return: 提示词内容
        """
        # 基础提示词
        base_prompt = self.load_prompt("Agent Prompt.txt")

        # 识别渠道
        markdown_spec = ""
        msg_channel = (
            next(
                (c for c in MessageChannel if c.value.lower() == channel.lower()), None
            )
            if channel
            else None
        )
        # 获取渠道能力说明
        if msg_channel:
            caps = ChannelCapabilityManager.get_capabilities(msg_channel)
            if caps:
                markdown_spec = self._generate_formatting_instructions(caps)

        # 啰嗦模式
        verbose_spec = ""
        if not settings.AI_AGENT_VERBOSE:
            verbose_spec = (
                "\n\n[Important Instruction] STRICTLY ENFORCED: DO NOT output any conversational "
                "text, thinking processes, or explanations before or during tool calls. Call tools "
                "directly without any transitional phrases. "
                "You MUST remain completely silent until the task is completely finished. "
                "DO NOT output any content whatsoever until your final summary reply."
            )

        # MoviePilot系统信息
        moviepilot_info = self._get_moviepilot_info()

        # 始终替换占位符，避免后续 .format() 时因残留花括号报 KeyError
        base_prompt = base_prompt.format(
            markdown_spec=markdown_spec,
            verbose_spec=verbose_spec,
            moviepilot_info=moviepilot_info,
        )

        return base_prompt

    @staticmethod
    def _get_moviepilot_info() -> str:
        """
        获取MoviePilot系统信息，用于注入到系统提示词中
        """
        # 获取主机名和IP地址
        try:
            hostname = socket.gethostname()
            ip_address = socket.gethostbyname(hostname)
        except Exception:  # noqa
            hostname = "localhost"
            ip_address = "127.0.0.1"

        # 配置文件和日志文件目录
        config_path = str(settings.CONFIG_PATH)
        log_path = str(settings.LOG_PATH)

        # API地址构建
        api_port = settings.PORT
        api_path = settings.API_V1_STR

        # API令牌
        api_token = settings.API_TOKEN or "未设置"

        # 数据库信息
        db_type = settings.DB_TYPE
        if db_type == "sqlite":
            db_info = f"SQLite ({settings.CONFIG_PATH / 'db' / 'moviepilot.db'})"
        else:
            db_password = settings.DB_POSTGRESQL_PASSWORD or ""
            db_info = f"PostgreSQL ({settings.DB_POSTGRESQL_USERNAME}:{db_password}@{settings.DB_POSTGRESQL_HOST}:{settings.DB_POSTGRESQL_PORT}/{settings.DB_POSTGRESQL_DATABASE})"

        info_lines = [
            f"- 当前时间: {strftime('%Y-%m-%d %H:%M:%S')}",
            f"- 运行环境: {SystemUtils.platform} {'docker' if SystemUtils.is_docker() else ''}",
            f"- 主机名: {hostname}",
            f"- IP地址: {ip_address}",
            f"- API端口: {api_port}",
            f"- API路径: {api_path}",
            f"- API令牌: {api_token}",
            f"- 外网域名: {settings.APP_DOMAIN or '未设置'}",
            f"- 数据库类型: {db_type}",
            f"- 数据库: {db_info}",
            f"- 配置文件目录: {config_path}",
            f"- 日志文件目录: {log_path}",
            f"- 系统安装目录: {settings.ROOT_PATH}",
        ]

        return "\n".join(info_lines)

    @staticmethod
    def _generate_formatting_instructions(caps: ChannelCapabilities) -> str:
        """
        根据渠道能力动态生成格式指令
        """
        instructions = []
        if ChannelCapability.RICH_TEXT not in caps.capabilities:
            instructions.append(
                "- Formatting: Use **Plain Text ONLY**. The channel does NOT support Markdown."
            )
            instructions.append(
                "- No Markdown Symbols: NEVER use `**`, `*`, `__`, or `[` blocks. Use natural text to emphasize (e.g., using ALL CAPS or separators)."
            )
            instructions.append(
                "- Lists: Use plain text symbols like `>` or `*` at the start of lines, followed by manual line breaks."
            )
            instructions.append("- Links: Paste URLs directly as text.")
        return "\n".join(instructions)

    def clear_cache(self):
        """
        清空缓存
        """
        self.prompts_cache.clear()
        logger.info("提示词缓存已清空")


prompt_manager = PromptManager()
