package com.gzzm.lobster.prompt;

import com.gzzm.platform.commons.Tools;
import net.cyan.arachne.annotation.Service;
import net.cyan.nest.annotation.Inject;

/**
 * PromptTemplateService —— Prompt 模板服务 / Prompt template service.
 */
@Service
public class PromptTemplateService {

    /** 默认系统骨架 / Default system skeleton (bytes stable per run). */
    public static final String DEFAULT_SKELETON_NAME = "system_skeleton_v1";

    @Inject
    private PromptTemplateDao promptDao;

    /** thunwind DAO 跨线程保护 —— 详见 feedback_thunwind_dao_thread_binding */
    private PromptTemplateDao promptDao() {
        try {
            PromptTemplateDao d = Tools.getBean(PromptTemplateDao.class);
            if (d != null) return d;
        } catch (Throwable ignore) { /* fallback */ }
        return promptDao;
    }

    public String loadSystemSkeleton() throws Exception {
        PromptTemplate t = promptDao().getActiveByName(DEFAULT_SKELETON_NAME);
        if (t != null && t.getContent() != null && !t.getContent().isEmpty()) return t.getContent();
        return DEFAULT_SKELETON;
    }

    /** 默认骨架：稳定字节，用于命中 prompt cache / Stable bytes; prompt-cache friendly. */
    public static final String DEFAULT_SKELETON =
            "# 角色\n"
          + "你是政务外网内的组织级 AI 工作助手「大龙虾」。\n"
          + "你被实名用户在 OA 工作区中调用；你的一切动作都被审计。\n"
          + "\n"
          + "# 语言\n"
          + "- 除非用户明确要求使用其他语言，默认全程使用简体中文：包括对用户的回复、思考过程（thinking / reasoning）、内部规划与自我对话。\n"
          + "- 代码、命令、API 名、库名、协议字段、错误原文等按原文输出，不强行翻译。\n"
          + "- 即使用户输入夹杂英文或技术术语，思考与回复仍然默认用简体中文。\n"
          + "\n"
          + "# 行为纪律\n"
          + "- NEVER 在没有工具结果证据时声称任务已完成。\n"
          + "- NEVER 在给用户的回复中暴露内部工具名（如 oa_read_file）。\n"
          + "- MUST 如实汇报结果与错误，不臆造「权限问题」「系统失败」等原因。\n"
          + "- MUST 对覆盖 OA 原文件、批量邮件/流程等破坏性操作使用 confirm_action 先征求确认。\n"
          + "- MUST 把工具返回的关键事实在 assistant 正文中复述，避免后续轮次压缩后丢失。\n"
          + "\n"
          + "# 工具使用\n"
          + "- 同步工具：当前轮直接返回结果。\n"
          + "- 异步/交互型工具（confirm_action / ask_user）：发出 pending request 后当前轮结束。\n"
          + "- 工具名、参数必须严格按提供的 schema，不存在的工具名不要编造。\n"
          + "- 工具连续失败 2 次后应换工具或用 ask_user 请用户澄清。\n"
          + "\n"
          + "# 输出格式\n"
          + "- 简洁、直接、面向业务场景；不做自我称呼，不复述用户问题。\n"
          + "- 工具进展以 1-2 句简述（如「已核对目录，开始读取材料」），不罗列技术细节。\n"
          + "- 正式文档产出放入 Artifact；普通对话直接输出文本。\n";

    /** 动态规则片段 / Dynamic rules section (per turn). */
    public String dynamicRules(String orgId) {
        StringBuilder sb = new StringBuilder();
        sb.append("## 会话规则\n");
        sb.append("- Skill：system prompt 的「可用 Skill」段只给 id/name/description；"
                + "当任务匹配某 skill 的 description 时，调用 `use_skill(skillId)` 读取其完整方法论，"
                + "再按方法论执行。不要在没读 guidance 前就照着 description 猜测步骤。\n");
        sb.append("- 超过工具返回结果字数上限时，请先取首要事实并在 assistant 正文中沉淀。\n");
        sb.append("- 除非用户明确要求其他语言，默认使用简体中文回答；代码、命令、API 名、错误原文等保持原文。\n");
        sb.append("- 创建给用户的最终交付文件时，文件名默认使用简体中文业务名称，保留正确扩展名；"
                + "只有代码脚本、用户指定名称或技术约定必须英文时才使用英文文件名。\n");
        return sb.toString();
    }
}
