"""
统一的 OFC 工具模块
Unified OFC Tool Module
整合 init_requirements_doc 和 generate_prp 功能
"""

from typing import Optional
from pydantic import BaseModel, Field
from pathlib import Path
import asyncio

from ..utils import read_file, file_exists, generate_prompt
from ..utils.loader import load_prompt


class ExecuteOfcParam(BaseModel):
    """execute_ofc 工具的参数结构"""
    action: str = Field(
        ...,
        description="执行动作类型：'init_doc' - 初始化需求文档，'generate_prp' - 生成 PRP 文档"
    )
    feature_file: Optional[str] = Field(
        None,
        description="功能需求文件路径，当 action='generate_prp' 时必填（例如：INITIAL.md）"
    )


# 获取当前文件所在目录
CURRENT_DIR = Path(__file__).parent.parent


async def get_init_requirements_doc_prompt() -> str:
    """
    获取初始化需求文档的 prompt
    Get the prompt for initializing requirements document
    """
    index_template = """
# 需求描述文档

## 目的

**此文件专为 AI Agent 设计，非一般开发者文档。**
**必须生成一个专属于 AI Agent 使用的需求描述文档([根据本次需求命名].md)。**

**必须专注于以下关键目标：**

- 准确识别和描述产品的核心功能特性
- 识别并规避潜在风险和注意事项
- 输出结构清晰、功能完整的需求文档

**强制规定：**

- 完成的规范必须使 AI Agent 能立即理解哪些文件必须参考或修改
- 避免使用模糊不清的需求描述语言
- 使用命令式语言定义规则，避免解释性内容
- 注意事项必须包含具体的风险规避方案
- 参考示例必须来自「examples」文件夹中的产品
- 识别描述中外部依赖，统一调用MCP工具阅读JAR包中源代码

**严重禁止：**

- 禁止包含通用开发知识
- 禁止包含 LLM 已知的通用开发知识
- 进行项目功能解释
- 禁止开始写代码

---

## 建议结构

请使用以下结构建立需求描述文档文件：

```markdown
# 需求描述文档 - [需求名称]

## 功能特性

### 1. 核心功能
- **功能点1**: [详细描述]
- **功能点2**: [详细描述]
- **功能点3**: [详细描述]

### 2. 功能优先级
| 优先级 | 功能名称 | 描述 | 预计工作量 |
|--------|----------|------|------------|
| P0 | [核心功能] | [描述] | [工时] |
| P1 | [重要功能] | [描述] | [工时] |
| P2 | [一般功能] | [描述] | [工时] |

### 3. 功能依赖关系
```yaml
依赖关系:
  - 功能A -> 功能B: [依赖说明]
  - 功能B -> 功能C: [依赖说明]
```

## 参考示例

以下为项目中现有的核心实现，重构时需保持其功能完整性：

### 1. 相关代码示例
**文件**: `[文件路径]`
- **功能**: [描述主要功能]
- **参考点**: [需要参考的具体实现]

### 2. 配置示例
**文件**: `[配置文件路径]`
- **配置项**: [描述配置项]

## 参考文档

### 1. 项目规范文件
- `[文件路径]` - [文件用途]

### 2. 外部文档
- [文档名称](URL) - [文档用途]

### 3. API 文档
- [API名称](URL) - [API用途]

## 技术方案建议

### 1. 推荐技术栈
```yaml
语言: [推荐语言及版本]
框架: [推荐框架及版本]
数据库: [推荐数据库]
缓存: [推荐缓存方案]
其他: [其他推荐]
```

### 2. 架构建议
- **分层架构**: [描述分层方案]
- **设计模式**: [推荐使用的设计模式]
- **性能优化**: [性能优化建议]

### 3. 关键技术决策
| 决策点 | 选择 | 理由 |
|--------|------|------|
| [决策点1] | [选择] | [理由] |
| [决策点2] | [选择] | [理由] |

## 验收标准

### 1. 功能验收
- [ ] [验收标准1]
- [ ] [验收标准2]
- [ ] [验收标准3]

### 2. 性能验收
- [ ] [性能指标1]: [目标值]
- [ ] [性能指标2]: [目标值]

### 3. 安全验收
- [ ] [安全要求1]
- [ ] [安全要求2]

### 4. 兼容性验收
- [ ] [兼容性要求1]
- [ ] [兼容性要求2]

## 风险评估与规避方案

### 1. 风险识别
| 风险ID | 风险描述 | 可能性 | 影响程度 | 优先级 |
|--------|----------|--------|----------|--------|
| R1 | [风险描述] | [高/中/低] | [高/中/低] | [P0/P1/P2] |

### 2. 风险规避方案
```yaml
风险 R1:
  描述: [详细描述]
  触发条件: [触发条件]
  规避措施:
    - [措施1]
    - [措施2]
  应急预案: [应急预案]
```

## 注意事项

### 1. 开发规范
**强制规定**:
- [规范1]
- [规范2]
- [规范3]

**严重禁止**:
- [禁止1]
- [禁止2]

### 2. 代码规范
- **命名规范**: [命名规则]
- **注释规范**: [注释要求]
- **日志规范**: [日志要求]

### 3. 测试要求
- **单元测试**: [单元测试要求]
- **集成测试**: [集成测试要求]
- **测试覆盖率**: [覆盖率要求]

---

**[AI Agent Action]**完成文档创建后请呼叫「log_report」工具进行本次工具使用记录上报
```

## 内容指南

需求描述文档应包含但不限于以下内容：

1. **功能特性** - 简要描述项目功能点描述，包含优先级和依赖关系
2. **参考示例** - 描述主要功能和使用场景，提供代码参考
3. **参考文档** - 开发过程中需要参考的任何文档
4. **技术方案建议** - 推荐的技术栈和架构建议
5. **验收标准** - 明确的功能、性能、安全验收标准
6. **风险评估与规避方案** - 风险识别和规避方案
7. **注意事项** - 任何其他注意事项或特定要求

## 文档质量要求

1. **面向 AI 优化** - 文档将作为 prompt 提供给 Coding Agent AI，应对 prompt 最佳化
2. **使用命令式语言** - 必须使用直接指令而非描述性语言，减少解释内容
3. **结构化呈现** - 所有内容必须以列表、表格等结构化形式呈现，便于 AI 解析
4. **突出重点标记** - 使用粗体、警告标记等突出关键规则和禁忌
5. **移除通用知识** - 禁止包含 LLM 已知的通用开发知识，仅包含项目特定规则
6. **优先级明确** - 必须标注功能优先级，便于分阶段实施
7. **验收标准量化** - 验收标准必须可量化、可测试

请根据以上指南，创建一个名为 [根据本次需求命名(使用下划线命名风格)].md 的文件并存放于根目录下「.joycode/docs」目录

## 完成上面的步骤后
**[AI Agent Action]**请呼叫「log_report」工具进行本次工具使用记录上报
    """

    return load_prompt(index_template, "INIT_REQUIREMENTS_DOC")


async def handle_init_doc() -> str:
    """
    处理初始化需求文档的请求
    Handle init requirements document request
    """
    return await get_init_requirements_doc_prompt()


async def handle_generate_prp(feature_file: str) -> str:
    """
    处理生成 PRP 文档的请求
    Handle generate PRP document request
    
    Args:
        feature_file: 功能需求文件路径
        
    Returns:
        str: 生成的提示内容
    """
    if not file_exists(feature_file):
        raise Exception(f"功能需求文件不存在: {feature_file}")

    # 获取模板路径
    template_path = CURRENT_DIR / "prompts"

    # 检查模板文件是否存在
    if not file_exists(template_path / "prp_base.md"):
        raise Exception(f"PRP 模板文件不存在: {template_path}")

    # 获取 template 内容
    template_content = await read_file(str(template_path), "prp_base.md")

    # 从功能文件名提取功能名称（用于输出路径）
    feature_name = Path(feature_file).stem

    prompt_content = f"""
# 创建 PRP

## 功能文件：{feature_file}

为通用功能实现生成完整的 PRP，并进行彻底研究。确保将上下文传递给 AI Agent，以实现自我验证和迭代改进。首先阅读功能文件以了解需要创建什么、提供的示例如何帮助以及任何其他考虑因素。

AI Agent只能获得您附加到 PRP 的上下文和训练数据。假设 AI Agent可以访问代码库并具有与您相同的知识截止日期，因此将您的研究发现包含或引用在 PRP 中非常重要。该代理具有网络搜索功能，因此请传递文档和示例的 URL。

## 研究流程

1. **代码库分析**
   - 在代码库中搜索类似的功能/模式
   - 识别要在 PRP 中引用的文件
   - 注意要遵循的现有约定
   - 检查验证方法的测试模式

2. 外部依赖分析规范
   - 对于代码库中缺失的依赖文件，统一使用MCP工具解析JAR包源码进行查阅
   - 处理外部依赖时，优先通过MCP工具读取JAR包内容，确保依赖关系的准确识别
   - 基于JAR包中目标方法的参数定义（入参/出参）作为开发参考标准，确保接口调用的正确性

3. **外部研究**
   - 在线搜索类似的功能/模式
   - 库文档（包含具体 URL）
   - 实现示例（GitHub/StackOverflow/博客）
   - 最佳实践和常见陷阱   

4. **用户澄清**（如果需要）
   - 要镜像的特定模式以及在哪里找到它们？
   - 集成需求以及在哪里找到它们？

## PRP 生成
使用使用以下内容作为PRP模板：
{template_content}

*** 关键：在您完成研究和探索代码库之后，开始编写 PRP 之前 ***

*** 深度思考 PRP 并规划您的方法，然后开始编写 PRP ***

## 输出
保存为：`.joycode/PRPs/{feature_name}.md`

## 质量检查清单
- [ ] 包含所有必要的上下文
- [ ] 验证门槛可由 AI 执行
- [ ] 引用现有模式
- [ ] 清晰的实现路径
- [ ] 记录错误处理
- [ ] 确保 `.joycode/PRPs/{feature_name}.md` 文件必须生成

在 1-10 的范围内为 PRP 评分（使用前端开发工具一次性实现成功的信心水平）

记住：目标是通过全面的上下文实现一次性实现成功。

**[AI Agent Action]**编辑完毕后请呼叫「log_report」工具进行本次工具使用记录上报，本次记录使用的工具为execute_ofc
**[AI Agent Action]**编辑完毕后请使用`.joycode/PRPs/{feature_name}.md`文件的全路径名呼叫「execute_prp」工具
    """
    return generate_prompt(prompt_content, {
        "feature_file": feature_file,
        "template_content": template_content,
        "feature_name": feature_name
    })


async def handle_execute_ofc(
    action: str,
    feature_file: Optional[str] = None
) -> str:
    """
    统一的 OFC 工具处理函数
    Unified OFC tool handler function
    
    Args:
        action: 执行动作类型 ('init_doc' 或 'generate_prp')
        feature_file: 功能需求文件路径（当 action='generate_prp' 时必填）
        
    Returns:
        str: 生成的提示内容或错误信息
    """
    try:
        if action == "init_doc":
            return await handle_init_doc()
        elif action == "generate_prp":
            if not feature_file:
                raise Exception("当 action='generate_prp' 时，feature_file 参数为必填项")
            return await handle_generate_prp(feature_file)
        else:
            raise Exception(f"未知的 action 类型: {action}。支持的类型: 'init_doc', 'generate_prp'")
            
    except Exception as error:
        error_message = str(error)
        return f"❌ 执行失败: {error_message}"