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

import cn.hutool.core.date.DateUtil;
import cn.iocoder.yudao.module.base.constant.SchoolBaseConstants;
import cn.iocoder.yudao.module.base.entity.DlDriveSchoolCoach;
import cn.iocoder.yudao.module.base.service.SchoolNotifyMessageSendService;
import cn.iocoder.yudao.module.base.vo.BusinessRecordExportVO;
import cn.iocoder.yudao.module.course.entity.Process;
import cn.iocoder.yudao.module.train.entity.DriveSchoolCoachClock;
import cn.iocoder.yudao.module.train.entity.Train;
import cn.iocoder.yudao.module.train.mapper.DriveSchoolCoachClockMapper;
import cn.iocoder.yudao.module.train.mapper.TrainMapper;
import cn.iocoder.yudao.module.train.service.IDriveSchoolCoachClockService;
import cn.iocoder.yudao.module.train.vo.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

/**
 * 教练打卡表 服务实现类
 *
 * @author author
 * @since 2025-07-16
 */
@Service
public class DriveSchoolCoachClockServiceImpl extends ServiceImpl<DriveSchoolCoachClockMapper, DriveSchoolCoachClock> implements IDriveSchoolCoachClockService {

    @Resource
    private DriveSchoolCoachClockMapper driveSchoolCoachClockMapper;

    @Resource
    private TrainMapper trainMapper;

    @Resource
    private SchoolNotifyMessageSendService schoolNotifyMessageSendService;



    /**
     * 获得教练打卡记录分页
     *
     * @param pageReqVO
     * @param page
     * @return
     */
    @Override
    public IPage<DriveSchoolCoachClockVO> queryListPage(DriveSchoolCoachClockVO pageReqVO, Page<DriveSchoolCoachClockVO> page) {
        String startTime = "";
        String endTime = "";
        if ("more".equals(pageReqVO.getTimeType())) {
            if (org.apache.commons.lang3.StringUtils.isNotEmpty(pageReqVO.getStartTimeStr())) {
                startTime = pageReqVO.getStartTimeStr();
            }
            if (org.apache.commons.lang3.StringUtils.isNotEmpty(pageReqVO.getEndTimeStr())) {
                endTime = pageReqVO.getEndTimeStr();
            }
        } else if ("month".equals(pageReqVO.getTimeType())) {
            //当月
            startTime = DateUtil.format(DateUtil.beginOfMonth(DateUtil.date()), "yyyy-MM-dd");
            endTime = DateUtil.format(DateUtil.endOfMonth(DateUtil.date()), "yyyy-MM-dd");
        } else if ("day".equals(pageReqVO.getTimeType())) {
            //当天
            startTime = DateUtil.formatDate(DateUtil.date());
            endTime = DateUtil.formatDate(DateUtil.date());
        }
        pageReqVO.setStartTimeStr(startTime);
        pageReqVO.setEndTimeStr(endTime);
        return driveSchoolCoachClockMapper.queryListPage(pageReqVO, page);
    }

    /**
     * 查询今天未离场的打卡记录
     */
    @Override
    public DriveSchoolCoachClock selectTodayClockRecord(Long userId,String carNo) {
        if (userId == null) {
            throw new IllegalArgumentException("用户ID不能为空");
        }
        List<DriveSchoolCoachClock> clockRecord = driveSchoolCoachClockMapper.selectList(
                new LambdaQueryWrapper<DriveSchoolCoachClock>()
                        .eq(DriveSchoolCoachClock::getUserId, userId)
                        .eq(DriveSchoolCoachClock::getCarNo,carNo)
                        .eq(DriveSchoolCoachClock::getTrainDay, DateUtil.format(new Date(), "yyyy-MM-dd"))
                        .isNull(DriveSchoolCoachClock::getEndTime)
                        .eq(DriveSchoolCoachClock::getDeleted, 0)
                        .orderByDesc(DriveSchoolCoachClock::getCreateTime)
        );
        if (!clockRecord.isEmpty()) {
            return clockRecord.get(0);
        }else{
            return null;
        }

    }

    /**
     * 到场打卡
     **/
    @Override
    public String createObj(DriveSchoolCoachClockVO coachClockVO) {
        coachClockVO.setTrainDay(DateUtil.format(new Date(), "yyyy-MM-dd"));
        this.save(coachClockVO);
        return coachClockVO.getId();
    }

    /**
     * 离场打卡
     **/
    @Override
    public void updateObj(DriveSchoolCoachClockVO coachClockVO) {
        // 如果同时存在开始和结束时间，计算时长
        /*LocalDateTime startTime = coachClockVO.getStartTime();
        LocalDateTime endTime = coachClockVO.getEndTime();

        if (startTime != null && endTime != null && endTime.isAfter(startTime)) {
            // 计算时间差，单位为分钟
            long minutes = Duration.between(startTime, endTime).toMinutes();
            coachClockVO.setTrainTime((double) minutes);
        }*/
        this.updateById(coachClockVO);
    }


    /**
     * 统计训练车辆台次
     */
    @Override
    public TrainCarCountVO countTrainCar(TrainCarCountVO trainCarCountVO) {
        String startTime = "";
        String endTime = "";
        if ("more".equals(trainCarCountVO.getTimeType())) {
            if (StringUtils.isNotEmpty(trainCarCountVO.getTrainDayStartTime())) {
                startTime = trainCarCountVO.getTrainDayStartTime();
            }
            if (StringUtils.isNotEmpty(trainCarCountVO.getTrainDayEndTime())) {
                endTime = trainCarCountVO.getTrainDayEndTime();
            }
        } else if ("month".equals(trainCarCountVO.getTimeType())) {
            //当月
            startTime = DateUtil.format(DateUtil.beginOfMonth(DateUtil.date()), "yyyy-MM-dd");
            endTime = DateUtil.format(DateUtil.endOfMonth(DateUtil.date()), "yyyy-MM-dd");
        } else if ("day".equals(trainCarCountVO.getTimeType())) {
            //当天
            startTime = DateUtil.formatDate(DateUtil.date());
            endTime = DateUtil.formatDate(DateUtil.date());
        }
        trainCarCountVO.setTrainDayStartTime(startTime);
        trainCarCountVO.setTrainDayEndTime(endTime);

        return driveSchoolCoachClockMapper.countTrainCar(trainCarCountVO);
    }

    /**
     * 车辆列表
     * @param trainCarCountVO
     * @return
     */
    @Override
    public List<TrainCarCountVO> trainClockByCar(TrainCarCountVO trainCarCountVO) {
        String startTime = "";
        String endTime = "";
        if ("more".equals(trainCarCountVO.getTimeType())) {
            if (StringUtils.isNotEmpty(trainCarCountVO.getTrainDayStartTime())) {
                startTime = trainCarCountVO.getTrainDayStartTime();
            }
            if (StringUtils.isNotEmpty(trainCarCountVO.getTrainDayEndTime())) {
                endTime = trainCarCountVO.getTrainDayEndTime();
            }
        } else if ("month".equals(trainCarCountVO.getTimeType())) {
            //当月
            startTime = DateUtil.format(DateUtil.beginOfMonth(DateUtil.date()), "yyyy-MM-dd");
            endTime = DateUtil.format(DateUtil.endOfMonth(DateUtil.date()), "yyyy-MM-dd");
        } else if ("day".equals(trainCarCountVO.getTimeType())) {
            //当天
            startTime = DateUtil.formatDate(DateUtil.date());
            endTime = DateUtil.formatDate(DateUtil.date());
        }
        trainCarCountVO.setTrainDayStartTime(startTime);
        trainCarCountVO.setTrainDayEndTime(endTime);

        return driveSchoolCoachClockMapper.trainClockByCar(trainCarCountVO);
    }

    /**
     * 车辆打卡训练详细信息，包含打卡基本信息和学员信息
     */
    @Override
    public List<TrainDetailsByCarVO> trainClockByCarDetail(TrainDetailsByCarVO trainDetailsByCarVO) {
        String startTime = "";
        String endTime = "";
        if ("more".equals(trainDetailsByCarVO.getTimeType())) {
            if (StringUtils.isNotEmpty(trainDetailsByCarVO.getTrainDayStartTime())) {
                startTime = trainDetailsByCarVO.getTrainDayStartTime();
            }
            if (StringUtils.isNotEmpty(trainDetailsByCarVO.getTrainDayEndTime())) {
                endTime = trainDetailsByCarVO.getTrainDayEndTime();
            }
        } else if ("month".equals(trainDetailsByCarVO.getTimeType())) {
            //当月
            startTime = DateUtil.format(DateUtil.beginOfMonth(DateUtil.date()), "yyyy-MM-dd");
            endTime = DateUtil.format(DateUtil.endOfMonth(DateUtil.date()), "yyyy-MM-dd");
        } else if ("day".equals(trainDetailsByCarVO.getTimeType())) {
            //当天
            startTime = DateUtil.formatDate(DateUtil.date());
            endTime = DateUtil.formatDate(DateUtil.date());
        }
        trainDetailsByCarVO.setTrainDayStartTime(startTime);
        trainDetailsByCarVO.setTrainDayEndTime(endTime);
        List<DriveSchoolCoachClock> coachClockList = driveSchoolCoachClockMapper.selectCoachClockIdsByCarId(trainDetailsByCarVO);
        if (CollectionUtils.isEmpty(coachClockList)) {
            return Collections.emptyList();
        }
        List<TrainDetailsByCarVO> trainDetailsByCarVOList = new ArrayList<>();
            for (DriveSchoolCoachClock driveSchoolCoachClock : coachClockList) {
                TrainDetailsByCarVO trainDetailsByCarVOAll = new TrainDetailsByCarVO();
                trainDetailsByCarVOAll.setCarId(driveSchoolCoachClock.getCarId());
                trainDetailsByCarVOAll.setCarNo(driveSchoolCoachClock.getCarNo());
                trainDetailsByCarVOAll.setTrainDay(driveSchoolCoachClock.getTrainDay());
                trainDetailsByCarVOAll.setUserId(driveSchoolCoachClock.getUserId());
                trainDetailsByCarVOAll.setUserName(driveSchoolCoachClock.getUserName());
                trainDetailsByCarVOAll.setSubject(driveSchoolCoachClock.getSubject());
                trainDetailsByCarVOAll.setStartTime(driveSchoolCoachClock.getStartTime());
                trainDetailsByCarVOAll.setEndTime(driveSchoolCoachClock.getEndTime());
                trainDetailsByCarVOAll.setTrainTime(driveSchoolCoachClock.getTrainTime());

                List<Train> trains = trainMapper.selectStudentByCoachClockId(driveSchoolCoachClock.getId());
                for (Train train : trains) {
                    List<Train> trainVOList = new ArrayList<>();
                    trainVOList.add(train);
                    trainDetailsByCarVOAll.setTrainVOList(trainVOList);
                }
                trainDetailsByCarVOList.add(trainDetailsByCarVOAll);
            }

        return trainDetailsByCarVOList;
    }

    @Override
    public CloakAndTrainCountVO getCloakAndTrainCount(CloakAndTrainCountVO cloakAndTrainCountVO) {
        String startTime = "";
        String endTime = "";
        if ("more".equals(cloakAndTrainCountVO.getTimeType())) {
            if (StringUtils.isNotEmpty(cloakAndTrainCountVO.getTrainStartTimeStr())) {
                startTime = cloakAndTrainCountVO.getTrainStartTimeStr();
            }
            if (StringUtils.isNotEmpty(cloakAndTrainCountVO.getTrainEndTimeStr())) {
                endTime = cloakAndTrainCountVO.getTrainEndTimeStr();
            }
        } else if ("month".equals(cloakAndTrainCountVO.getTimeType())) {
            //当月
            startTime = DateUtil.format(DateUtil.beginOfMonth(DateUtil.date()), "yyyy-MM-dd");
            endTime = DateUtil.format(DateUtil.endOfMonth(DateUtil.date()), "yyyy-MM-dd");
        } else if ("day".equals(cloakAndTrainCountVO.getTimeType())) {
            //当天
            startTime = DateUtil.formatDate(DateUtil.date());
            endTime = DateUtil.formatDate(DateUtil.date());
        }
        cloakAndTrainCountVO.setTrainStartTimeStr(startTime);
        cloakAndTrainCountVO.setTrainEndTimeStr(endTime);

        CloakAndTrainCountVO trainStudentCount = driveSchoolCoachClockMapper.getTrainStudentCount(cloakAndTrainCountVO);
        CloakAndTrainCountVO trainCarCount = driveSchoolCoachClockMapper.getTrainCarCount(cloakAndTrainCountVO);
        CloakAndTrainCountVO returnCount = new CloakAndTrainCountVO();
        returnCount.setTotalStudentCount(trainStudentCount.getTotalStudentCount());
        returnCount.setSubject2StudentCount(trainStudentCount.getSubject2StudentCount());
        returnCount.setSubject3StudentCount(trainStudentCount.getSubject3StudentCount());
        returnCount.setTotalCarCount(trainCarCount.getTotalCarCount());
        returnCount.setSubject2CarCount(trainCarCount.getSubject2CarCount());
        returnCount.setSubject3CarCount(trainCarCount.getSubject3CarCount());

        return returnCount;
    }


    /**
     * 每天晚上7点提醒未进行离场打卡的教练进行打卡
     */
    @Override
    public void noClockInRemind() {
        List<DriveSchoolCoachClock> driveSchoolCoachClockList = driveSchoolCoachClockMapper.noClockInRemind();
        for (DriveSchoolCoachClock driveSchoolCoachClock : driveSchoolCoachClockList) {
            String message = String.format(SchoolBaseConstants.SCHOOL_NOTIFY_MESSAGE_TEMPLATE_MEMBER_NOT_ATTENDANCE_TODAY, driveSchoolCoachClock.getCarNo());
                schoolNotifyMessageSendService.sendMessage(driveSchoolCoachClock.getUserId(), message, SchoolBaseConstants.SCHOOL_NOTIFY_MESSAGE_TYPE_ADMIN, driveSchoolCoachClock.getTenantId());
        }
    }


    /**
     * 导出数据获取
     */
    @Override
    public IPage<CoachClockExportVO> coachClockAll(CoachClockExportVO exportVO, Page<CoachClockExportVO> page) {
        String startTime = "";
        String endTime = "";

        if ("more".equals(exportVO.getTimeType())) {
            if (StringUtils.isNotEmpty(exportVO.getTrainStartTimeStr())) {
                startTime = exportVO.getTrainStartTimeStr();
            }
            if (StringUtils.isNotEmpty(exportVO.getTrainEndTimeStr())) {
                endTime = exportVO.getTrainEndTimeStr();
            }
        } else if ("month".equals(exportVO.getTimeType())) {
            //当月
            startTime = DateUtil.format(DateUtil.beginOfMonth(DateUtil.date()), "yyyy-MM-dd");
            endTime = DateUtil.format(DateUtil.endOfMonth(DateUtil.date()), "yyyy-MM-dd");
        } else if ("day".equals(exportVO.getTimeType())) {
            //当天
            startTime = DateUtil.formatDate(DateUtil.date());
            endTime = DateUtil.formatDate(DateUtil.date());
        }

        exportVO.setTrainStartTimeStr(startTime);
        exportVO.setTrainEndTimeStr(endTime);

        IPage<CoachClockExportVO> coachClockExportVOIPage = driveSchoolCoachClockMapper.coachClockExport(exportVO, page);
        List<CoachClockExportVO> records = coachClockExportVOIPage.getRecords();

        List<CoachClockExportVO> resultList = new ArrayList<>(records.size());

        for (CoachClockExportVO record : records) {
            List<Train> studentTrainList = trainMapper.selectStudentByCoachClockId(record.getId());
            CoachClockExportVO resultVO = new CoachClockExportVO();
            BeanUtils.copyProperties(record, resultVO);
            resultVO.setStudentTrainList(studentTrainList);

            resultList.add(resultVO);
        }

        return coachClockExportVOIPage.setRecords(resultList);
    }


    /**
     * 导出的三种形式
     * @param exportVO
     * @return
     */
    @Override
    public List<CoachClockExportVO> getCoachClockRecordList(CoachClockExportVO exportVO) {
        Page<CoachClockExportVO> page = new Page<>(exportVO.getPageNo(), exportVO.getPageSize());
        IPage<CoachClockExportVO> result = driveSchoolCoachClockMapper.coachClockExport(exportVO, page);
        List<CoachClockExportVO> records = result.getRecords();

        // 对每条记录追加 studentTrainList 和 studentTrainStr
        return enrichCoachClockExport(records);
    }

    @Override
    public List<CoachClockExportVO> getAllCoachClockRecordList(CoachClockExportVO exportVO) {
        Page<CoachClockExportVO> page = new Page<>(1, Integer.MAX_VALUE);
        IPage<CoachClockExportVO> result = driveSchoolCoachClockMapper.coachClockExport(exportVO, page);
        List<CoachClockExportVO> records = result.getRecords();

        return enrichCoachClockExport(records);
    }

    @Override
    public List<CoachClockExportVO> getCoachClockListByRange(CoachClockExportVO exportVO) {
        List<CoachClockExportVO> allData = new ArrayList<>();

        for (int i = exportVO.getStartPage(); i <= exportVO.getEndPage(); i++) {
            Page<CoachClockExportVO> page = new Page<>(i, exportVO.getPageSize());
            IPage<CoachClockExportVO> result = driveSchoolCoachClockMapper.coachClockExport(exportVO, page);
            List<CoachClockExportVO> records = result.getRecords();
            allData.addAll(records);

            if (i >= result.getPages()) {
                break;
            }
        }

        return enrichCoachClockExport(allData);
    }

    private List<CoachClockExportVO> enrichCoachClockExport(List<CoachClockExportVO> records) {
        for (CoachClockExportVO record : records) {
            List<Train> studentTrainList = trainMapper.selectStudentByCoachClockId(record.getId());
            record.setStudentTrainList(studentTrainList);

            if (studentTrainList != null && !studentTrainList.isEmpty()) {
                StringBuilder sb = new StringBuilder();
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");

                for (Train train : studentTrainList) {
                    String subjectStr = convertSubjectToStr(train.getSubject());
                    String userName = train.getUserName() != null ? train.getUserName() : "";
                    String carNo = train.getCarNo() != null ? train.getCarNo() : "";
                    String startTimeStr = train.getStartTime() != null ? sdf.format(train.getStartTime()) : "";
                    String endTimeStr = train.getEndTime() != null ? sdf.format(train.getEndTime()) : "";
                    String trainTimeStr = train.getTrainTime() != null ? train.getTrainTime().intValue() + " 分钟" : "0 分钟";

                    // 学员排在科目前面
                    sb.append(" ").append(userName)
                            .append("  |  ").append(subjectStr)
                            .append("  |  ").append(carNo)
                            .append("  |  到场：").append(startTimeStr)
                            .append("  |  离场：").append(endTimeStr)
                            .append("  |  训练时长：").append(trainTimeStr)
                            .append("\n");
                }

                record.setStudentTrainStr(sb.toString().trim());
            }
        }

        return records;
    }

    private String convertSubjectToStr(Integer subject) {
        if (subject == null) {
            return "未知科目";
        }
        switch (subject) {
            case 1: return "科目一";
            case 2: return "科目二";
            case 3: return "科目三";
            case 4: return "科目四";
            default: return "未知科目";
        }
    }


    /**
     * 获取当日实时训练情况
     */
    @Override
    public CloakAndTrainCountVO getTodayTrainSituation() {
        return driveSchoolCoachClockMapper.getTodayTrainSituation();
    }

    /**
     * 获取正在训练的车辆信息
     */
    @Override
    public List<DriveSchoolCoachClockVO> getTodayCarTrainSituation(DriveSchoolCoachClock driveSchoolCoachClock) {
        return driveSchoolCoachClockMapper.getTodayCarTrainSituation(driveSchoolCoachClock);
    }

    /**
     * 根据教练id查询当日打卡记录的车牌号列表
     */
    @Override
    public List<String> getClockCarNoByUserId(Long userId) {
        return driveSchoolCoachClockMapper.getClockCarNoByUserId(userId);
    }

    @Override
    public DriveSchoolCoachClock getClockCarInfoByUserId(Long userId, String carNo) {
        return driveSchoolCoachClockMapper.getClockCarInfoByUserId(userId, carNo);
    }

    /**
     * 获得教练异常打卡记录分页
     *
     * @param pageReqVO
     * @param page
     * @return
     */
    @Override
    public IPage<DriveSchoolCoachClockVO> queryErrorClockListPage(DriveSchoolCoachClockVO pageReqVO, Page<DriveSchoolCoachClockVO> page) {
        String startTime = "";
        String endTime = "";
        if ("more".equals(pageReqVO.getTimeType())) {
            if (org.apache.commons.lang3.StringUtils.isNotEmpty(pageReqVO.getStartTimeStr())) {
                startTime = pageReqVO.getStartTimeStr();
            }
            if (org.apache.commons.lang3.StringUtils.isNotEmpty(pageReqVO.getEndTimeStr())) {
                endTime = pageReqVO.getEndTimeStr();
            }
        } else if ("month".equals(pageReqVO.getTimeType())) {
            //当月
            startTime = DateUtil.format(DateUtil.beginOfMonth(DateUtil.date()), "yyyy-MM-dd");
            endTime = DateUtil.format(DateUtil.endOfMonth(DateUtil.date()), "yyyy-MM-dd");
        } else if ("day".equals(pageReqVO.getTimeType())) {
            //当天
            startTime = DateUtil.formatDate(DateUtil.date());
            endTime = DateUtil.formatDate(DateUtil.date());
        }
        pageReqVO.setStartTimeStr(startTime);
        pageReqVO.setEndTimeStr(endTime);
        return driveSchoolCoachClockMapper.queryErrorClockListPage(pageReqVO, page);
    }

}
