"""
管理员查看学员考试成绩API
"""
from datetime import datetime
from typing import List, Optional

from fastapi import APIRouter, Body, Depends, Query
from pydantic import BaseModel
from sqlalchemy import and_, delete, func, or_, select
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import selectinload

from app.core.deps import get_current_user, get_db
from app.core.logger import logger
from app.models.course import Course
from app.models.exam import Exam
from app.models.exam_mistake import ExamMistake
from app.models.position_member import PositionMember
from app.models.position import Position
from app.models.user import User
from app.schemas.base import PaginatedResponse, ResponseModel

router = APIRouter(prefix="/manager/student-scores", tags=["manager-student-scores"])


class BatchDeleteRequest(BaseModel):
    """批量删除请求"""
    ids: List[int]


@router.get("/{exam_id}/mistakes", response_model=ResponseModel[PaginatedResponse])
async def get_exam_mistakes(
    exam_id: int,
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
) -> ResponseModel:
    """
    获取指定考试的错题记录（管理员和manager可访问）
    """
    try:
        # 权限检查
        if current_user.role not in ['admin', 'manager']:
            return ResponseModel(code=403, message="无权访问", data=None)
        
        # 查询错题记录
        query = (
            select(ExamMistake)
            .options(selectinload(ExamMistake.question))
            .where(ExamMistake.exam_id == exam_id)
            .order_by(ExamMistake.created_at.desc())
        )
        
        result = await db.execute(query)
        mistakes = result.scalars().all()
        
        items = []
        for mistake in mistakes:
            # 获取解析：优先从关联题目获取，如果是AI生成的题目可能没有关联题目
            analysis = ""
            if mistake.question and mistake.question.explanation:
                analysis = mistake.question.explanation
                
            items.append({
                "id": mistake.id,
                "question_content": mistake.question_content,
                "correct_answer": mistake.correct_answer,
                "user_answer": mistake.user_answer,
                "question_type": mistake.question_type,
                "analysis": analysis,
                "created_at": mistake.created_at.strftime('%Y-%m-%d %H:%M:%S') if mistake.created_at else None
            })
        
        return ResponseModel(
            code=200,
            message="success",
            data=PaginatedResponse(
                items=items,
                total=len(items),
                page=1,
                page_size=len(items),
                pages=1
            )
        )
    
    except Exception as e:
        logger.error(f"获取错题记录失败: {e}", exc_info=True)
        return ResponseModel(code=500, message=f"获取错题记录失败: {str(e)}", data=None)


@router.get("/", response_model=ResponseModel[PaginatedResponse])
async def get_student_scores(
    page: int = Query(1, ge=1, description="页码"),
    size: int = Query(20, ge=1, le=100, description="每页数量"),
    student_name: Optional[str] = Query(None, description="学员姓名搜索"),
    position: Optional[str] = Query(None, description="岗位筛选"),
    course_id: Optional[int] = Query(None, description="课程ID筛选"),
    score_range: Optional[str] = Query(None, description="成绩范围: excellent/good/pass/fail"),
    start_date: Optional[str] = Query(None, description="开始日期 YYYY-MM-DD"),
    end_date: Optional[str] = Query(None, description="结束日期 YYYY-MM-DD"),
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
) -> ResponseModel:
    """
    获取所有学员的考试成绩列表（管理员和manager可访问）
    
    支持筛选：
    - student_name: 按学员姓名模糊搜索
    - position: 按岗位筛选
    - course_id: 按课程筛选
    - score_range: 按成绩范围筛选（excellent>=90, good>=80, pass>=60, fail<60）
    - start_date/end_date: 按日期范围筛选
    """
    try:
        # 权限检查
        if current_user.role not in ['admin', 'manager']:
            return ResponseModel(code=403, message="无权访问", data=None)
        
        # 构建基础查询
        # 关联User、Course、ExamMistake来获取完整信息
        query = (
            select(
                Exam,
                User.full_name.label('student_name'),
                User.id.label('student_id'),
                Course.name.label('course_name'),
                func.count(ExamMistake.id).label('wrong_count')
            )
            .join(User, Exam.user_id == User.id)
            .join(Course, Exam.course_id == Course.id)
            .outerjoin(ExamMistake, and_(
                ExamMistake.exam_id == Exam.id,
                ExamMistake.user_id == User.id
            ))
            .where(
                Exam.status.in_(['completed', 'submitted'])  # 只查询已完成的考试
            )
            .group_by(Exam.id, User.id, User.full_name, Course.id, Course.name)
        )
        
        # 学员姓名筛选
        if student_name:
            query = query.where(User.full_name.contains(student_name))
        
        # 岗位筛选
        if position:
            # 通过position_members关联查询
            query = query.join(
                PositionMember,
                and_(
                    PositionMember.user_id == User.id,
                    PositionMember.is_deleted == False
                )
            ).join(
                Position,
                Position.id == PositionMember.position_id
            ).where(
                Position.name == position
            )
        
        # 课程筛选
        if course_id:
            query = query.where(Exam.course_id == course_id)
        
        # 成绩范围筛选
        if score_range:
            score_field = Exam.round1_score  # 使用第一轮成绩
            if score_range == 'excellent':
                query = query.where(score_field >= 90)
            elif score_range == 'good':
                query = query.where(and_(score_field >= 80, score_field < 90))
            elif score_range == 'pass':
                query = query.where(and_(score_field >= 60, score_field < 80))
            elif score_range == 'fail':
                query = query.where(score_field < 60)
        
        # 日期范围筛选
        if start_date:
            try:
                start_dt = datetime.strptime(start_date, '%Y-%m-%d')
                query = query.where(Exam.created_at >= start_dt)
            except ValueError:
                pass
        
        if end_date:
            try:
                end_dt = datetime.strptime(end_date, '%Y-%m-%d')
                end_dt = end_dt.replace(hour=23, minute=59, second=59)
                query = query.where(Exam.created_at <= end_dt)
            except ValueError:
                pass
        
        # 按创建时间倒序
        query = query.order_by(Exam.created_at.desc())
        
        # 计算总数
        count_query = select(func.count()).select_from(query.subquery())
        total_result = await db.execute(count_query)
        total = total_result.scalar() or 0
        
        # 分页查询
        offset = (page - 1) * size
        results = await db.execute(query.offset(offset).limit(size))
        
        # 构建响应数据
        items = []
        for exam, student_name, student_id, course_name, wrong_count in results:
            # 查询该学员的所有岗位
            position_query = (
                select(Position.name)
                .join(PositionMember, Position.id == PositionMember.position_id)
                .where(
                    PositionMember.user_id == student_id,
                    PositionMember.is_deleted == False,
                    Position.is_deleted == False
                )
            )
            position_result = await db.execute(position_query)
            positions = position_result.scalars().all()
            position_str = ', '.join(positions) if positions else None
            
            # 计算正确率和用时
            accuracy = None
            correct_count = None
            duration_seconds = None
            
            if exam.question_count and exam.question_count > 0:
                correct_count = exam.question_count - wrong_count
                accuracy = round((correct_count / exam.question_count) * 100, 1)
            
            if exam.start_time and exam.end_time:
                duration_seconds = int((exam.end_time - exam.start_time).total_seconds())
            
            items.append({
                "id": exam.id,
                "student_id": student_id,
                "student_name": student_name,
                "position": position_str,  # 所有岗位，逗号分隔
                "course_id": exam.course_id,
                "course_name": course_name,
                "exam_type": "assessment",  # 简化处理，统一为assessment
                "score": float(exam.round1_score) if exam.round1_score else 0,
                "round1_score": float(exam.round1_score) if exam.round1_score else None,
                "round2_score": float(exam.round2_score) if exam.round2_score else None,
                "round3_score": float(exam.round3_score) if exam.round3_score else None,
                "total_score": float(exam.total_score) if exam.total_score else 100,
                "accuracy": accuracy,
                "correct_count": correct_count,
                "wrong_count": wrong_count,
                "total_count": exam.question_count,
                "duration_seconds": duration_seconds,
                "exam_date": exam.created_at.strftime('%Y-%m-%d %H:%M:%S') if exam.created_at else None
            })
        
        # 计算分页信息
        pages = (total + size - 1) // size
        
        return ResponseModel(
            code=200,
            message="success",
            data=PaginatedResponse(
                items=items,
                total=total,
                page=page,
                page_size=size,
                pages=pages
            )
        )
    
    except Exception as e:
        logger.error(f"获取学员考试成绩失败: {e}", exc_info=True)
        return ResponseModel(code=500, message=f"获取学员考试成绩失败: {str(e)}", data=None)


@router.get("/statistics", response_model=ResponseModel)
async def get_student_scores_statistics(
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
) -> ResponseModel:
    """
    获取学员考试成绩统计数据
    
    返回：
    - total_exams: 总考试次数
    - avg_score: 平均分
    - pass_rate: 通过率
    - excellent_rate: 优秀率
    """
    try:
        # 权限检查
        if current_user.role not in ['admin', 'manager']:
            return ResponseModel(code=403, message="无权访问", data=None)
        
        # 查询所有用户的已完成考试
        query = (
            select(Exam)
            .join(User, Exam.user_id == User.id)
            .where(
                Exam.status.in_(['completed', 'submitted']),
                Exam.round1_score.isnot(None)
            )
        )
        
        result = await db.execute(query)
        exams = result.scalars().all()
        
        if not exams:
            return ResponseModel(
                code=200,
                message="success",
                data={
                    "total_exams": 0,
                    "avg_score": 0,
                    "pass_rate": 0,
                    "excellent_rate": 0
                }
            )
        
        total_exams = len(exams)
        total_score = sum(exam.round1_score for exam in exams if exam.round1_score)
        avg_score = round(total_score / total_exams, 1) if total_exams > 0 else 0
        
        passed = sum(1 for exam in exams if exam.round1_score and exam.round1_score >= 60)
        pass_rate = round((passed / total_exams) * 100, 1) if total_exams > 0 else 0
        
        excellent = sum(1 for exam in exams if exam.round1_score and exam.round1_score >= 90)
        excellent_rate = round((excellent / total_exams) * 100, 1) if total_exams > 0 else 0
        
        return ResponseModel(
            code=200,
            message="success",
            data={
                "total_exams": total_exams,
                "avg_score": avg_score,
                "pass_rate": pass_rate,
                "excellent_rate": excellent_rate
            }
        )
    
    except Exception as e:
        logger.error(f"获取学员考试成绩统计失败: {e}", exc_info=True)
        return ResponseModel(code=500, message=f"获取学员考试成绩统计失败: {str(e)}", data=None)


@router.delete("/{exam_id}", response_model=ResponseModel)
async def delete_exam_record(
    exam_id: int,
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
) -> ResponseModel:
    """
    删除单条考试记录（管理员可访问）
    
    会同时删除关联的错题记录
    """
    try:
        # 权限检查 - 仅管理员可删除
        if current_user.role != 'admin':
            return ResponseModel(code=403, message="无权操作，仅管理员可删除考试记录", data=None)
        
        # 查询考试记录
        result = await db.execute(
            select(Exam).where(Exam.id == exam_id)
        )
        exam = result.scalar_one_or_none()
        
        if not exam:
            return ResponseModel(code=404, message="考试记录不存在", data=None)
        
        # 删除关联的错题记录
        await db.execute(
            delete(ExamMistake).where(ExamMistake.exam_id == exam_id)
        )
        
        # 删除考试记录
        await db.delete(exam)
        await db.commit()
        
        logger.info(f"管理员 {current_user.username} 删除了考试记录 {exam_id}")
        
        return ResponseModel(
            code=200,
            message="考试记录已删除",
            data={"deleted_id": exam_id}
        )
    
    except Exception as e:
        await db.rollback()
        logger.error(f"删除考试记录失败: {e}", exc_info=True)
        return ResponseModel(code=500, message=f"删除考试记录失败: {str(e)}", data=None)


@router.delete("/batch/delete", response_model=ResponseModel)
async def batch_delete_exam_records(
    request: BatchDeleteRequest,
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
) -> ResponseModel:
    """
    批量删除考试记录（管理员可访问）
    
    会同时删除关联的错题记录
    """
    try:
        # 权限检查 - 仅管理员可删除
        if current_user.role != 'admin':
            return ResponseModel(code=403, message="无权操作，仅管理员可删除考试记录", data=None)
        
        if not request.ids:
            return ResponseModel(code=400, message="请选择要删除的记录", data=None)
        
        # 查询存在的考试记录
        result = await db.execute(
            select(Exam.id).where(Exam.id.in_(request.ids))
        )
        existing_ids = [row[0] for row in result.all()]
        
        if not existing_ids:
            return ResponseModel(code=404, message="未找到要删除的记录", data=None)
        
        # 删除关联的错题记录
        await db.execute(
            delete(ExamMistake).where(ExamMistake.exam_id.in_(existing_ids))
        )
        
        # 删除考试记录
        await db.execute(
            delete(Exam).where(Exam.id.in_(existing_ids))
        )
        await db.commit()
        
        deleted_count = len(existing_ids)
        logger.info(f"管理员 {current_user.username} 批量删除了 {deleted_count} 条考试记录")
        
        return ResponseModel(
            code=200,
            message=f"成功删除 {deleted_count} 条考试记录",
            data={
                "deleted_count": deleted_count,
                "deleted_ids": existing_ids
            }
        )
    
    except Exception as e:
        await db.rollback()
        logger.error(f"批量删除考试记录失败: {e}", exc_info=True)
        return ResponseModel(code=500, message=f"批量删除考试记录失败: {str(e)}", data=None)

