package com.ruoyi.course.service.impl;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Maps;
import com.ruoyi.RestResponse;
import com.ruoyi.basic.domain.YjStore;
import com.ruoyi.basic.service.YjAppUserService;
import com.ruoyi.basic.service.YjStoreService;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.entity.AppUser;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.AppLoginUser;
import com.ruoyi.common.utils.*;
import com.ruoyi.common.utils.sign.Base64;
import com.ruoyi.course.domain.*;
import com.ruoyi.course.domain.enums.ClaTimeAttendStatusEnums;
import com.ruoyi.course.domain.enums.ClaTimeStatusEnums;
import com.ruoyi.course.domain.enums.CourseChargeTypeEnum;
import com.ruoyi.course.domain.enums.LogTypeEnum;
import com.ruoyi.course.domain.req.ReqSearchClaTime;
import com.ruoyi.course.domain.res.*;
import com.ruoyi.course.domain.time.*;
import com.ruoyi.course.mapper.*;
import com.ruoyi.course.service.IScStudentCourseOrderService;
import com.ruoyi.course.service.ScClaTimeAttendService;
import com.ruoyi.course.service.ScClaTimeService;
import com.ruoyi.im.domain.Friend;
import com.ruoyi.system.domain.SysTeacher;
import com.ruoyi.system.service.ISysDeptService;
import com.ruoyi.system.service.SysTeacherService;
import com.ruoyi.system.service.impl.SysUserServiceImpl;
import org.apache.commons.compress.utils.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestBody;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;
@Service
public class ScClaTimeServiceImpl extends ServiceImpl<ScClaTimeMapper, ScClaTime> implements ScClaTimeService {

    @Autowired
    private ScClaTimeMapper claTimeMapper;

    @Autowired
    private ScStudentCourseMapper studentCourseMapper;


    @Autowired
    private ScBookCourseMapper bookCourseMapper;

    @Autowired
    private ScBookCourseLogMapper bookCourseLogMapper;

    @Autowired
    private ScCourseClaMapper claMapper;

    @Autowired
    private YjStoreService storeService;

    @Autowired
    private ScClaTimeAttendService attendService;

    @Autowired
    private  ScCourseMapper courseMapper;

    @Autowired
    private SysUserServiceImpl sysUserService;

    @Autowired
    private SysTeacherService staffService;

    @Autowired
    private ISysDeptService deptService;

    @Autowired
    private  ScCommissionPlansMapper commissionMapper;

    @Autowired
    private ScRoomMapper roomMapper;

    @Autowired
    private YjAppUserService appUserService;

    @Autowired
    private ScMemberCardsMapper memberCardsMapper;


    /**
     * 按周获取课表
     * @return
     */
    @Override
    public RespBusinessClaTimeCalendar searchListForCalendar(ReqSearchClaTime reqSearchClaTime) {
        Long appUserId=SecurityUtils.getAppLoginUser().getAppUserId();
        AppUser appUser= appUserService.getById(appUserId);
        if (ObjectUtil.isEmpty(appUser.getVisitStore())){
            return null;
        }
        YjStore store=storeService.getOne(appUser.getVisitStore());
        if (ObjectUtil.isEmpty(store)){
            return null;
        }
        if (ObjectUtil.isEmpty(reqSearchClaTime.getTeacherId())){
            if (ObjectUtil.isEmpty(appUser.getVisitStore())){
                return null;
            }
            reqSearchClaTime.setDeptId(appUser.getVisitStore());
        }

        Date cycleBegin = DateUtil.beginOfDay(new Date());//开始时间
        Date cycleEnd = DateUtil.offsetDay(cycleBegin,14);//结束时间
        List<DateTime> dateList=DateUtil.rangeToList(cycleBegin
                , cycleEnd
                , DateField.DAY_OF_YEAR);


        reqSearchClaTime.setBeginDate(DateUtil.format(cycleBegin,"yyyy-MM-dd"));
        reqSearchClaTime.setEndDate(DateUtil.format(cycleEnd,"yyyy-MM-dd"));
        // 获取排课信息
        List<RespClaTimeCalendar> respClaTimeList = claTimeMapper.selectListForCalendar(reqSearchClaTime);

        // 2. 根据返回的 开始时间(startHour) + 时长(claDuration) 自动生成时间段 MAP
        Map<String, String> AUTO_CLA_TIME_MAP = generateTimeMapFromData(respClaTimeList);

        Map<String, Map<Integer, List<RespClaTimeCalendar>>> claTimeCalendarMap = Maps.newHashMap();
        AUTO_CLA_TIME_MAP.forEach((claTimeKey, claTimeValue) -> {
            Map<Integer, List<RespClaTimeCalendar>> halfMonthDayMap = new HashMap();
            for (int i = 0; i < dateList.size(); i++) {
                List<RespClaTimeCalendar> claTimeArrayList = Lists.newArrayList();
                halfMonthDayMap.put(i+1, claTimeArrayList);
            }
            claTimeCalendarMap.put(claTimeKey, halfMonthDayMap);
        });
        // 将排课信息 入到 claTimeCalendarMap
        respClaTimeList.forEach(item -> {
            DateTime day=new DateTime(item.getClaDate());
            Integer halfMonthDay=dateList.indexOf(day)+1;
            String startTime =item.getStartTime();

            if (claTimeCalendarMap.containsKey(startTime)) {
                claTimeCalendarMap.get(startTime).get(halfMonthDay).add(item);
            }
//            else if (claTimeCalendarMap.containsKey(startHour - 1)) {
//                // 每两个小时 一个上课时段，所以-1
//                claTimeCalendarMap.get(startHour - 1).get(halfMonthDay).add(item);
//            }
        });


        RespBusinessClaTimeCalendar timeCalendar = new RespBusinessClaTimeCalendar();
        // 每行数据
        List<ClaTimeContainer> claTimeContainerList = Lists.newArrayList();
        // 星期排课数量
        Map<Integer, Integer> columnTitleTimeCountMap = new HashMap();

        // 每行数据
        claTimeCalendarMap.forEach((claTimeKey, claTimeMap) -> {
            ClaTimeContainer claTimeContainer = new ClaTimeContainer();
            claTimeContainer.setTime(AUTO_CLA_TIME_MAP.get(claTimeKey));

            Map<Integer, List<ClaTimeCalendarItem>> claTimeWeekDayMap = new HashMap();
            claTimeMap.forEach((weekDayKey, list) -> {


                if (columnTitleTimeCountMap.containsKey(weekDayKey)) {
                    columnTitleTimeCountMap.put(weekDayKey, columnTitleTimeCountMap.get(weekDayKey) + list.size());
                } else {
                    columnTitleTimeCountMap.put(weekDayKey, list.size());
                }

                List<ClaTimeCalendarItem> timeItemList = list.stream().map(item -> {
                    ClaTimeCalendarItem claTimeItem = new ClaTimeCalendarItem();
                    claTimeItem.transfer(item);
                    return claTimeItem;
                }).collect(Collectors.toList());
                claTimeWeekDayMap.put(weekDayKey, timeItemList);
            });
            claTimeContainer.setClaTimeWeekDayMap(claTimeWeekDayMap);
            claTimeContainerList.add(claTimeContainer);
        });
//        Collections.sort(claTimeContainerList, (o1, o2) -> {
//            int a = Integer.parseInt(o1.getTime().substring(0, 2));
//            int b = Integer.parseInt(o2.getTime().substring(0, 2));
//            if (a > b) {
//                return 1;
//            } else if (a < b) {
//                return -1;
//            } else {
//                return 0;
//            }
//        });
        // 按小时正序排序
        Collections.sort(claTimeContainerList, Comparator.comparing(o -> o.getTime()));
        timeCalendar.setClaTimeContainer(claTimeContainerList);


        // 标题
        List<ClaTimeColumnTitle> columnTitles = Lists.newArrayList();
        int i=1;
        while (cycleBegin.before(cycleEnd)) {
            int dayOfWeek = DateUtil.dayOfWeek(cycleBegin);
//            Date  new DateTime(DateUtil.format(cycleBegin,"yyyy-MM-dd"));
            int dayOfcycle = dateList.indexOf(cycleBegin)+1;


            ClaTimeColumnTitle claTimeColumnTitle = new ClaTimeColumnTitle();
            claTimeColumnTitle.setWeekName(Constants.WEEK_DAY_MAP.get(dayOfWeek));
            claTimeColumnTitle.setDay(DateUtil.format(cycleBegin,"yyyy-MM-dd"));
            claTimeColumnTitle.setCount(columnTitleTimeCountMap.get(dayOfcycle));

            columnTitles.add(claTimeColumnTitle);
            cycleBegin = DateUtil.offsetDay(cycleBegin,1);
        }
        timeCalendar.setColumnTitles(columnTitles);

        return timeCalendar;
    }



    /**
     * 按日获取我的课程
     * @param date
     * @return
     */
    @Override
    public RestResponse getCourseListByDate(String date){
        Long appUserId=SecurityUtils.getAppLoginUser().getAppUserId();
        AppUser appUser= appUserService.getById(appUserId);
        if (ObjectUtil.isEmpty(appUser.getVisitStore())){
            return RestResponse.failure("请选择访问门店！");
        }
        YjStore store=storeService.getOne(appUser.getVisitStore());
        if (ObjectUtil.isEmpty(store)){
            return RestResponse.failure("门店不在运营状态！");
        }
        List<ClaTimeCalendarItem> list=claTimeMapper.getCourseList(date,null,appUser.getVisitStore());
        return new RestResponse().setData(list);
    }

    /**
     * 预约课程
     * @param searchClaTime
     * @return
     */
    @Override
    @Transactional
    public RestResponse bookCourse(@RequestBody ReqSearchClaTime searchClaTime){
        Long studentId=SecurityUtils.getAppLoginUser().getStudentId();
        Long courseTimeId=searchClaTime.getCourseTimeId();//某节课的编号
        ScClaTime claTim=claTimeMapper.selectById(courseTimeId);

        if (ObjectUtil.isEmpty(claTim)){
            return new RestResponse().setSuccess(false).setMessage("课程编号有误，无法预约");
        }


        if (claTim.getBookAttendCnt().equals(claTim.getAtClassCnt())){
            return new RestResponse().setSuccess(false).setMessage("课程预约已满，无法预约");
        }

        //状态 1:待上课 2:已上课
        if (claTim.getStatus().equals(2)){
            return new RestResponse().setSuccess(false).setMessage("课程已开始上课，无法预约！");
        }


        //获取当前用户 在租户所拥有的会员卡
        List<ScMemberCard> cardList=memberCardsMapper.getByMemberId(studentId,claTim.getTenantId(),claTim.getClaDate());


        if (cardList.size()==0){
            return new RestResponse().setSuccess(false).setMessage("会员卡失效 或 未在本机构开通会员卡，请联系教练预约！");
        }


        List<Long> cardIds=cardList.stream().map(it -> it.getId()).collect(Collectors.toList());
        List<RespMemberTypeCourses> course= memberCardsMapper.getCourseDetail(claTim.getCourseId(),claTim.getTeacherId(),cardIds);

        //改：
        // 1.会员卡排序 按天 -> 按课时 -> 按储值
        // 2.判断是否含有本课程类型+教练 sql
        // 3.判断约课次数
        // 4.限制课程 sql





        if (course.size()==0){
            return new RestResponse().setSuccess(false).setMessage("会员卡不包含本次课程，请联系教练预约！");
        }

        // 校验预约次数 预约教师

        //消费优先级 ： 时间卡 > 次数卡 > 储值卡
        Map<String, List<RespMemberTypeCourses>> courseMap = course.stream().collect(Collectors.groupingBy(RespMemberTypeCourses::getChargeType));
        int flag=0;//1次数卡次数不够用 2储值卡余额不够 3 两个卡都不够
        RespMemberTypeCourses selected=new RespMemberTypeCourses();

        if (ObjectUtil.isNotEmpty(courseMap.get("days"))
                && courseMap.get("days").size()>0
                && checkBookNum(courseMap.get("days").get(0).getCardTypeId(),courseMap.get("days").get(0).getCardNo())
        ){
            selected= courseMap.get("days").get(0);

        }else {
            if (ObjectUtil.isNotEmpty(courseMap.get("count"))
                    && courseMap.get("count").size()>0
                    && checkBookNum(courseMap.get("count").get(0).getCardTypeId(),courseMap.get("count").get(0).getCardNo())
            ){
                RespMemberTypeCourses chargeCount= courseMap.get("count").get(0);
                if (chargeCount.getRemainingCount().compareTo(chargeCount.getDeductCnt())>-1){
                    selected=chargeCount;
                }else {
                     flag=1;
                     //储值卡
                    if (ObjectUtil.isNotEmpty(courseMap.get("total_fee"))
                            && courseMap.get("total_fee").size()>0
                            && checkBookNum(courseMap.get("total_fee").get(0).getCardTypeId(),courseMap.get("total_fee").get(0).getCardNo())
                    ){
                        RespMemberTypeCourses chargeFee= courseMap.get("total_fee").get(0);
                        //划扣费用，如果未设置，则使用课程 价值
                        BigDecimal deductFee=chargeFee.getRemainingTotalFee().equals(BigDecimal.ZERO)?chargeFee.getTuitionFee():chargeFee.getRemainingTotalFee();
                        if (chargeFee.getRemainingTotalFee().compareTo(deductFee)>-1){
                            selected=chargeFee;
                        }else {
                            flag=3;
                        }
                    }
                }
            }else {
                //储值卡
                if (ObjectUtil.isNotEmpty(courseMap.get("total_fee"))
                        && courseMap.get("total_fee").size()>0
                        && checkBookNum(courseMap.get("total_fee").get(0).getCardTypeId(),courseMap.get("total_fee").get(0).getCardNo())
                ){
                    RespMemberTypeCourses chargeFee= courseMap.get("total_fee").get(0);
                    //划扣费用，如果未设置，则使用课程 价值
                    BigDecimal deductFee=chargeFee.getRemainingTotalFee().equals(BigDecimal.ZERO)?chargeFee.getTuitionFee():chargeFee.getRemainingTotalFee();
                    if (chargeFee.getRemainingTotalFee().compareTo(deductFee)>-1){
                        selected=chargeFee;

                    }else {
                        flag=2;
                    }
                }
            }
        }

        if (ObjectUtil.isEmpty(selected)){

            if (flag==0){
                return new RestResponse().setSuccess(false).setMessage("没有满足预约条件的会员卡，请联系教练预约！");
            }

            if (flag==1){
                return new RestResponse().setSuccess(false).setMessage("会员卡剩余次数不足，请联系教练预约！");
            }

            if (flag==2){
                return new RestResponse().setSuccess(false).setMessage("会员卡剩余金额不足，请联系教练预约！");
            }

            if (flag==3){
                return new RestResponse().setSuccess(false).setMessage("会员卡额度不足，请联系教练预约！");
            }
        }

        //预约
        ScBookCourse bookCourse= bookCourseMapper.selectOne(new QueryWrapper<ScBookCourse>()
                .eq("course_time_id",courseTimeId)
                .eq("student_id",studentId)
                .eq("card_no",selected.getCardNo())
        );



        if (ObjectUtil.isNotEmpty(bookCourse)){
            //预约状态:0->预约中；1->教练确认；2->店长确认/预约成功/待上课 3->已取消;4- >已完成/待评价;5- >预约失败；
            int[] a= {0,1,2,4};
            if (ArrayUtil.contains(a,bookCourse.getBookStatus())){
                return new RestResponse().setSuccess(false).setMessage("课程预约中，请勿重复预约！");
            }

            if (bookCourse.getBookStatus()==3){
                bookCourse.setBookStatus(0);
                bookCourseMapper.updateById(bookCourse);
                addBookLogFromApp(0,bookCourse.getId());
            }
        }else {
            //预约表
            bookCourse=new ScBookCourse();
            bookCourse.setBookStatus(0);
            bookCourse.setCourseTimeId(courseTimeId);
            bookCourse.setCreateTime(new Date());
            bookCourse.setStudentId(studentId);
            bookCourse.setCardNo(selected.getCardNo());
            bookCourse.setChargeType(selected.getChargeType());
            bookCourse.setDeductCnt(selected.getDeductCnt());
            bookCourse.setDeductFee(selected.getDeductFee());
            bookCourse.setTenantId(claTim.getTenantId());
            bookCourse.setCourseId(claTim.getCourseId());
            bookCourse.setDepartId(claTim.getStoreId());
            //生成一个code 用于消课
            Long code = IDGenerator.generateId();
            bookCourseMapper.insert(bookCourse);
            try {
                byte[] qrCode= CodeUtil.generateQrCodeBytes(bookCourse.getId().toString());
                bookCourse.setQrCode(Base64.encode(qrCode));
            }catch (Exception e){

            }
            bookCourse.setCode(bookCourse.getId());
            bookCourseMapper.updateById(bookCourse);
            //预约记录
            addBookLogFromApp(0,bookCourse.getId());

            //预约成功 后 首次预约激活
            Map<String, List<ScMemberCard>> cardMap =cardList.stream().collect(Collectors.groupingBy(ScMemberCard::getCardNo));
            ScMemberCard card=cardMap.get(selected.getCardNo()).get(0);
            if (card.getHaveActivationDate().equals("2")
                    && card.getStatus().equals("INACTIVE")){
                ScMemberCard edtiCard=new ScMemberCard();
                edtiCard.setActivationDate(LocalDate.now());
                edtiCard.setStatus("ACTIVE");
                edtiCard.setId(card.getId());

                memberCardsMapper.updateById(edtiCard);
            }
        }

        //本节课
        claTim.setBookAttendCnt(claTim.getBookAttendCnt()+1);
        claTimeMapper.updateById(claTim);
        jpush(bookCourse.getId(),
                selected.getCourseName(),
                SecurityUtils.getAppLoginUser().getAppUser().getId());
        return new RestResponse().setSuccess(true).setMessage("预约成功");
    }
    public void jpush(Long bookId,String coursesName,Long recvId){
        AppUser recvUser= appUserService.getById(recvId);
        if (StrUtil.isNotEmpty(recvUser.getRegisterId())){
            String msg = String.format(
                    "%s：%s",
                    coursesName, "课程预约成功！"
            );
            Map<String, String> extras=new HashMap<>();
            extras.put("type","bookCourses");//type推送类型：bookCourses 预约课程 groupMessage群聊消息 privateMessage私信消息
            extras.put("pagePath","/pages/book/book");//pagePath跳转页面
            extras.put("bookId",bookId.toString());//bookId预约id
            JpushClientUtil.pushByRegistrationId(Arrays.asList(recvUser.getRegisterId()),"瑜伽汇",msg,extras);
        }

    }
    //约课次数
        public Boolean checkBookNum(Long cardTypeId,String cardNo){
        RespMemberTypeCourses type= memberCardsMapper.getMemberTypeById(cardTypeId);
        if(type.getRestrictedNum().equals("2")&&StrUtil.isNotEmpty(type.getBookTime())){
            //限制约课时间范围 每天、每周、半月、每月
            TimeCycleUtil.TimeRange range= TimeCycleUtil.getCycleTimeRange(type.getBookTime());
            String startTime=range.getStartTime();
            String endTime=range.getEndTime();

            Long count= bookCourseMapper.selectCount(new QueryWrapper<ScBookCourse>()
                    .eq("card_no",cardNo)
                    .between("create_time",startTime,endTime)
                    .in("book_status","0,1,2,4")
            );
            if (count.intValue()>type.getBookNum().intValue()){
                return false;
            }
        }
       return true;
    }

    /**
     * 我的预约列表
     * @return
     */
    @Override
    public Map<String,List<ClaTimeBookItem>> bookCourseList(){
        Long studentId=SecurityUtils.getAppLoginUser().getStudentId();
        List<ClaTimeBookItem> list=bookCourseMapper.getListByStudent(studentId);

        Map<String,List<ClaTimeBookItem>> map=new HashMap<>();
        map.put("all",list);

        List<ClaTimeBookItem> booking=new ArrayList<>();
        List<ClaTimeBookItem> waitingForClass=new ArrayList<>();
        List<ClaTimeBookItem> canceled=new ArrayList<>();
        List<ClaTimeBookItem> completed=new ArrayList<>();
        //预约状态:0->预约中；1->教练确认；2->店长确认/预约成功/待上课 3->已取消;4- >已完成/待评价；
        for (ClaTimeBookItem b : list) {
            if (b.getBookStatus()==0){
                booking.add(b);
            }
            if (b.getBookStatus()==2){
                waitingForClass.add(b);
            }
            if (b.getBookStatus()==3){
                canceled.add(b);
            }
            if (b.getBookStatus()==4){
                completed.add(b);
            }
        }
        map.put("booking",booking);//预约中
        map.put("waitingForClass",waitingForClass);//待上课
        map.put("canceled",canceled);//已取消
        map.put("completed",completed);//已完成
        return map;
    }

    /**
     * 预约详情
     * @return
     */
    @Override
    public RestResponse bookCourseDetail(Long bookId){
        ClaTimeBookItem bookItem=bookCourseMapper.getDetail(bookId);
        if (ObjectUtil.isEmpty(bookItem)){
            return new RestResponse().setSuccess(false).setMessage("预约详情不存在");
        }
        List<ScBookCourseLog> logs=bookCourseLogMapper.selectList(new QueryWrapper<ScBookCourseLog>()
                .eq("book_id",bookId).orderByAsc("update_time"));

        List list=new ArrayList<>();
        for (ScBookCourseLog l : logs) {
            Map map=new HashMap<>();
            map.put("status",l.getBookStatus());
            map.put("time",DateUtil.format(l.getUpdateTime(),"yyyy-MM-dd HH:mm:ss"));
            list.add(map);
        }

        bookItem.setStatusTime(list);

        return new RestResponse().setData(bookItem);
    }

    /**
     * 取消预约
     * @return
     */
    @Override
    @Transactional
    public RestResponse cancelCourse(Long courseTimeId){
        Long studentId=SecurityUtils.getAppLoginUser().getStudentId();
        ScClaTime claTim=claTimeMapper.selectById(courseTimeId);

        //状态 1:待上课 2:已上课
        if (claTim.getStatus().equals(2)){
            return new RestResponse().setSuccess(false).setMessage("课程已开始上课，无法取消！");
        }

        //预约
        ScBookCourse bookCourse= bookCourseMapper.selectOne(new QueryWrapper<ScBookCourse>()
                .eq("course_time_id",courseTimeId)
                .eq("student_id",studentId)
        );
        if (bookCourse.getCheckIn()==1){
            return new RestResponse().setSuccess(false).setMessage("已签到，无法取消！");
        }

        if (StrUtil.containsAny("0,1,2",bookCourse.getBookStatus()+"")){
            bookCourse.setBookStatus(3);
            bookCourseMapper.updateById(bookCourse);
            addBookLogFromApp(3,bookCourse.getId());
            return new RestResponse().setSuccess(true).setMessage("取消成功");

        }else {
            return new RestResponse().setSuccess(false).setMessage("取消失败");
        }

    }

    /**
     * 预约详情
     * @param courseTimeId
     * @return
     */
    @Override
    public RestResponse courseTimeDetail(Long courseTimeId){
        //课程信息
        ClaTimeCalendarItem claTimeCalendarItem=claTimeMapper.getCourseList(null,courseTimeId,null).get(0);
        //预约学员信息 姓名 性别 电话
        List<RespStuBook> students=claTimeMapper.getCourseBookStudent(courseTimeId);

        Map map=new HashMap();
        map.put("courseDetail",claTimeCalendarItem);
        map.put("studentList",students);

        return new RestResponse().setSuccess(true).setData(map);
    }

    @Override
    public RestResponse getCourseDetail(Long courseTimeId){
        ClaTimeCalendarItem claTimeCalendarItem=claTimeMapper.getCourseDetail(courseTimeId);
        return new RestResponse().setSuccess(true).setData(claTimeCalendarItem);
    }

    @Override
    public RestResponse appointmentListForTeacher(){
        Long[] roleId=SecurityUtils.getAppLoginUser().getRoles();
        //104 教师  105店长  103 会籍顾问
        if (!ArrayUtil.containsAny(roleId,104L)){
            return new RestResponse().setSuccess(false).setMessage("当前登录人无权限！");
        }
        Long userId= SecurityUtils.getAppLoginUser().getManageAccountId();
        Date beginTime = new Date();//开始时间
        Date endTime = DateUtil.offsetDay(beginTime,14);//结束时间
        //按教师id 查  近15日课程 （sc_cla_time） 预约（sc_book_course）
        List<RespBook> listForTeacher=claTimeMapper.getBookListForTeacher(userId,DateUtil.format(beginTime,"yyyy-MM-dd"),DateUtil.format(endTime,"yyyy-MM-dd"));


        return new RestResponse().setData(listForTeacher);
    }
    @Override
    public RestResponse appointmentListForManager(){
        Long[] roleId=SecurityUtils.getAppLoginUser().getRoles();
        //104 教师  105店长  103 会籍顾问
        if (!ArrayUtil.containsAny(roleId,105L)){
            return new RestResponse().setSuccess(false).setMessage("当前登录人无权限！");
        }

        Long userId= SecurityUtils.getAppLoginUser().getManageAccountId();

       SysUser sysUser= sysUserService.selectUserById(userId);
        Long deptId=   sysUser.getDeptId();

        Date beginTime = new Date();//开始时间
        Date endTime = DateUtil.offsetDay(beginTime,14);//结束时间
        List<RespBook> listForManager=claTimeMapper.getBookListForManager(deptId,DateUtil.format(beginTime,"yyyy-MM-dd"),DateUtil.format(endTime,"yyyy-MM-dd"));

        return new RestResponse().setData(listForManager);
    }


    //确认预约or拒接预约（教师/店长）
    @Override
    @Transactional
    public RestResponse checkAppointment(Long bookId,int bookStatus){
        Long[] roleId=SecurityUtils.getAppLoginUser().getRoles();
        //104 教师  105店长  103 会籍顾问
        if (!ArrayUtil.containsAny(roleId,105L, 104L)){
            return new RestResponse().setSuccess(false).setMessage("当前登录人无权限！");
        }
        //0->预约中；1->教练确认；2->店长确认/预约成功/待上课 3->已取消;4- >已完成/待评价;5- >预约失败；
        //当前课程状态
        ScBookCourse bookCourse= bookCourseMapper.selectById(bookId);
        Integer dbBookStatus= new Integer(bookCourse.getBookStatus());
        Integer[] status={3,4,5};

        if (ArrayUtil.containsAny(status,dbBookStatus)){
            return new RestResponse().setSuccess(false).setMessage("请刷新预约状态！");
        }


        ScBookCourse updateBook=new ScBookCourse();
        updateBook.setId(bookId);
        int f=0;
        if (bookStatus==5){
            updateBook.setBookStatus(5);
            f=bookCourseMapper.updateById(updateBook);
            addBookLogFromApp(5,bookId);
            return new RestResponse().setSuccess(true).setMessage("成功！");
        }

        if (ArrayUtil.containsAny(roleId, 104L)&& dbBookStatus==0){
            updateBook.setBookStatus(1);
            f=bookCourseMapper.updateById(updateBook);
            addBookLogFromApp(1,bookId);
            return new RestResponse().setSuccess(true).setMessage("成功！");
        }

        if (ArrayUtil.containsAny(roleId, 105L)&& dbBookStatus==1){
            updateBook.setBookStatus(2);
            f=bookCourseMapper.updateById(updateBook);
            addBookLogFromApp(2,bookId);
            return new RestResponse().setSuccess(true).setMessage("成功！");
        }

            return new RestResponse().setSuccess(false).setMessage("请刷新预约状态！");


    }

    void addBookLogFromApp(int bookStatus,Long bookId){
        ScBookCourseLog log=new ScBookCourseLog();
        log.setBookStatus(bookStatus);
        log.setUpdateTime(new Date());
        log.setUpdateUser(SecurityUtils.getAppLoginUser().getManageAccountId());//后台sys_user id
        log.setBookId(bookId);
        bookCourseLogMapper.insert(log);
    }

    /**
     * 确认上课
     * @param courseTimeId
     * @return
     */
    @Override
    @Transactional
    public RestResponse confirmClass(Long courseTimeId,String startTime,String endTime){
        Long[] roleId=SecurityUtils.getAppLoginUser().getRoles();
        //104 教师  105店长  103 会籍顾问
        if (!ArrayUtil.containsAny(roleId,104l)){
            return new RestResponse().setSuccess(false).setMessage("当前登录人无权限！");
        }
        AppLoginUser loginUser=SecurityUtils.getAppLoginUser();
        //本节课的预约
        List<ScBookCourse> bookCourses=bookCourseMapper.selectList(new QueryWrapper<ScBookCourse>()
                        .in("book_status",0,1,2)
                .eq("course_time_id",courseTimeId)
        );
        if (bookCourses.size()<1)throw new RuntimeException("无学员预约！");
        //判断预约状态（未确认）
//        Long needCheck= bookCourses.stream()
//                .filter(l-> StrUtil.containsAny("0,1",l.getBookStatus()+"")).count();
//        if (needCheck>0){
//            return new RestResponse().setSuccess(false).setMessage("请检查学员预约状态！");
//        }

        //判断是否有学员未签到
        Long notCheckIn=bookCourses.stream().filter(l->l.getCheckIn()==0).count();
        if (notCheckIn>0){
            return new RestResponse().setSuccess(false).setMessage("请确认学员签到情况，如无法到课请联系学员取消预约！");
        }
        //签到学员
        List<ScBookCourse> checkIn=bookCourses.stream().filter(l->l.getCheckIn()==1).collect(Collectors.toList());

        ScClaTime claTime=claTimeMapper.selectById(courseTimeId);
        //签到数量是否少于开课人数
        if (claTime.getLessCnt()>checkIn.size()){
            return new RestResponse().setSuccess(false).setMessage("学员数量到不到开课标准！");
        }

        //教室使用时间及费用
        Date startTimeDate= DateUtil.parseTime(startTime);
        Date endTimeDate= DateUtil.parseTime(endTime);

        BigDecimal  venueFee=new BigDecimal(     0);
        double roomUsageTime=0.0;

        if (ObjectUtil.isNotEmpty(claTime.getRoomId())){
           ScRoom room= roomMapper.selectById(claTime.getRoomId());
            //上课时间段  >0.5小时，按1小时计
             roomUsageTime=DateUtil.between(startTimeDate, endTimeDate, DateUnit.MINUTE)/ 60.0;
            int c=(int)roomUsageTime;
            double d=roomUsageTime-c;
            if (d > 0.5) {
                roomUsageTime= c + 1.0;
            } else if (d > 0) {
                roomUsageTime= c + 0.5;
            }
            venueFee= room.getVenueFee().add(new BigDecimal(roomUsageTime));
        }

        //更改预约状态
        bookCourseMapper.update(null,new UpdateWrapper<ScBookCourse>()
                .eq("course_time_id",courseTimeId)
                .eq("check_in","1")
                .eq("book_status",2)
                .set("book_status","4"));
        //添加预约状态记录
        for (ScBookCourse bookCours : checkIn) {
            addBookLogFromApp(4,bookCours.getId());
        }
        claTime.setRealClaDate(DateUtil.format(new Date(),"yyyy-MM-dd"));
        claTime.setRealStartTime(startTime);
        claTime.setRealEndTime(endTime);
        claTime.setVenueFee(venueFee);
        claTime.setRoomUsageTime(roomUsageTime);
        claTime.setStatus("2");
        claTime.setLastUpdateTime(new Date());
        claTimeMapper.updateById(claTime);

        return new RestResponse().setSuccess(true).setMessage("开始上课！");
    }


    /**
     * 签到
     *
     * @param
     * @return
     */
    @Override
    @Transactional
    public RestResponse checkIn(Map map) {

        Long[] roleId=SecurityUtils.getAppLoginUser().getRoles();
        //104 教师  105店长  103 会籍顾问
        if (!ArrayUtil.containsAny(roleId,104l,105l,103l)){
            return new RestResponse().setSuccess(false).setMessage("当前登录人无权限！");
        }
        //预约id/code
        String code= map.get("code").toString();
        Long bookId=Long.parseLong(map.get("bookId").toString());
        //预约
        ScBookCourse bookCourse= bookCourseMapper.selectOne(new QueryWrapper<ScBookCourse>()
                .eq("code",code));

        //判断预约状态
        //预约状态:0->预约中；1->教练确认；2->店长确认/预约成功/待上课 3->已取消;4- >已完成/待评价;5- >预约失败；
//        if (StrUtil.containsAny("3,4,5",bookCourse.getBookStatus()+"")){
        if (bookCourse.getBookStatus()!=2){
            return new RestResponse().setSuccess(false).setMessage("请检查学员预约状态！");
        }

        AppLoginUser loginUser = SecurityUtils.getAppLoginUser();
        Long courseTimeId = bookCourse.getCourseTimeId();

        ScMemberCard memberCard=memberCardsMapper.selectOne(new QueryWrapper<ScMemberCard>()
                .eq("card_no",bookCourse.getCardNo())
                .eq("charge_type",bookCourse.getChargeType())
                .eq("is_deleted",0)
                .last(" and expiry_date > CURDATE() ")

        );
        if (ObjectUtil.isEmpty(memberCard)){
            return new RestResponse().setSuccess(false).setMessage("会员卡状态异常，请与教练核实!");
        }

        // 排课信息
        ScClaTime claTime= claTimeMapper.selectById(courseTimeId);
        Long  teacherId = claTime.getTeacherId();
        if (!ClaTimeStatusEnums.WAIT_CLASS.getStatus().equals(claTime.getStatus())) {
            return new RestResponse().setSuccess(false).setMessage("非待上课状态,无法重复上课!");
        }
        //班级信息
        Long claId = claTime.getClaId();
        ScCourseCla dbCla = claMapper.selectById(claId);
        if (null == dbCla) {
            return new RestResponse().setSuccess(false).setMessage("无法获取班级信息,请稍后重试");
        }
        //课程信息
        Long courseId = dbCla.getCourseId();
        ScCourse scCourse = courseMapper.selectById(courseId);
        if (null == scCourse) {
            return new RestResponse().setSuccess(false).setMessage("无法获取课程信息,请稍后重试");
        }
        Long departId = dbCla.getDepartId();
        SysDept sysDept = deptService.getById(departId);
        if (null == sysDept) {
            return new RestResponse().setSuccess(false).setMessage("无法获取校区信息,请稍后重试");
        }
        String chargeType=memberCard.getChargeType();

        // 上课记出勤表
        ScClaTimeAttend addClaTimeAttend = new ScClaTimeAttend();

        if (chargeType.equals("count")){
            if (memberCard.getRemainingCount().compareTo(bookCourse.getDeductCnt())>-1){
                addClaTimeAttend.setPayHour(bookCourse.getDeductCnt());
                addClaTimeAttend.setCountBefore(memberCard.getRemainingCount());
                addClaTimeAttend.setPayFee(memberCard.getCountFee().multiply(bookCourse.getDeductCnt()));

                BigDecimal  countAfter= memberCard.getRemainingCount().subtract(bookCourse.getDeductCnt());
                addClaTimeAttend.setCountAfter(countAfter);
                memberCard.setRemainingCount(countAfter);
            }else {
                return new RestResponse().setSuccess(false).setMessage("会员卡剩余次数不足，请充值后重新预约！");
            }
        }

        if (chargeType.equals("total_fee")){
            if (memberCard.getRemainingTotalFee().compareTo(bookCourse.getDeductFee())>-1){
                addClaTimeAttend.setPayFee(bookCourse.getDeductFee());
                addClaTimeAttend.setFeeBefore(memberCard.getRemainingTotalFee());

                BigDecimal feeAfter=memberCard.getRemainingTotalFee().subtract(bookCourse.getDeductFee());
                addClaTimeAttend.setFeeAfter(feeAfter);
                memberCard.setRemainingTotalFee(feeAfter);
            }else {
                return new RestResponse().setSuccess(false).setMessage("会员卡剩余金额不足，请充值后重新预约！");
            }
        }
        bookCourse.setUserId(SecurityUtils.getAppLoginUser().getManageAccountId());
        bookCourse.setCheckIn(1);
        bookCourse.setCheckInTime(new Date());
        bookCourseMapper.updateById(bookCourse);
        //会员卡余额变更
        memberCardsMapper.updateById(memberCard);

        //本节课 到课人数变更
        claTime.setRealAttendCnt(claTime.getRealAttendCnt()+1);
        claTimeMapper.updateById(claTime);

        SysTeacher sysStaff=staffService.getById(teacherId);

        addClaTimeAttend.setBookId(bookCourse.getId());
        addClaTimeAttend.setMemberCardId(memberCard.getId());
        addClaTimeAttend.setCourseTimeId(courseTimeId);
        addClaTimeAttend.setStudentId(bookCourse.getStudentId());
        addClaTimeAttend.setClaId(claTime.getClaId());
        addClaTimeAttend.setCourseId(scCourse.getCourseId());
        addClaTimeAttend.setTeacherId(teacherId);
        addClaTimeAttend.setTeacherName(sysStaff.getUserName());
        addClaTimeAttend.setChargeType(chargeType);
        addClaTimeAttend.setTenantId(claTime.getTenantId());
        addClaTimeAttend.setAttendStatus("1");
        addClaTimeAttend.setCreateUser(loginUser.getManageAccountId());

        // 保存上课记录
        attendService.save(addClaTimeAttend);

        // 上课日志
//        StringBuffer sb = new StringBuffer("");
//        sb.append("上课[").append(ClaTimeAttendStatusEnums.getNameByStatus("1")).append("],上课时间")
//                .append(DateUtil.now()).append(",");
//        ScStudentCourseLog studentCourseLog = ScStudentCourseLog.builder()
//                .studentId(bookCourse.getStudentId())
//                .logType(LogTypeEnum.ATTEND_CLA.getLogType())
//                .courseId(scCourse.getCourseId())
//                .courseName(scCourse.getCourseName())
//                .claId(dbCla.getClaId())
//                .claName(dbCla.getClaName())
//                .deptName(sysDept.getDeptName())
//                .createUser(loginUser.getAppUserId())
//                .createUserType("app")
//                .createUserName(loginUser.getAppUser().getUserName())
//                .createTime(new Date())
//                .build();
//        //count:课时 days:时间 total_fee:储值
//        if (chargeType.equals("count")) {
//            studentCourseLog.setChangeHour(addClaTimeAttend.getPayHour());
//            studentCourseLog.setAfterBalanceHour(addClaTimeAttend.getCountAfter());
//            sb.append("扣减").append(addClaTimeAttend.getPayHour()).append("课时；");
//        }
//        if (chargeType.equals("total_fee")) {
//            studentCourseLog.setChangeFee(addClaTimeAttend.getPayFee());
//            studentCourseLog.setAfterBalanceHour(addClaTimeAttend.getFeeAfter());
//            sb.append("扣减").append(addClaTimeAttend.getPayHour()).append("元；");
//        }
//        studentCourseLog.setMemo(sb.toString());
//        }

        // 保存学生日志
//        studentCourseLogMapper.insert(studentCourseLog);

        return new RestResponse().setSuccess(true).setMessage("签到成功！");
    }

    /**
     * 教练课时统计
     * @return
     */
    @Override
    public RestResponse teacherClaTotal(String time) {
        Long[] roleId=SecurityUtils.getAppLoginUser().getRoles();
        //104 教师  105店长
        if (!ArrayUtil.containsAny(roleId,104l)){
            return new RestResponse().setSuccess(false).setMessage("当前登录人无权限！");
        }

        Long teacherId= SecurityUtils.getAppLoginUser().getManageAccountId();

        QueryWrapper queryWrapper=   new QueryWrapper<ScClaTime>();
        queryWrapper.eq("teacher_id",teacherId);

        switch (time) {
            case "today" :
                queryWrapper.eq("real_cla_date",DateUtil.format(DateUtil.date(),"yyyy-MM-dd"));
                break;
            case "yesterday" :
                queryWrapper.eq("real_cla_date",DateUtil.format(DateUtil.yesterday(),"yyyy-MM-dd"));
                break;
            case "thisMonth" :
                queryWrapper.eq("substr(real_cla_date,1,7)",
                        DateUtil.format(DateUtil.date(),"yyyy-MM")
                );
                break;
            case "lastMonth" :
                queryWrapper.eq("substr(real_cla_date,1,7)",
                        DateUtil.format(DateUtil.lastMonth(),"yyyy-MM")
                );
                break;
        }

       List<ScClaTime> claTimeList=claTimeMapper.selectList(queryWrapper);

        //上课节数
        int claCount=claTimeList.size();

        BigDecimal totalFee = claTimeList.stream()
                // 将user对象的age取出来map为Bigdecimal
                .map(ScClaTime::getTeacherFee)
                // 使用reduce()聚合函数,实现累加器
                .reduce(BigDecimal.ZERO,BigDecimal::add);
        claTimeList.forEach(l->{
         String  courseName= claTimeMapper.getCourseList(null,l.getCourseTimeId(),null).get(0).getCourseName();
            l.setCourseName(courseName);
        });
        Map map=new HashMap<>();
        map.put("claCount",claCount);
        map.put("totalFee",totalFee);
        map.put("claTimeList",claTimeList);

        return new RestResponse().setSuccess(true).setData(map);
    }

    private String beginTime;
    private String endTime;


    /**
     * 教练费用统计（店长）
     * @return
     */
    @Override
    public RestResponse teacherFeeTotal(String time) {
        Long[] roleId=SecurityUtils.getAppLoginUser().getRoles();
        //104 教师  105店长
        if (!ArrayUtil.containsAny(roleId,105l)){
            return new RestResponse().setSuccess(false).setMessage("当前登录人无权限！");
        }

        Long staffId= SecurityUtils.getAppLoginUser().getManageAccountId();

        getTime(time);

        List<ClaTimeItem> claTimeList=claTimeMapper.getCourseCountByStoreManager(staffId,this.beginTime,this.endTime);

        //上课节数
        int claCount=claTimeList.size();
        //课时费
        BigDecimal totalFee = claTimeList.stream()
                // 将user对象的age取出来map为Bigdecimal
                .map(ClaTimeItem::getTeacherFee)
                // 使用reduce()聚合函数,实现累加器
                .reduce(BigDecimal.ZERO,BigDecimal::add);

        Map map=new HashMap<>();
        map.put("claCount",claCount);
        map.put("totalFee",totalFee);
        map.put("claTimeList",claTimeList);

        return new RestResponse().setSuccess(true).setData(map);
    }


    /**
     * 我的客户
     * @return
     */
    @Override
   public RestResponse myClient(){
        Long[] roleId=SecurityUtils.getAppLoginUser().getRoles();
        //104 教师  105店长  103 会籍顾问
        if (!ArrayUtil.containsAny(roleId,103l)){
            return new RestResponse().setSuccess(false).setMessage("当前登录人无权限！");
        }
       Long staffId= SecurityUtils.getAppLoginUser().getManageAccountId();
       List<StudentOrderItem> students= claTimeMapper.getStudentsBySaleStaff(staffId);
       return new RestResponse().setSuccess(true).setData(students);
    }

    /**
     * 我的提成
     * @param time
     * @return
     */
    @Override
    public RestResponse commissionTotal(String time){
        Long[] roleId=SecurityUtils.getAppLoginUser().getRoles();
        //104 教师  105店长  103 会籍顾问
        if (!ArrayUtil.containsAny(roleId,103l)){
            return new RestResponse().setSuccess(false).setMessage("当前登录人无权限！");
        }
        Long staffId= SecurityUtils.getAppLoginUser().getManageAccountId();
        getTime(time);
        //获取成交的订单信息
        List<RespOrderForApp> orderLost=claTimeMapper.myDealOrder(staffId,beginTime,endTime);
        //佣金方案
        Map<Long, List<RespOrderForApp>> orderMap =
                orderLost.stream().collect(Collectors.groupingBy(RespOrderForApp::getCommissionPlansId));

        BigDecimal totalFee=new BigDecimal(0);
        //佣金策略(多个)
        for (Long aLong : orderMap.keySet()) {
           ScCommissionPlans plans= commissionMapper.selectById(aLong);
            BigDecimal commissionFee = orderMap.get(aLong).stream()
                    // 将user对象的age取出来map为Bigdecimal
                    .map(RespOrderForApp::getReceiptFee)
                    // 使用reduce()聚合函数,实现累加器
                    .reduce(BigDecimal.ZERO,BigDecimal::add);

            BigDecimal fee=new BigDecimal(0);
            //小于 第一阶梯阈值
            if (plans.getTier1Threshold().compareTo(totalFee)>0){
                fee=commissionFee.multiply(plans.getTier1Rate());
            }
            //第二阶梯
            if (totalFee.compareTo(plans.getTier1Threshold())>0
                    &&plans.getTier2Threshold().compareTo(totalFee)>0){
                fee=commissionFee.multiply(plans.getTier2Rate());
            }
            //第三阶梯
            if (totalFee.compareTo(plans.getTier2Threshold())>0
                    &&plans.getTier3Threshold().compareTo(totalFee)>0){
                fee=commissionFee.multiply(plans.getTier3Rate());
            }
            //第4阶梯
            if (totalFee.compareTo(plans.getTier3Threshold())>0){
                fee=commissionFee.multiply(plans.getTier4Rate());
            }

            totalFee=totalFee.add(fee);
        }
            //todo 转介绍佣金...

        Map map=new HashMap();
        map.put("commission",totalFee);
        map.put("orderCount",orderLost.size());
        map.put("orderList",orderLost);

        return new RestResponse().setSuccess(true).setData(map);
    }

    //销售信息（店长）
    @Override
    public RestResponse salesInformation(String time){
        Long[] roleId=SecurityUtils.getAppLoginUser().getRoles();
        //104 教师  105店长  103 会籍顾问
        if (!ArrayUtil.containsAny(roleId,105l)){
            return new RestResponse().setSuccess(false).setMessage("当前登录人无权限！");
        }
        Long staffId= SecurityUtils.getAppLoginUser().getManageAccountId();
        SysUser sysUser=sysUserService.selectUserById(staffId);
        getTime(time);
        //获取成交的订单信息
        List<RespOrderForApp> orderLost=claTimeMapper.getOrdersForStore(sysUser.getDeptId(),beginTime,endTime);
        BigDecimal totalAmount = orderLost.stream()
                // 将user对象的age取出来map为Bigdecimal
                .map(RespOrderForApp::getReceiptFee)
                // 使用reduce()聚合函数,实现累加器
                .reduce(BigDecimal.ZERO,BigDecimal::add);

        Map map=new HashMap();
        map.put("totalAmount",totalAmount);
        map.put("orderCount",orderLost.size());
        map.put("orderList",orderLost);

        return new RestResponse().setSuccess(true).setData(map);
    }

    //教室费用
    @Override
    public RestResponse claRoomFee(String time){
        Long[] roleId=SecurityUtils.getAppLoginUser().getRoles();
        //104 教师  105店长  103 会籍顾问
        if (!ArrayUtil.containsAny(roleId,105l)){
            return new RestResponse().setSuccess(false).setMessage("当前登录人无权限！");
        }
        Long staffId= SecurityUtils.getAppLoginUser().getManageAccountId();

        getTime(time);
        //获取门店上课信息
        List<ClaTimeItem> claTimeList=claTimeMapper.getCourseCountByStoreManager(staffId,beginTime,endTime);
        //教室使用费用
        BigDecimal venueFee = claTimeList.stream()
                // 将user对象的age取出来map为Bigdecimal
                .map(ClaTimeItem::getVenueFee)
                // 使用reduce()聚合函数,实现累加器
                .reduce(BigDecimal.ZERO,BigDecimal::add);

        Map map=new HashMap<>();
        map.put("venueFee",venueFee);
        map.put("claTimeList",claTimeList);

        return new RestResponse().setSuccess(true).setData(map);
    }

    private void getTime( String time){
//        String beginTime,String endTime,
        switch (time) {
            case "today" :
                beginTime=DateUtil.format(DateUtil.date(),"yyyy-MM-dd 00:00:00");
                endTime=DateUtil.format(DateUtil.date(),"yyyy-MM-dd 23:59:59");;
                break;
            case "yesterday" :
                beginTime=DateUtil.format(DateUtil.yesterday(),"yyyy-MM-dd 00:00:00");
                endTime=DateUtil.format(DateUtil.yesterday(),"yyyy-MM-dd 23:59:59");
                break;
            case "thisMonth" :
                beginTime=DateUtil.format(DateUtil.date(),"yyyy-MM-01 00:00:00");
                endTime=DateUtil.format(DateUtil.date(),"yyyy-MM-dd 23:59:59");
                break;
            case "lastMonth" :
                DateTime lastMonth=DateUtil.lastMonth();
                beginTime=DateUtil.format(lastMonth,"yyyy-MM-01 00:00:00");
                endTime=DateUtil.format(DateUtil.endOfMonth(lastMonth),"yyyy-MM-dd 23:59:59");
                break;
            default:
                throw new RuntimeException("请选择查询时间范围");
        }
    }
    /**
     * 3. 只包含数据库中实际存在的上课时段
     */
    private Map<String, String> generateTimeMapFromData(List<RespClaTimeCalendar> respClaTimeList) {
        // TreeMap 自动按 key 升序排列
        Map<String, String> timeMap = new TreeMap<>();
        for (RespClaTimeCalendar item : respClaTimeList) {
            String startHour = item.getStartTime();
            if (startHour == null) continue;
            timeMap.put(startHour, startHour );
        }
        return timeMap;
    }
    private Map<Integer, String> generateTimeMapFromData_old(List<RespClaTimeCalendar> respClaTimeList) {
        // TreeMap 自动按 key 升序排列
        Map<Integer, String> timeMap = new TreeMap<>();
        if (CollectionUtils.isEmpty(respClaTimeList)) {
            timeMap=Constants.CLA_TIME_MAP;
            return timeMap;
        }

        // 第一步：收集所有【合法的2小时制开始小时】（8、10、12、14、16、18...）
        Set<Integer> validStartHours = new HashSet<>();
        for (RespClaTimeCalendar item : respClaTimeList) {
            Integer startHour = item.getStartHour();
            if (startHour == null) continue;

            // 计算属于哪个2小时时段（核心：向下取整到偶数整点）
            int sectionStart = (startHour / 2) * 2;
            // 限制在合理范围 0~24
            if (sectionStart >= 0 && sectionStart <= 22) {
                validStartHours.add(sectionStart);
            }
        }

        // 第二步：生成 2小时间隔、不重叠 的时间段
        for (Integer start : validStartHours) {
            int end = start + 2;
            String startTime = String.format("%02d:00", start);
            String endTime = String.format("%02d:00", end);
            timeMap.put(start, startTime + " ~ " + endTime);
        }

        return timeMap;
    }
}
