"""Prompt 模板管理：内置 system prompt、用户自定义合并、diff 内容组装。"""

from __future__ import annotations

from acm.config import ACMConfig, get_commit_types
from acm.feedback import FeedbackRecord, load_feedback, match_feedback

# ---------------------------------------------------------------------------
# 内置默认 System Prompt
# ---------------------------------------------------------------------------

DEFAULT_SYSTEM_PROMPT = """\
你是一个专业的 Git Commit Message 生成助手。你的任务是根据提供的代码 diff 内容，生成规范的 commit message。

## 规则

1. **格式**：`<type>(<scope>): <描述>`
2. **type** 必须从以下列表中选择：{types}
3. **scope** 根据变更文件所在的目录/模块自动推断，使用最能代表变更范围的模块名
4. **描述**使用{language}，简洁明了，不超过 50 个字符
5. **合并同类变更**：如果多个文件的变更属于同一类操作（如都是优化导入、移除未使用代码、统一格式调整等），应合并为一条 message，scope 用逗号分隔列出所有涉及的模块，而不是为每个文件单独生成描述。例如：
   - `refactor(cve_service, cve_serializer): 优化导入和移除未使用模块`
   - `style(auth, api, utils): 统一代码格式化`
6. 如果变更涉及多个不同类型的修改（非同类操作）：
   - 标题行用逗号分隔 scope，如 `feat(auth,api): 描述`
   - 标题行后空一行，再用列表形式分别描述每个模块的变更
7. 只输出 commit message 本身，不要包含任何解释、前缀或 markdown 标记

## 输出格式示例

单域变更：
```
feat(auth): 添加用户登录功能
```

多文件同类变更（合并）：
```
refactor(cve_service, cve_serializer): 优化导入和移除未使用模块
```

多域不同类变更：
```
feat(auth,api): 添加用户认证模块

- auth: 实现基于JWT的登录认证逻辑
- api: 新增 /login 和 /logout 接口
```
"""


# ---------------------------------------------------------------------------
# Prompt 构建
# ---------------------------------------------------------------------------

def build_system_prompt(config: ACMConfig, diff_content: str = "") -> str:
    """构建 system prompt，支持用户自定义覆盖。

    Args:
        config: ACM 配置。
        diff_content: 当前 diff 内容，用于智能匹配相关反馈。
    """
    if config.prompt.system:
        # 用户完全自定义
        return config.prompt.system

    types = get_commit_types(config)
    types_str = ", ".join(types)

    language_map = {
        "zh-CN": "中文",
        "en": "English",
        "ja": "日本語",
    }
    language = language_map.get(config.commit.language, config.commit.language)

    prompt = DEFAULT_SYSTEM_PROMPT.format(types=types_str, language=language)

    if config.prompt.extra:
        prompt += f"\n\n## 额外指令\n\n{config.prompt.extra}"

    # 智能匹配并注入相关历史反馈
    feedback_section = _build_feedback_section(diff_content=diff_content)
    if feedback_section:
        prompt += feedback_section

    return prompt


def _build_feedback_section(
    records: list[FeedbackRecord] | None = None,
    diff_content: str = "",
) -> str:
    """根据历史反馈记录构建学习示例段落。

    当提供 diff_content 时，使用智能匹配选择最相关的反馈；
    否则回退到全量注入。

    Args:
        records: 反馈记录列表，None 时从文件加载/匹配。
        diff_content: 当前 diff 内容，用于匹配相关反馈。

    Returns:
        格式化后的反馈段落，无记录时返回空字符串。
    """
    if records is None:
        if diff_content:
            records = match_feedback(diff_content)
        else:
            records = load_feedback()
    if not records:
        return ""

    lines = ["\n\n## 用户偏好（从历史反馈中学习）\n"]
    lines.append("以下是用户曾经的修正记录，请学习用户的偏好并应用到后续生成中：\n")
    for i, r in enumerate(records, 1):
        lines.append(f"{i}. 原始: `{r.original_message}`")
        lines.append(f"   反馈: {r.feedback}")
        lines.append(f"   改进: `{r.improved_message}`")
    return "\n".join(lines) + "\n"


def build_user_prompt(diff_content: str, feedback: str = "") -> str:
    """构建 user prompt，包含 diff 内容和可选的用户反馈。"""
    prompt = f"请根据以下 git diff 内容生成 commit message：\n\n```diff\n{diff_content}\n```"

    if feedback:
        prompt += f"\n\n用户对上一次生成结果的反馈：{feedback}\n请根据反馈重新生成。"

    return prompt


def build_split_system_prompt(config: ACMConfig) -> str:
    """构建用于智能拆分提交的 system prompt。"""
    types = get_commit_types(config)
    types_str = ", ".join(types)

    language_map = {
        "zh-CN": "中文",
        "en": "English",
    }
    language = language_map.get(config.commit.language, config.commit.language)

    return f"""\
你是一个专业的 Git 提交拆分助手。你的任务是分析 git diff 内容，将变更按照逻辑关联性拆分为多个独立的原子提交。

## 规则

1. 每个提交组包含逻辑上相关联的文件
2. 每个提交组对应一个 commit message，格式为：`<type>(<scope>): <描述>`
3. type 从以下列表中选择：{types_str}
4. 描述使用{language}
5. 输出严格使用 JSON 格式，不要包含任何其他内容

## 输出 JSON 格式

```json
[
  {{
    "files": ["path/to/file1.py", "path/to/file2.py"],
    "message": "feat(auth): 添加用户登录功能"
  }},
  {{
    "files": ["path/to/test_file.py"],
    "message": "test(auth): 添加登录功能单元测试"
  }}
]
```
"""


def build_split_user_prompt(diff_content: str, files: list[str]) -> str:
    """构建用于智能拆分的 user prompt。"""
    files_str = "\n".join(f"- {f}" for f in files)
    return (
        f"以下是待提交的文件列表：\n{files_str}\n\n"
        f"以下是 git diff 内容：\n\n```diff\n{diff_content}\n```\n\n"
        f"请将这些变更拆分为多个原子提交。"
    )
