#!/usr/bin/env python
"""
为统计分析页面生成轻医美场景的模拟数据

生成的数据包括：
1. 考试记录（exams）- 不同时间段、不同课程、不同分数
2. 错题记录（exam_mistakes）- 不同难度、不同知识点
3. 陪练会话（practice_sessions）- 不同时间的陪练记录
4. 知识点数据（knowledge_points）- 轻医美相关知识点

目标：确保统计分析页面的每个模块都能显示数据
"""
import sys
import asyncio
from datetime import datetime, timedelta
import random
from pathlib import Path

# 添加项目路径
project_root = Path(__file__).parent.parent
sys.path.insert(0, str(project_root))

from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
from sqlalchemy.orm import sessionmaker
from sqlalchemy import select, func

from app.models.exam import Exam, Question
from app.models.exam_mistake import ExamMistake
from app.models.course import Course, KnowledgePoint
from app.models.practice import PracticeSession
from app.models.user import User
from app.core.logger import get_logger

logger = get_logger(__name__)

# 数据库连接（开发测试环境）
DATABASE_URL = "mysql+aiomysql://root:nj861021@localhost:3306/kaopeilian"


# 轻医美知识点数据
BEAUTY_KNOWLEDGE_POINTS = {
    "皮肤生理学基础": [
        "皮肤结构与层次",
        "皮肤类型与特征",
        "皮肤屏障功能",
        "皮肤老化机制",
        "皮肤色素形成",
        "皮肤水分平衡"
    ],
    "医美产品知识与应用": [
        "透明质酸的应用",
        "肉毒素的作用机理",
        "光子嫩肤原理",
        "果酸焕肤技术",
        "维生素C美白",
        "胶原蛋白补充"
    ],
    "美容仪器操作与维护": [
        "超声刀操作流程",
        "热玛吉治疗参数",
        "皮秒激光使用",
        "射频美容仪器",
        "冷光美肤仪",
        "水光注射仪"
    ],
    "轻医美销售技巧": [
        "客户需求分析",
        "项目推荐话术",
        "价格异议处理",
        "成交技巧",
        "客户关系维护",
        "套餐设计方法"
    ],
    "客户服务与投诉处理": [
        "服务标准流程",
        "投诉应对技巧",
        "客户期望管理",
        "售后跟踪服务",
        "客户满意度提升",
        "危机公关处理"
    ]
}

# 难度级别
DIFFICULTY_LEVELS = ["easy", "medium", "hard"]


async def clear_old_demo_data(db: AsyncSession, user_id: int):
    """清理旧的演示数据"""
    logger.info(f"清理用户 {user_id} 的旧演示数据...")
    
    # 清理考试记录（会级联删除错题记录）
    from sqlalchemy import delete
    await db.execute(delete(Exam).where(Exam.user_id == user_id))
    
    # 清理陪练会话
    await db.execute(delete(PracticeSession).where(PracticeSession.user_id == user_id))
    
    await db.commit()
    logger.info("旧数据清理完成")


async def get_or_create_knowledge_points(db: AsyncSession, course_id: int, course_name: str) -> list:
    """获取或创建知识点"""
    # 检查是否已有知识点
    result = await db.execute(
        select(KnowledgePoint).where(
            KnowledgePoint.course_id == course_id,
            KnowledgePoint.is_deleted == False
        )
    )
    existing_kps = result.scalars().all()
    
    if existing_kps:
        logger.info(f"课程 {course_name} 已有 {len(existing_kps)} 个知识点")
        return existing_kps
    
    # 创建新知识点
    knowledge_points = []
    if course_name in BEAUTY_KNOWLEDGE_POINTS:
        for kp_name in BEAUTY_KNOWLEDGE_POINTS[course_name]:
            kp = KnowledgePoint(
                course_id=course_id,
                name=kp_name,
                description=f"{course_name}中的重要知识点：{kp_name}",
                type="核心概念",
                source=0,  # 手动创建
                is_deleted=False
            )
            db.add(kp)
            knowledge_points.append(kp)
    
    await db.commit()
    
    # 刷新以获取ID
    for kp in knowledge_points:
        await db.refresh(kp)
    
    logger.info(f"为课程 {course_name} 创建了 {len(knowledge_points)} 个知识点")
    return knowledge_points


async def create_exam_records(db: AsyncSession, user_id: int, courses: list):
    """创建考试记录"""
    logger.info("创建考试记录...")
    
    end_date = datetime.now()
    exams_created = 0
    
    # 在过去60天内创建考试记录
    for days_ago in range(60, 0, -1):
        exam_date = end_date - timedelta(days=days_ago)
        
        # 跳过一些日期（不是每天都考试）
        if random.random() > 0.3:  # 30%的日子有考试
            continue
        
        # 每天可能考1-2次
        num_exams = random.choice([1, 1, 1, 2])
        
        for _ in range(num_exams):
            # 随机选择课程
            course = random.choice(courses)
            
            # 生成考试分数（呈现进步趋势）
            # 早期分数较低，后期分数较高
            progress_factor = (60 - days_ago) / 60  # 0 到 1
            base_score = 60 + (progress_factor * 20)  # 60-80分基础
            score_variance = random.uniform(-10, 15)
            round1_score = max(50, min(100, base_score + score_variance))
            
            # 创建考试记录
            exam = Exam(
                user_id=user_id,
                course_id=course.id,
                exam_name=f"{course.name}测试",
                question_count=10,
                total_score=100.0,
                pass_score=60.0,
                start_time=exam_date,
                end_time=exam_date + timedelta(minutes=random.randint(15, 45)),
                duration_minutes=random.randint(15, 45),
                round1_score=round(round1_score, 1),
                round2_score=None,
                round3_score=None,
                score=round(round1_score, 1),
                is_passed=round1_score >= 60,
                status="submitted"
            )
            
            db.add(exam)
            exams_created += 1
    
    await db.commit()
    logger.info(f"创建了 {exams_created} 条考试记录")
    
    return exams_created


async def create_exam_mistakes(db: AsyncSession, user_id: int, courses: list):
    """创建错题记录"""
    logger.info("创建错题记录...")
    
    # 获取用户的所有考试
    result = await db.execute(
        select(Exam).where(Exam.user_id == user_id).order_by(Exam.start_time)
    )
    exams = result.scalars().all()
    
    mistakes_created = 0
    
    for exam in exams:
        # 找到对应的课程
        course = next((c for c in courses if c.id == exam.course_id), None)
        if not course:
            continue
        
        # 获取该课程的知识点
        result = await db.execute(
            select(KnowledgePoint).where(
                KnowledgePoint.course_id == course.id,
                KnowledgePoint.is_deleted == False
            )
        )
        knowledge_points = result.scalars().all()
        
        if not knowledge_points:
            continue
        
        # 根据分数决定错题数（分数越低，错题越多）
        score = exam.round1_score or 70
        mistake_rate = (100 - score) / 100  # 0.0 到 0.5
        num_mistakes = int(exam.question_count * mistake_rate)
        num_mistakes = max(1, min(num_mistakes, exam.question_count - 1))
        
        # 创建错题
        for i in range(num_mistakes):
            # 随机选择知识点
            kp = random.choice(knowledge_points)
            
            # 随机选择题型
            question_types = ["single_choice", "multiple_choice", "true_false", "fill_blank", "essay"]
            question_type = random.choice(question_types)
            
            mistake = ExamMistake(
                user_id=user_id,
                exam_id=exam.id,
                question_id=None,  # AI生成的题目
                knowledge_point_id=kp.id,
                question_content=f"关于{kp.name}的问题{i+1}",
                correct_answer="正确答案",
                user_answer="用户错误答案",
                question_type=question_type
            )
            
            db.add(mistake)
            mistakes_created += 1
    
    await db.commit()
    logger.info(f"创建了 {mistakes_created} 条错题记录")
    
    return mistakes_created


async def create_practice_sessions(db: AsyncSession, user_id: int):
    """创建陪练会话记录"""
    logger.info("创建陪练会话记录...")
    
    end_date = datetime.now()
    sessions_created = 0
    
    # 在过去60天内创建陪练记录
    for days_ago in range(60, 0, -1):
        session_date = end_date - timedelta(days=days_ago)
        
        # 跳过一些日期
        if random.random() > 0.25:  # 25%的日子有陪练
            continue
        
        # 每次陪练的时长（秒）
        duration_seconds = random.randint(600, 1800)  # 10-30分钟
        
        # 场景类型
        scene_types = ["电话销售", "面对面咨询", "客户投诉处理", "售后服务", "产品介绍"]
        scene_name = random.choice(scene_types)
        
        session = PracticeSession(
            session_id=f"session_{user_id}_{int(session_date.timestamp())}",
            user_id=user_id,
            scene_id=random.randint(1, 5),
            scene_name=scene_name,
            scene_type=scene_name,
            start_time=session_date,
            end_time=session_date + timedelta(seconds=duration_seconds),
            duration_seconds=duration_seconds,
            turns=random.randint(10, 30),
            status="completed",
            is_deleted=False
        )
        
        db.add(session)
        sessions_created += 1
    
    await db.commit()
    logger.info(f"创建了 {sessions_created} 条陪练会话记录")
    
    return sessions_created


async def main():
    """主函数"""
    logger.info("=" * 60)
    logger.info("开始为统计分析页面生成轻医美场景的模拟数据")
    logger.info("=" * 60)
    
    # 创建数据库连接
    engine = create_async_engine(DATABASE_URL, echo=False)
    async_session = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
    
    try:
        async with async_session() as db:
            # 1. 获取测试用户（admin或第一个用户）
            result = await db.execute(
                select(User).where(User.username == "admin")
            )
            user = result.scalar_one_or_none()
            
            if not user:
                # 如果没有admin，使用第一个用户
                result = await db.execute(select(User).limit(1))
                user = result.scalar_one_or_none()
            
            if not user:
                logger.error("❌ 未找到用户，请先创建用户")
                return
            
            logger.info(f"📝 使用用户: {user.username} (ID: {user.id})")
            
            # 2. 获取轻医美相关课程
            result = await db.execute(
                select(Course).where(
                    Course.is_deleted == False,
                    Course.status == "published"
                )
            )
            courses = result.scalars().all()
            
            if not courses:
                logger.error("❌ 未找到已发布的课程")
                return
            
            logger.info(f"📚 找到 {len(courses)} 门课程")
            
            # 3. 清理旧数据（可选）
            clear_old = input("\n是否清理该用户的旧数据？(y/n): ").lower()
            if clear_old == 'y':
                await clear_old_demo_data(db, user.id)
            
            # 4. 为每门课程创建知识点
            logger.info("\n" + "=" * 60)
            logger.info("步骤 1/3: 创建知识点")
            logger.info("=" * 60)
            for course in courses:
                await get_or_create_knowledge_points(db, course.id, course.name)
            
            # 5. 创建考试记录
            logger.info("\n" + "=" * 60)
            logger.info("步骤 2/3: 创建考试记录")
            logger.info("=" * 60)
            exams_count = await create_exam_records(db, user.id, courses)
            
            # 6. 创建错题记录
            logger.info("\n" + "=" * 60)
            logger.info("步骤 3/3: 创建错题记录")
            logger.info("=" * 60)
            mistakes_count = await create_exam_mistakes(db, user.id, courses)
            
            # 7. 创建陪练会话记录
            logger.info("\n" + "=" * 60)
            logger.info("步骤 4/4: 创建陪练会话记录")
            logger.info("=" * 60)
            sessions_count = await create_practice_sessions(db, user.id)
            
            # 8. 统计信息
            logger.info("\n" + "=" * 60)
            logger.info("✅ 数据生成完成！")
            logger.info("=" * 60)
            logger.info(f"用户: {user.username} (ID: {user.id})")
            logger.info(f"考试记录: {exams_count} 条")
            logger.info(f"错题记录: {mistakes_count} 条")
            logger.info(f"陪练记录: {sessions_count} 条")
            logger.info("=" * 60)
            logger.info("\n现在可以访问统计分析页面查看数据：")
            logger.info("http://localhost:5173/analysis/statistics")
            logger.info("=" * 60)
            
    except Exception as e:
        logger.error(f"❌ 生成数据失败: {e}")
        import traceback
        traceback.print_exc()
    
    finally:
        await engine.dispose()


if __name__ == "__main__":
    asyncio.run(main())

