package cn.iocoder.yudao.module.course.controller.admin;

import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
import cn.iocoder.yudao.module.base.entity.DlDriveSchoolStudent;
import cn.iocoder.yudao.module.base.entity.DriveSchoolCourseDeduct;
import cn.iocoder.yudao.module.base.service.DlDriveSchoolCourseDeductService;
import cn.iocoder.yudao.module.base.service.DlDriveSchoolCourseService;
import cn.iocoder.yudao.module.base.service.DlDriveSchoolStudentService;
import cn.iocoder.yudao.module.base.vo.DlDriveSchoolCourseVO;
import cn.iocoder.yudao.module.course.entity.Process;
import cn.iocoder.yudao.module.course.service.ProcessService;
import cn.iocoder.yudao.module.course.service.SchoolCourseOrderService;
import cn.iocoder.yudao.module.course.vo.*;
import cn.iocoder.yudao.module.jx.domain.DriveSchoolDeduct;
import cn.iocoder.yudao.module.jx.service.IDriveSchoolDeductService;
import cn.iocoder.yudao.module.system.service.dict.DictDataService;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.annotation.security.PermitAll;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;

@Tag(name = "管理后台 - 学员课程进度")
@RestController
@RequestMapping("/process")
@Validated
public class ProcessController {

    @Resource
    private ProcessService processService;

    @Resource
    private DlDriveSchoolCourseDeductService driveSchoolCourseDeductService;

    @Resource
    private IDriveSchoolDeductService driveSchoolDeductService;

    @Resource
    private SchoolCourseOrderService schoolCourseOrderService;

    @Resource
    private DlDriveSchoolStudentService schoolStudentService;




    /**
     * 学员课程进度分页查询
     *
     * @param pageReqVO {@link ProcessVO}
     * @param pageNo    分页参数
     * @param pageSize  分页参数
     * @return cn.iocoder.yudao.framework.common.pojo.CommonResult<com.baomidou.mybatisplus.core.metadata.IPage < ?>>
     * @author PQZ
     * @date 15:33 2025/2/17
     **/
    @GetMapping("/page")
    @Operation(summary = "学员课程进度分页")
    public CommonResult<IPage<?>> getDlDriveSchoolCoachPage(ProcessVO pageReqVO,
                                                            @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                                            @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) {
        Page<ProcessVO> page = new Page<>(pageNo, pageSize);
        return success(processService.pageProcess(page, pageReqVO));
    }

    @GetMapping("/newPage")
    @Operation(summary = "学员课程进度分页")
    public CommonResult<IPage<?>> getDlDriveSchoolCoachPageNew(ProcessVO pageReqVO,
                                                            @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                                            @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) {
        Page<ProcessVO> page = new Page<>(pageNo, pageSize);
        return success(processService.pageProcessNew(page, pageReqVO));
    }

    /**
     * 教练查自己带教的课程和科目
     *
     * @return cn.iocoder.yudao.framework.common.pojo.CommonResult<?>
     * @author vinjor-M
     * @date 11:05 2025/1/15
     **/
    @GetMapping("/getMyCourseAndSubject")
    @Operation(summary = "教练查自己带教的课程和科目")
    public CommonResult<?> getMyCourseAndSubject() {
        return success(processService.getMyCourseAndSubject());
    }

    /**
     * 教练查自己带教的课程和科目在训练中的学生
     *
     * @return cn.iocoder.yudao.framework.common.pojo.CommonResult<?>
     * @author vinjor-M
     * @date 11:05 2025/1/15
     **/
    @GetMapping("/getMyCourseStudentPage")
    @Operation(summary = "教练查自己带教的课程和科目在训练中的学生")
    public CommonResult<IPage<?>> getMyCourseStudentPage(Process process,
                                                         @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                                         @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) {
        Page<Process> page = new Page<>(pageNo, pageSize);
        return success(processService.getMyCourseStudentPage(process, page));
    }

    /**
     * 通过id查询学员进度课程
     *
     * @param id 学员课程进度id
     * @return cn.iocoder.yudao.framework.common.pojo.CommonResult<cn.iocoder.yudao.module.base.vo.DlDriveSchoolCoachRespVO>
     * @author PQZ
     * @date 11:28 2025/2/18
     **/
    @GetMapping("/get")
    @Operation(summary = "通过id 查询学员进度课程")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    public CommonResult<ProcessVO> getDlDriveSchoolCoach(@RequestParam("id") String id) {
        ProcessVO dlDriveSchoolCoach = processService.getDlDriveSchoolCoach(id);
        return success(dlDriveSchoolCoach);
    }

    @GetMapping("/getProcessAndBatch")
    @Operation(summary = "通过id 查询学员进度课程及批次信息")
    public CommonResult<ProcessAndExamBatchVO> getProcessAndBatch(@RequestParam("id") String id) {
        ProcessAndExamBatchVO processAndBatch = processService.getProcessAndBatch(id);
        return success(processAndBatch);
    }

    /**
     * 通过uniqueCode查询学员进度课程
     * @return
     */
    @GetMapping("/getByStudentAndCourseByUniqueCode")
    public CommonResult<List<Process>> getByStudentAndCourseByUniqueCode(@RequestParam("uniqueCode") String uniqueCode){
        return success(processService.getByStudentAndCourseByUniqueCode(uniqueCode));
    }

    /**
     * 财务审核
     *
     * @param processVO {@link Process}
     * @return cn.iocoder.yudao.framework.common.pojo.CommonResult<java.lang.Boolean>
     * @author PQZ
     * @date 15:23 2025/2/18
     **/
    @PostMapping("/check")
    @Operation(summary = "财务审核")
    public CommonResult<Boolean> saveSchoolCoach(@Valid @RequestBody ProcessVO processVO) {
        processService.checkProcess(processVO);
        return success(true);
    }

    /**
     * 保存学员课程进度
     *
     * @param request {@link ProcessAddVO}
     * @return cn.iocoder.yudao.framework.common.pojo.CommonResult<java.lang.Boolean>
     */
    @PostMapping("/saveProcess")
    @Operation(summary = "保存学员课程进度")
    public CommonResult<Boolean> saveProcess(@RequestBody ProcessAddVO request) {
        // 订单id和科目集合不能为空
        if (request.getOrderId() == null || request.getProcessList() == null) {
            throw new RuntimeException("订单和科目不能为空");
        }
        processService.saveProcess(request);
        return success(true);
    }

    /**
     * 通过学员id和课程id查询学员课程进度
     *
     * @param userId   学员id
     * @param courseId 课程id
     * @return cn.iocoder.yudao.framework.common.pojo.CommonResult<java.util.List < cn.iocoder.yudao.module.course.vo.ProcessVO>>
     */
    @GetMapping("/getAllByUserIdAndCourseId")
    public CommonResult<?> getAllByUserIdAndCourseId(Long userId, String courseId) {
        return success(processService.getAllByUserIdAndCourseId(userId, courseId));
    }

    /**
     * 教练自招学员，自动分配教练
     */
    @PostMapping("/autoAssignCoach")
    public CommonResult<Boolean> autoAssignCoach(@RequestBody ProcessNewVO requset) {
        processService.autoAssignCoach(requset);
        return success(true);
    }

    /**
     * 在录入成绩处修改教练
     */
    @GetMapping("/updateCoach")
    public CommonResult<Boolean> updateCoachForScoreInput(String id, Long coachId, String coachName){
        return success(processService.updateCoachForScoreInput(id, coachId, coachName));
    }

    /**
     * 已毕业学员统计
     */
    @GetMapping("/getGraduateStudent")
    public CommonResult<?> getGraduateStudent(String courseType){
        return success(processService.getGraduateStudent(courseType));
    }

    /**
     * 未毕业学员统计
     */
    @GetMapping("/getNoGraduateStudent")
    public CommonResult<?> getNoGraduateStudent(String courseType){
        return success(processService.getNoGraduateStudent(courseType));
    }

    /**
     * 获取 科目二/三 通过学员
     */
    @GetMapping("/getPassStudent")
    public CommonResult<IPage<?>> getPassStudent(@RequestParam("subject") int subject,
                                                 @RequestParam("coachId") Long coachId,
                                                 @RequestParam(name = "courseType", required = false) String courseType,
                                                 @RequestParam(name = "name", required = false) String name,
                                                 @RequestParam(name = "sort", required = false) String sort,
                                                 @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                                 @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize){
        Page<ProcessVO> page = new Page<>(pageNo, pageSize);
        return success(processService.getPassStudent(coachId, subject, courseType, name, sort, page));
    }

    /**
     * 导出界面获取数据
     * @param exportVO
     * @param pageNo
     * @param pageSize
     * @return
     */
    @GetMapping("/getProcessExportData")
    public CommonResult<IPage<ProcessExportVO>> getProcessExportData(ProcessExportVO exportVO,
                                                                     @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                                                     @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) {
        Page<ProcessExportVO> page = new Page<>(pageNo, pageSize);
        return success(processService.getProcessExportData(exportVO, page));
    }
    @GetMapping("/getSubjectPassCount")
    public CommonResult<ProcessExportVO> getSubjectPassCount(ProcessExportVO exportVO) {
        return success(processService.getSubjectPassCount(exportVO));
    }


    /**
     * 导出
     * @param exportVO
     * @param response
     * @throws IOException
     */
    @GetMapping("/export")
    public void exportCommission(ProcessExportVO exportVO, HttpServletResponse response) throws IOException {
        // 校验导出类型
        if (exportVO.getExportType() == null || !Arrays.asList("current", "all", "range").contains(exportVO.getExportType())) {
            throw new IllegalArgumentException("无效的导出类型: " + exportVO.getExportType());
        }

        // 根据不同类型查询数据
        List<ProcessExportVO> exportData;
        String fileName = "学员进度记录";

        switch (exportVO.getExportType()) {
            case "current":
                exportData = processService.getProcessList(exportVO);
                fileName += "_第" + exportVO.getPageNo() + "页";
                break;
            case "all":
                exportData = processService.getAllProcessList(exportVO);
                fileName += "_全部数据";
                break;
            case "range":
                exportData = processService.getProcessListByRange(exportVO);
                fileName += "_" + exportVO.getStartPage() + "-" + exportVO.getEndPage() + "页";
                break;
            default:
                throw new IllegalArgumentException("无效的导出类型: " + exportVO.getExportType());
        }
        // 导出Excel
        ExcelUtils.write(response, fileName + ".xlsx", "学员进度记录", ProcessExportVO.class, exportData);
    }


    /**
     * 学员考试合格率计算
     */
    @GetMapping("/getExamPassRate")
    public CommonResult<List<ExamPassRateVO>> getExamPassRate(@RequestParam(name = "subject", required = false) Integer subject,
                                                        @RequestParam(name = "coachId", required = false) Long coachId,
                                                        @RequestParam(name = "timeType", required = false) String timeType,
                                                        @RequestParam(name="startTimeStr", required = false) String startTimeStr,
                                                        @RequestParam(name="endTimeStr", required = false) String endTimeStr) {

        return success(processService.getExamPassRate(subject, coachId, timeType, startTimeStr, endTimeStr));
    }

    /**
     * 学员考试合格率计算
     */
    @GetMapping("/getPassingRateByCoachId")
    public CommonResult<List<CoachExamPassRateVO>> getPassingRateByCoachId(@RequestParam(name = "coachId", required = false) Long coachId,
                                                        @RequestParam(name = "timeType", required = false) String timeType,
                                                        @RequestParam(name="startTimeStr", required = false) String startTimeStr,
                                                        @RequestParam(name="endTimeStr", required = false) String endTimeStr) {

        return success(processService.getPassingRateByCoachId(coachId, timeType, startTimeStr, endTimeStr));
    }

    /**
     * 考试通过率计算获取
     */
    @GetMapping("/getPassedStudentsByCoachAndExamNum")
    public CommonResult<IPage<StudentPassInfoVO>> getPassedStudentsByCoachAndExamNum(@RequestParam(name = "timeType", required = false) String timeType,
                                                                                     @RequestParam(name = "coachId", required = false) Long coachId,
                                                                                     @RequestParam(name = "subject", required = false) Integer subject,
                                                                                     @RequestParam(name = "examNum", required = false) Integer examNum,
                                                                                     @RequestParam(name = "name", required = false) String name,
                                                                                     @RequestParam(name = "courseType", required = false) String courseType,
                                                                                     @RequestParam(name="startTimeStr", required = false) String startTimeStr,
                                                                                     @RequestParam(name="endTimeStr", required = false) String endTimeStr,
                                                                                     @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                                                                     @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) {
        Page<StudentPassInfoVO> page = new Page<>(pageNo, pageSize);
        return success(processService.getPassedStudentsByCoachAndExamNum(timeType, coachId, subject, examNum, name, courseType, startTimeStr, endTimeStr, page));
    }
}
