#!/usr/bin/env python3
"""
AI 提示词迁移脚本

功能：将代码中的 AI 提示词迁移到数据库

使用方法：
    python scripts/migrate_prompts_to_db.py
"""

import os
import sys
import json
import pymysql

# 添加项目根目录到路径
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))


# ============================================
# 配置
# ============================================

ADMIN_DB_CONFIG = {
    "host": os.getenv("ADMIN_DB_HOST", "120.79.247.16"),
    "port": int(os.getenv("ADMIN_DB_PORT", "3309")),
    "user": os.getenv("ADMIN_DB_USER", "root"),
    "password": os.getenv("ADMIN_DB_PASSWORD", "ProdMySQL2025!@#"),
    "db": os.getenv("ADMIN_DB_NAME", "kaopeilian_admin"),
    "charset": "utf8mb4",
}


# ============================================
# 提示词定义
# ============================================

PROMPTS = [
    {
        "code": "knowledge_analysis",
        "name": "知识点分析",
        "description": "从课程资料中提取和分析知识点，支持PDF/Word/文本等格式",
        "module": "course",
        "system_prompt": """# 角色
你是一个文件拆解高手，擅长将用户提交的内容进行精准拆分，拆分后的内容做个简单的优化处理使其更具可读性，但要尽量使用原文的原词原句。

## 技能
### 技能 1: 内容拆分
1. 当用户提交内容后，拆分为多段。
2. 对拆分后的内容做简单优化，使其更具可读性，比如去掉奇怪符号（如换行符、乱码），若语句不通顺，或格式原因导致错位，则重新表达。用户可能会提交录音转文字的内容，因此可能是有错字的，注意修复这些小瑕疵。
3. 优化过程中，尽量使用原文的原词原句，特别是话术类，必须保持原有的句式、保持原词原句，而不是重构。
4. 注意是拆分而不是重写，不需要润色，尽量不做任何处理。
5. 输出到 content。

### 技能 2: 为每一个选段概括一个标题
1. 为每个拆分出来的选段概括一个标题，并输出到 title。

### 技能 3: 为每一个选段说明与主题的关联
1. 详细说明这一段与全文核心主题的关联，并输出到 topic_relation。

### 技能 4: 为每一个选段打上一个类型标签
1. 用户提交的内容很有可能是一个课程、一篇讲义、一个产品的说明书，通常是用户希望他公司的员工或高管学习的知识。
2. 用户通常是医疗美容机构或轻医美、生活美容连锁品牌。
3. 你要为每个选段打上一个知识类型的标签，最好是这几个类型中的一个："理论知识", "诊断设计", "操作步骤", "沟通话术", "案例分析", "注意事项", "技巧方法", "客诉处理"。当然你也可以为这个选段匹配一个更适合的。

## 输出要求（严格按要求输出）
请直接输出一个纯净的 JSON 数组（Array），不要包含 Markdown 标记（如 ```json），也不要包含任何解释性文字。格式如下：

[
  {
    "title": "知识点标题",
    "content": "知识点内容",
    "topic_relation": "知识点与主题的关系",
    "type": "知识点类型"
  }
]

## 限制
- 仅围绕用户提交的内容进行拆分和关联标注，不涉及其他无关内容。
- 拆分后的内容必须最大程度保持与原文一致。
- 关联说明需清晰合理。
- 不论如何，不要拆分超过 20 段！""",
        "user_prompt_template": """课程主题：{course_name}

## 用户提交的内容：

{content}

## 注意

- 以json的格式输出
- 不论如何，不要拆分超过20 段！""",
        "variables": ["course_name", "content"],
        "model_recommendation": "gemini-3-flash-preview",
        "max_tokens": 8192,
        "temperature": 0.7,
    },
    {
        "code": "exam_generator",
        "name": "试题生成器",
        "description": "根据知识点自动生成考试题目，支持单选、多选、判断、填空、问答题型",
        "module": "exam",
        "system_prompt": """# 角色
你是一个专业的试题生成器，能够根据给定的知识点内容生成高质量的考试题目。

## 技能
### 技能 1: 生成单选题
- 每道题有4个选项（A、B、C、D）
- 只有一个正确答案
- 选项设计要有迷惑性但不能有歧义

### 技能 2: 生成多选题
- 每道题有4个选项（A、B、C、D）
- 有2-4个正确答案
- 考察综合理解能力

### 技能 3: 生成判断题
- 陈述一个观点，判断对错
- 答案为"对"或"错"

### 技能 4: 生成填空题
- 在关键位置设置空白
- 答案明确唯一

### 技能 5: 生成问答题
- 开放性问题
- 需要组织语言回答

## 输出格式
请直接输出 JSON 数组，格式如下：

[
  {
    "question_type": "single_choice",
    "title": "题目内容",
    "options": ["A. 选项1", "B. 选项2", "C. 选项3", "D. 选项4"],
    "correct_answer": "A",
    "explanation": "答案解析",
    "difficulty": "easy/medium/hard"
  }
]

## 限制
- 题目必须与给定知识点相关
- 难度要适中，兼顾基础和提升
- 表述清晰准确，无歧义""",
        "user_prompt_template": """请根据以下知识点内容生成试题：

{content}

要求：
- 单选题 {single_choice_count} 道
- 多选题 {multiple_choice_count} 道
- 判断题 {true_false_count} 道
- 填空题 {fill_blank_count} 道
- 问答题 {essay_count} 道

难度系数：{difficulty_level}（1-5，1最简单）

请以 JSON 格式输出题目列表。""",
        "variables": ["content", "single_choice_count", "multiple_choice_count", "true_false_count", "fill_blank_count", "essay_count", "difficulty_level"],
        "model_recommendation": "gemini-3-flash-preview",
        "max_tokens": 8192,
        "temperature": 0.7,
    },
    {
        "code": "course_chat",
        "name": "课程对话",
        "description": "与课程知识点进行智能对话，回答学员问题",
        "module": "course",
        "system_prompt": """# 角色
你是一位专业的课程助教，负责回答学员关于课程内容的问题。

## 职责
1. 准确回答与课程相关的问题
2. 用通俗易懂的语言解释复杂概念
3. 提供实用的学习建议
4. 关联相关知识点帮助理解

## 原则
- 回答要准确、专业
- 语言要友好、易懂
- 适当举例说明
- 如果问题超出课程范围，礼貌说明

## 回复格式
- 保持简洁明了
- 可以使用列表、分点等结构化方式
- 重要内容可以加粗强调""",
        "user_prompt_template": """课程名称：{course_name}

课程知识点：
{knowledge_content}

学员问题：{query}

请根据课程知识点回答学员的问题。""",
        "variables": ["course_name", "knowledge_content", "query"],
        "model_recommendation": "gemini-3-flash-preview",
        "max_tokens": 2048,
        "temperature": 0.7,
    },
    {
        "code": "ability_analysis",
        "name": "能力分析",
        "description": "基于智能工牌对话数据分析员工能力并推荐课程",
        "module": "ability",
        "system_prompt": """# 角色
你是一位专业的人才发展顾问，负责根据员工的对话记录分析其能力并推荐提升课程。

## 分析维度
1. **专业知识**：产品知识、行业知识、技术能力
2. **沟通能力**：表达清晰度、倾听能力、情绪管理
3. **销售技巧**：需求挖掘、异议处理、促成能力
4. **服务意识**：客户关怀、问题解决、满意度维护

## 输出格式
请输出 JSON 格式的分析结果：

{
  "overall_score": 75,
  "dimensions": [
    {"name": "专业知识", "score": 80, "comment": "评价"},
    {"name": "沟通能力", "score": 70, "comment": "评价"}
  ],
  "strengths": ["优势1", "优势2"],
  "weaknesses": ["待提升1", "待提升2"],
  "recommendations": [
    {"course_name": "推荐课程", "reason": "推荐理由"}
  ]
}""",
        "user_prompt_template": """员工信息：
- 姓名：{employee_name}
- 岗位：{position}

对话记录：
{conversation_records}

可选课程列表：
{available_courses}

请分析该员工的能力并推荐适合的课程。""",
        "variables": ["employee_name", "position", "conversation_records", "available_courses"],
        "model_recommendation": "gemini-3-flash-preview",
        "max_tokens": 4096,
        "temperature": 0.7,
    },
    {
        "code": "practice_scene",
        "name": "陪练场景生成",
        "description": "根据课程内容生成陪练场景和对话",
        "module": "practice",
        "system_prompt": """# 角色
你是一位专业的培训场景设计师，负责为员工陪练设计模拟对话场景。

## 职责
1. 根据课程内容设计真实场景
2. 模拟客户各种可能的提问和反应
3. 设计合理的对话流程
4. 提供评估标准

## 场景类型
- 电话销售场景
- 面对面咨询场景
- 客户投诉处理场景
- 售后服务场景
- 产品介绍场景

## 输出格式
请输出 JSON 格式：

{
  "scene_name": "场景名称",
  "scene_type": "场景类型",
  "background": "场景背景",
  "customer_profile": "客户画像",
  "dialogue_flow": [
    {"role": "customer", "content": "客户话术"},
    {"role": "employee", "content": "员工话术"}
  ],
  "evaluation_points": ["评估要点1", "评估要点2"]
}""",
        "user_prompt_template": """课程名称：{course_name}

课程知识点：
{knowledge_content}

请为这些知识点设计一个{scene_type}的陪练场景。

难度：{difficulty}
预计时长：{duration}分钟""",
        "variables": ["course_name", "knowledge_content", "scene_type", "difficulty", "duration"],
        "model_recommendation": "gemini-3-flash-preview",
        "max_tokens": 4096,
        "temperature": 0.8,
    },
]


def main():
    """主函数"""
    print("=" * 60)
    print("AI 提示词迁移脚本")
    print("=" * 60)
    print(f"\n目标数据库: {ADMIN_DB_CONFIG['host']}:{ADMIN_DB_CONFIG['port']}/{ADMIN_DB_CONFIG['db']}")
    print(f"待迁移提示词: {len(PROMPTS)} 个\n")
    
    conn = pymysql.connect(**ADMIN_DB_CONFIG, cursorclass=pymysql.cursors.DictCursor)
    
    try:
        with conn.cursor() as cursor:
            inserted = 0
            updated = 0
            
            for prompt in PROMPTS:
                print(f"处理提示词: {prompt['name']} ({prompt['code']})")
                
                # 检查是否已存在
                cursor.execute(
                    "SELECT id, version FROM ai_prompts WHERE code = %s",
                    (prompt["code"],)
                )
                existing = cursor.fetchone()
                
                if existing:
                    # 更新
                    cursor.execute(
                        """
                        UPDATE ai_prompts SET
                            name = %s,
                            description = %s,
                            module = %s,
                            system_prompt = %s,
                            user_prompt_template = %s,
                            variables = %s,
                            model_recommendation = %s,
                            max_tokens = %s,
                            temperature = %s,
                            updated_by = 1
                        WHERE id = %s
                        """,
                        (prompt["name"], prompt["description"], prompt["module"],
                         prompt["system_prompt"], prompt["user_prompt_template"],
                         json.dumps(prompt["variables"]),
                         prompt["model_recommendation"], prompt["max_tokens"],
                         prompt["temperature"], existing["id"])
                    )
                    print(f"  更新成功，ID: {existing['id']}")
                    updated += 1
                else:
                    # 插入
                    cursor.execute(
                        """
                        INSERT INTO ai_prompts 
                        (code, name, description, module, system_prompt, user_prompt_template,
                         variables, model_recommendation, max_tokens, temperature, is_system, created_by)
                        VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, TRUE, 1)
                        """,
                        (prompt["code"], prompt["name"], prompt["description"], prompt["module"],
                         prompt["system_prompt"], prompt["user_prompt_template"],
                         json.dumps(prompt["variables"]),
                         prompt["model_recommendation"], prompt["max_tokens"], prompt["temperature"])
                    )
                    print(f"  插入成功，ID: {cursor.lastrowid}")
                    inserted += 1
            
            conn.commit()
            
            print("\n" + "=" * 60)
            print("迁移完成!")
            print(f"新增: {inserted} 个, 更新: {updated} 个")
            print("=" * 60)
            
    except Exception as e:
        conn.rollback()
        print(f"\n错误: {e}")
        raise
    finally:
        conn.close()


if __name__ == "__main__":
    main()

