package cn.iocoder.yudao.module.base.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.iocoder.yudao.module.base.entity.DlDriveSchoolStudent;
import cn.iocoder.yudao.module.base.mapper.DlDriveSchoolStudentMapper;
import cn.iocoder.yudao.module.base.service.DataViewService;
import cn.iocoder.yudao.module.base.service.DlDriveSchoolCoachService;
import cn.iocoder.yudao.module.base.service.DlDriveSchoolStudentService;
import cn.iocoder.yudao.module.base.vo.*;
import cn.iocoder.yudao.module.course.entity.Process;
import cn.iocoder.yudao.module.course.entity.SchoolCommission;
import cn.iocoder.yudao.module.course.entity.SchoolCourseOrder;
import cn.iocoder.yudao.module.course.mapper.ProcessMapper;
import cn.iocoder.yudao.module.course.mapper.SchoolCommissionMapper;
import cn.iocoder.yudao.module.course.mapper.SchoolCourseOrderMapper;
import cn.iocoder.yudao.module.course.service.ProcessService;
import cn.iocoder.yudao.module.exam.mapper.ExamBatchItemMapper;
import cn.iocoder.yudao.module.exam.service.ExamBatchItemService;
import cn.iocoder.yudao.module.exam.vo.ExamBatchItemVO;
import cn.iocoder.yudao.module.train.entity.Train;
import cn.iocoder.yudao.module.train.mapper.TrainMapper;
import cn.iocoder.yudao.module.train.service.TrainService;
import cn.iocoder.yudao.module.train.vo.TrainVO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Validated
public class DataViewServiceImpl implements DataViewService {
    @Autowired
    private DlDriveSchoolStudentService studentService;
    @Autowired
    private DlDriveSchoolStudentMapper studentMapper;
    @Autowired
    private DlDriveSchoolCoachService coachService;
    @Autowired
    private ProcessService processService;
    @Autowired
    private ProcessMapper processMapper;
    @Autowired
    private TrainService trainService;
    @Autowired
    private TrainMapper trainMapper;
    @Autowired
    private ExamBatchItemService examBatchItemService;
    @Autowired
    private ExamBatchItemMapper examBatchItemMapper;
    @Autowired
    private SchoolCourseOrderMapper courseOrderMapper;
    @Autowired
    private SchoolCommissionMapper commissionMapper;

    /**
     * 查询学员详情
     *
     * @param id 学生id
     * @return cn.iocoder.yudao.module.base.vo.StudentInfoVO
     * @author vinjor-M
     * @date 14:37 2025/2/8
     **/
    @Override
    public StudentInfoVO selectStudentInfo(Long id,Long coachId) {
        StudentInfoVO studentInfoVO = new StudentInfoVO();

        // 学员主信息
        DlDriveSchoolStudent student = studentService.getStudentByUserId(id);
        studentInfoVO.setStudentInfo(student);

        // 查询学员订单信息
        SchoolCourseOrder orderInfo = courseOrderMapper.getOrderInfo(id);
        studentInfoVO.setStudentOrderInfo(orderInfo);

        // 当前学习进度
        Process process = processService.selectByUserId(id, coachId);
        studentInfoVO.setProcess(process);

        // 学习进度列表
        String courseId = "";
        if (orderInfo != null && orderInfo.getCourseId() != null) {
            courseId = orderInfo.getCourseId();
        }
        List<Process> processList = processMapper.getProcessList(id, courseId);
        studentInfoVO.setProcessList(processList != null ? processList : new ArrayList<>());

        // 查这个课程累计总训练时长
        if (process != null && process.getCourseId() != null) {
            studentInfoVO.setTrainTime(processService.getAllTrainTime(id, process.getCourseId()));
        } else {
            studentInfoVO.setTrainTime(0.0);
        }

        // 查归属教练信息
        if (process != null && process.getCoachId() != null) {
            DlDriveSchoolCoachRespVO coachRespVO = coachService.getDlDriveSchoolCoachByUserId(process.getCoachId());
            if (coachRespVO != null) {
                coachRespVO.setDataMap(processService.selectByCoachId(coachRespVO.getUserId()));
                studentInfoVO.setCoachInfo(coachRespVO);
            }
        }

        // 查该学生的培训记录
        List<Train> trainList = trainService.selectByUserIdAndCoachId(id, coachId);
        if (trainList != null) {
            trainList.forEach(item -> item.setShowMore(false));
            studentInfoVO.setTrainList(trainList);
        } else {
            studentInfoVO.setTrainList(new ArrayList<>());
        }

        // 查该学生的考试记录
        List<ExamBatchItemVO> examList = examBatchItemService.selectByUserIdAndCoachId(id, coachId);
        if (examList != null) {
            examList.forEach(item -> item.setShowMore(false));
            studentInfoVO.setExamList(examList);
        } else {
            studentInfoVO.setExamList(new ArrayList<>());
        }

        return studentInfoVO;

        /*StudentInfoVO studentInfoVO = new StudentInfoVO();
        //学员主信息
        DlDriveSchoolStudent student = studentService.getStudentByUserId(id);
        studentInfoVO.setStudentInfo(student);
        // 查询学员订单信息
        SchoolCourseOrder orderInfo = courseOrderMapper.getOrderInfo(id);
        studentInfoVO.setStudentOrderInfo(orderInfo);
        //当前学习进度
        Process process = processService.selectByUserId(id,coachId);
        studentInfoVO.setProcess(process);
        // 学习进度列表
        String courseId="";
        if(orderInfo != null){
            courseId = orderInfo.getCourseId();
        }
        List<Process> processList = processMapper.getProcessList(id,courseId);
        if (processList != null) {
            studentInfoVO.setProcessList(processList);
        } else {
            studentInfoVO.setProcessList(null);;
        }
        //查这个课程累计总训练时长
        studentInfoVO.setTrainTime(processService.getAllTrainTime(id,process.getCourseId()));
        //查归属教练信息
        DlDriveSchoolCoachRespVO coachRespVO = coachService.getDlDriveSchoolCoachByUserId(process.getCoachId());
        if(null!=coachRespVO){
            //有教练，查未毕业学员、已毕业学员，区分科目
            coachRespVO.setDataMap(processService.selectByCoachId(coachRespVO.getUserId()));
            studentInfoVO.setCoachInfo(coachRespVO);
        }
        //查该学生的培训记录
        List<Train> trainList = trainService.selectByUserIdAndCoachId(id,coachId);
        trainList.forEach(item-> item.setShowMore(false));
        studentInfoVO.setTrainList(trainList);
        //查该学生的考试记录
        List<ExamBatchItemVO> examList = examBatchItemService.selectByUserIdAndCoachId(id, coachId);
        examList.forEach(item->item.setShowMore(false));
        studentInfoVO.setExamList(examList);
        return studentInfoVO;*/
    }

    /**
     * 首页数据统计查询接口 --
     *
     * @param type      查询类型（coach-教练查询|admin-管理员查询）
     * @param timeType  时间查询类型（all-全部|day-当日|month-当月|more-自定义）
     * @param coachId   教练id
     * @param startTime 查询时间范围--开始
     * @param endTime   查询时间范围--结束
     * @author vinjor-M
     * @date 14:12 2025/2/14
     **/
    @Override
    public IndexDataVO selectIndexInfo(String type, String timeType, Long coachId, String startTime, String endTime) {
        IndexDataVO rtnObj = new IndexDataVO();
        DecimalFormat df = new DecimalFormat("#.00");
        //默认查全部数据
        String startTimeStr = "";
        String endTimeStr = "";
        if("more".equals(timeType)){
            if(StringUtils.isNotEmpty(startTime)){
                startTimeStr = startTime+" 00:00:01";
            }
            if(StringUtils.isNotEmpty(endTime)) {
                endTimeStr = endTime + " 23:59:59";
            }
        }else if("month".equals(timeType)){
            //当月
            startTimeStr = DateUtil.format(DateUtil.beginOfMonth(DateUtil.date()),"yyyy-MM-dd")+" 00:00:01";
            endTimeStr = DateUtil.format(DateUtil.endOfMonth(DateUtil.date()),"yyyy-MM-dd")+" 23:59:59";
        }else if("day".equals(timeType)){
            //当天
            startTimeStr = DateUtil.formatDate(DateUtil.date())+" 00:00:01";
            endTimeStr = DateUtil.formatDate(DateUtil.date())+" 23:59:59";
        }
        if("admin".equals(type)){
            //管理员查询
            /*1.招生情况*/
            List<DlDriveSchoolStudentVO> studentList = studentMapper.selectStudentList(coachId, startTimeStr, endTimeStr);
            Map<String,Object> studentInfoMap = new HashMap<>();
            int coachNum=0;
            double coachAmount=0;
            int schoolNum=0;
            double schoolAmount=0;
            for (DlDriveSchoolStudentVO item:studentList){
                if("02".equals(item.getSource())){
                    //教练自招
                    coachNum++;
                    coachAmount = coachAmount+item.getPriceAmount();
                }else{
                    //驾校统招
                    schoolNum++;
                    schoolAmount = schoolAmount+item.getPriceAmount();
                }
            }
            int allNum = coachNum+schoolNum;
            double coachRate=0;
            double schoolRate=0;
            if(allNum>0){
                if(coachNum>0){
                    coachRate = (double)coachNum / allNum;
                }
                if(schoolNum>0){
                    schoolRate = (double)schoolNum / allNum;
                }
            }
            studentInfoMap.put("coachNum", new BigDecimal(coachNum).setScale(2, RoundingMode.HALF_UP));
            studentInfoMap.put("coachAmount", new BigDecimal(coachAmount).setScale(2, RoundingMode.HALF_UP));
            studentInfoMap.put("coachRate",0!=coachRate?(Double.parseDouble(df.format(coachRate))*100):0);
            studentInfoMap.put("schoolNum",schoolNum);
            studentInfoMap.put("schoolAmount",schoolAmount);
            studentInfoMap.put("schoolRate",0!=schoolRate?(Double.parseDouble(df.format(schoolRate))*100):0);
            rtnObj.setStudentInfo(studentInfoMap);
            /*4.财务情况--*/
            //应收
            Double showedReceive = courseOrderMapper.selectByCoachUserId(coachId,startTimeStr,endTimeStr);
            //应付
            List<SchoolCommission> schoolCommissionList = commissionMapper.selectByCoachId(coachId,startTimeStr,endTimeStr);
            double showedPay =0.0;
            for (SchoolCommission item:schoolCommissionList){
                if(null!=item.getCommissionAmount()){
                    showedPay =showedPay+item.getCommissionAmount().doubleValue();
                }
            }
            Map<String,Object> moneyInfoMap = new HashMap<>();
            moneyInfoMap.put("inAmount",null==showedReceive?0:showedReceive);
            moneyInfoMap.put("outAmount",showedPay);
            rtnObj.setMoneyInfo(moneyInfoMap);
        }else if("coach".equals(type)){
            //教练查询
            /*1.学员情况*/
            List<DlDriveSchoolStudentVO> studentVOList = studentMapper.selectStudentListCoach(coachId,startTimeStr,endTimeStr);
            int overNum = (int) studentVOList.stream().filter(item -> null != item.getOrderGradTime()).count();
            int noOverNum = studentVOList.size()-overNum;
            // 按 courseType（C1/C2）统计
            long c1Total = studentVOList.stream().filter(item -> "C1".equals(item.getCourseType())).count();
            long c2Total = studentVOList.stream().filter(item -> "C2".equals(item.getCourseType())).count();
            Map<String,Object> studentInfoMap = new HashMap<>();
            studentInfoMap.put("allNum",studentVOList.size());
            studentInfoMap.put("overNum",overNum);
            studentInfoMap.put("noOverNum",noOverNum);
            studentInfoMap.put("c1Total", c1Total);
            studentInfoMap.put("c2Total", c2Total);
            rtnObj.setStudentInfo(studentInfoMap);
            /*4.财务情况-查教练自己应得的提成-*/
            List<SchoolCommission> schoolCommissionList = commissionMapper.selectByCoachId(coachId,startTimeStr,endTimeStr);
            double showedPay =0.0;
            for (SchoolCommission item:schoolCommissionList){
                if(null!=item.getCommissionAmount()){
                    showedPay =showedPay+item.getCommissionAmount().doubleValue();
                }
            }
            Map<String,Object> moneyInfoMap = new HashMap<>();
            moneyInfoMap.put("money",showedPay);
            rtnObj.setMoneyInfo(moneyInfoMap);
        }else if("business".equals(type)){
            //业务经理查询
            /*1.招生情况*/
            List<DlDriveSchoolStudentVO> studentVOList = studentMapper.selectStudentListBusiness(coachId,startTimeStr,endTimeStr);
            int overNum = (int) studentVOList.stream().filter(item -> null != item.getOrderGradTime()).count();
            int noOverNum = studentVOList.size()-overNum;
            // 按 courseType（C1/C2）统计
            long c1Total = studentVOList.stream().filter(item -> "C1".equals(item.getCourseType())).count();
            long c2Total = studentVOList.stream().filter(item -> "C2".equals(item.getCourseType())).count();
            Map<String,Object> studentInfoMap = new HashMap<>();
            studentInfoMap.put("allNum",studentVOList.size());
            studentInfoMap.put("overNum",overNum);
            studentInfoMap.put("noOverNum",noOverNum);
            studentInfoMap.put("c1Total", c1Total);
            studentInfoMap.put("c2Total", c2Total);
            rtnObj.setStudentInfo(studentInfoMap);
            /*4.财务情况-查教练自己应得的提成-*/
            List<SchoolCommission> schoolCommissionList = commissionMapper.selectByCoachId(coachId,startTimeStr,endTimeStr);
            double showedPay =0.0;
            for (SchoolCommission item:schoolCommissionList){
                if(null!=item.getCommissionAmount()){
                    showedPay =showedPay+item.getCommissionAmount().doubleValue();
                }
            }
            Map<String,Object> moneyInfoMap = new HashMap<>();
            moneyInfoMap.put("money",showedPay);
            rtnObj.setMoneyInfo(moneyInfoMap);
        }
        /*2.训练情况*/
        List<TrainVO> allTrainList = trainMapper.selectTrainByCondition(coachId,startTimeStr,endTimeStr);
        //所有车辆set，目的是去重
        Set<String> allCarSet = new HashSet<>();
        Set<String> subject2CarSet = new HashSet<>();
        Set<String> subject3CarSet = new HashSet<>();
        Set<Long> allUserSet = new HashSet<>();
        Set<Long> subject2UserSet = new HashSet<>();
        Set<Long> subject3UserSet = new HashSet<>();
        for (TrainVO trainVO:allTrainList){
            if(2==trainVO.getSubject()){
                subject2CarSet.add(trainVO.getCarNo());
                allCarSet.add(trainVO.getCarNo());
                subject2UserSet.add(trainVO.getUserId());
                allUserSet.add(trainVO.getUserId());
            }else if(3==trainVO.getSubject()){
                subject3CarSet.add(trainVO.getCarNo());
                allCarSet.add(trainVO.getCarNo());
                subject3UserSet.add(trainVO.getUserId());
                allUserSet.add(trainVO.getUserId());
            }
        }
        Map<String,Object> trainInfoMap = new HashMap<>();
        trainInfoMap.put("allCarNum",allCarSet.size());
        trainInfoMap.put("subject2CarNum",subject2CarSet.size());
        trainInfoMap.put("subject3CarNum",subject3CarSet.size());
        trainInfoMap.put("allUserNum",allUserSet.size());
        trainInfoMap.put("subject2UserNum",subject2UserSet.size());
        trainInfoMap.put("subject3UserNum",subject3UserSet.size());
        rtnObj.setTrainInfo(trainInfoMap);
        /*3.考试情况*/
        List<ExamBatchItemVO> examBatchItemVOList = examBatchItemMapper.selectByCoachId(coachId,startTimeStr,endTimeStr);
        Double subject2Num = 0.0;
        Double subject3Num = 0.0;
        Double subject2PassNum = 0.0;
        Double subject3PassNum = 0.0;
        for (ExamBatchItemVO exam:examBatchItemVOList){
            if(2==exam.getSubject()){
                subject2Num++;
                if(null!=exam.getIfPass() && exam.getIfPass()){
                    //考试通过
                    subject2PassNum++;
                }
            }else if(3==exam.getSubject()){
                subject3Num++;
                if(null!=exam.getIfPass() && exam.getIfPass()){
                    //考试通过
                    subject3PassNum++;
                }
            }
        }
        double subject2Rate=0;
        double subject3Rate=0;
        if(0!=subject2Num && 0!=subject2PassNum){
            subject2Rate = subject2PassNum / subject2Num;
        }
        if(0!=subject3Num && 0!=subject3PassNum){
            subject3Rate = subject3PassNum / subject3Num;
        }
        Map<String,Object> examInfoMap = new HashMap<>();
        examInfoMap.put("subject2All",subject2Num);
        examInfoMap.put("subject2Pass",subject2PassNum);
        examInfoMap.put("subject2Rate",0!=subject2Rate?(Double.parseDouble(df.format(subject2Rate))*100):0);
        examInfoMap.put("subject3All",subject3Num);
        examInfoMap.put("subject3Pass",subject3PassNum);
        examInfoMap.put("subject3Rate",0!=subject3Rate?(Double.parseDouble(df.format(subject3Rate))*100):0);
        rtnObj.setExamInfo(examInfoMap);
        return rtnObj;
    }

    /**
     * 查询学生总数
     *
     * @return java.util.Map<java.lang.String, java.lang.Object>
     * @author vinjor-M
     * @date 15:58 2025/2/25
     **/
    @Override
    public Map<String, Object> getStudentCount() {
        List<DlDriveSchoolStaffVO> list= studentMapper.selectStudentListCount();
        Map<String, Object> rtnMap = new HashMap<>();
        rtnMap.put("all",list.size());
        //按courseType分组
        Map<String, List<DlDriveSchoolStaffVO>> map = list.stream()
                .filter(item -> item.getCourseType() != null)  // 过滤掉 courseType 为 null 的元素
                .collect(Collectors.groupingBy(DlDriveSchoolStaffVO::getCourseType));

        for (String key:map.keySet()){
            rtnMap.put(key,map.get(key).size());
        }
        return rtnMap;
    }
}
