package com.zhongzheng.modules.user.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.zhongzheng.common.utils.DateUtils;
import com.zhongzheng.modules.course.vo.CourseVo;
import com.zhongzheng.modules.goods.vo.GoodsUserVo;
import com.zhongzheng.modules.goods.vo.GoodsVo;
import com.zhongzheng.modules.user.bo.UserPlanGoodsAddBo;
import com.zhongzheng.modules.user.domain.UserPlanGoods;
import com.zhongzheng.modules.user.service.IUserPlanCourceService;
import com.zhongzheng.modules.user.service.IUserPlanGoodsService;
import com.zhongzheng.modules.user.vo.CalendarStudyVo;
import com.zhongzheng.modules.user.vo.DaySectionVo;
import com.zhongzheng.modules.user.vo.DayStudyVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.Page;
import com.zhongzheng.modules.user.bo.UserPlanAddBo;
import com.zhongzheng.modules.user.bo.UserPlanQueryBo;
import com.zhongzheng.modules.user.bo.UserPlanEditBo;
import com.zhongzheng.modules.user.domain.UserPlan;
import com.zhongzheng.modules.user.mapper.UserPlanMapper;
import com.zhongzheng.modules.user.vo.UserPlanVo;
import com.zhongzheng.modules.user.service.IUserPlanService;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 学习计划Service业务层处理
 *
 * @author ruoyi
 * @date 2021-12-08
 */
@Service
public class UserPlanServiceImpl extends ServiceImpl<UserPlanMapper, UserPlan> implements IUserPlanService {

    @Autowired
    private IUserPlanGoodsService userPlanGoodsService;



    @Override
    public UserPlanVo queryById(UserPlanQueryBo bo){
        UserPlan userPlan = this.baseMapper.selectById(bo.getPlanId());
        //得到日历日期
        UserPlanVo userPlanVo = new UserPlanVo();
        userPlanVo.setUserId(userPlan.getUserId());
        userPlanVo.setExamDate(userPlan.getExamDate());
        userPlanVo.setReminderTime(userPlan.getReminderTime());
        userPlanVo.setStudyDay(userPlan.getStudyDay());
        userPlanVo.setStartTime(userPlan.getStartTime());
        userPlanVo.setEndTime(userPlan.getEndTime());
        userPlanVo.setPitchNum(userPlan.getPitchNum());
        userPlanVo.setStudyNum(userPlan.getStudyNum());
        userPlanVo.setPlanId(userPlan.getPlanId());
        List<GoodsUserVo> goodsVos = userPlanGoodsService.selectGoods(bo.getPlanId(),bo.getUserId());
        userPlanVo.setGoodsVos(goodsVos);
        // List转成数组
        Long[] array = new Long[goodsVos.size()];
        // 输出数组
        List<Long> arrys = new ArrayList<>();
        for (GoodsUserVo goodsVo : goodsVos) {
            arrys.add(goodsVo.getGoodsId());
        }
        arrys.toArray(array);
        userPlanVo.setGoodsId(array);
        //得到日历日期
        List<CalendarStudyVo> calendarStudyVos = JSONObject.parseArray(userPlan.getSchedule(), CalendarStudyVo.class);
        if (bo.getMonth() != null){
            calendarStudyVos=calendarStudyVos.stream().filter(CalendarStudyVo -> CalendarStudyVo.getMonth().equals(bo.getMonth())).collect(Collectors.toList());
        }

        //得到学习的周
        List<Long> cont = JSONObject.parseArray(userPlan.getStudyCount(), Long.class);
        Long[] strings = new Long[cont.size()];
        cont.toArray(strings);

        userPlanVo.setCalendarStudyVo(calendarStudyVos);
        userPlanVo.setStudyCount(strings);
        return userPlanVo;
    }

    @Override
    public List<UserPlanVo> queryList(UserPlanQueryBo bo) {
        LambdaQueryWrapper<UserPlan> lqw = Wrappers.lambdaQuery();
        lqw.eq(StrUtil.isNotBlank(bo.getSchedule()), UserPlan::getSchedule, bo.getSchedule());
        lqw.eq(bo.getUserId() != null, UserPlan::getUserId, bo.getUserId());
        lqw.eq(bo.getExamDate() != null, UserPlan::getExamDate, bo.getExamDate());
        lqw.eq(StrUtil.isNotBlank(bo.getReminderTime()), UserPlan::getReminderTime, bo.getReminderTime());
        lqw.eq(StrUtil.isNotBlank(bo.getStudyCount()), UserPlan::getStudyCount, bo.getStudyCount());
        lqw.eq(bo.getStudyDay() != null, UserPlan::getStudyDay, bo.getStudyDay());
        lqw.eq(bo.getEndTime() != null, UserPlan::getEndTime, bo.getEndTime());
        lqw.eq(bo.getStartTime() != null, UserPlan::getStartTime, bo.getStartTime());
        lqw.in(bo.getStatus() != null, UserPlan::getStatus, bo.getStatus());
        lqw.eq(bo.getPitchNum() != null, UserPlan::getPitchNum, bo.getPitchNum());
        lqw.eq(bo.getStudyNum() != null, UserPlan::getStudyNum, bo.getStudyNum());
        List<UserPlan> userPlans = this.list(lqw);
        List<UserPlanVo> userPlanVos = new ArrayList<>();
        for (UserPlan userPlan : userPlans) {
            UserPlanVo userPlanVo = new UserPlanVo();
            userPlanVo.setUserId(userPlan.getUserId());
            userPlanVo.setExamDate(userPlan.getExamDate());
            userPlanVo.setReminderTime(userPlan.getReminderTime());
            userPlanVo.setStudyDay(userPlan.getStudyDay());
            userPlanVo.setStartTime(userPlan.getStartTime());
            userPlanVo.setEndTime(userPlan.getEndTime());
            userPlanVo.setPitchNum(userPlan.getPitchNum());
            userPlanVo.setStudyNum(userPlan.getStudyNum());
            userPlanVo.setPlanId(userPlan.getPlanId());
            List<GoodsUserVo> goodsVos = userPlanGoodsService.selectGoods(userPlanVo.getPlanId(),userPlanVo.getUserId());
            userPlanVo.setGoodsVos(goodsVos);
            // List转成数组
            Long[] array = new Long[goodsVos.size()];
            // 输出数组
            List<Long> arrys = new ArrayList<>();
            for (GoodsUserVo goodsVo : goodsVos) {
                arrys.add(goodsVo.getGoodsId());
            }
            arrys.toArray(array);
            userPlanVo.setGoodsId(array);
            //得到日历日期
            List<CalendarStudyVo> calendarStudyVos = JSONObject.parseArray(userPlan.getSchedule(), CalendarStudyVo.class);
            //得到学习的周
            List<Long> cont = JSONObject.parseArray(userPlan.getStudyCount(), Long.class);
            Long[] strings = new Long[cont.size()];
            cont.toArray(strings);

            userPlanVo.setCalendarStudyVo(calendarStudyVos);
            userPlanVo.setStudyCount(strings);
            userPlanVos.add(userPlanVo);
        }

        return userPlanVos;
    }

    /**
    * 实体类转化成视图对象
    *
    * @param collection 实体类集合
    * @return
    */
    private List<UserPlanVo> entity2Vo(Collection<UserPlan> collection) {
        List<UserPlanVo> voList = collection.stream()
                .map(any -> BeanUtil.toBean(any, UserPlanVo.class))
                .collect(Collectors.toList());
        if (collection instanceof Page) {
            Page<UserPlan> page = (Page<UserPlan>)collection;
            Page<UserPlanVo> pageVo = new Page<>();
            BeanUtil.copyProperties(page,pageVo);
            pageVo.addAll(voList);
            voList = pageVo;
        }
        return voList;
    }

    @Override
    public Boolean insertByAddBo(UserPlanAddBo bo) throws ParseException {
        validEntityPlanBeforeSave(bo);
        UserPlan userPlan = new UserPlan();
        Calendar c = Calendar.getInstance();
        c.setTime(new Date(bo.getStartTime()*1000));

        //设置为1号,当前日期既为本月第一天
        c.set(Calendar.DAY_OF_MONTH, 1);
        //将小时至0
        c.set(Calendar.HOUR_OF_DAY, 0);
        //将分钟至0
        c.set(Calendar.MINUTE, 0);
        //将秒至0
        c.set(Calendar.SECOND,0);
        //将毫秒至0
        c.set(Calendar.MILLISECOND, 0);

        Calendar c1 = Calendar.getInstance();
        c1.setTime(new Date(bo.getEndTime()*1000));
        //设置为当月最后一天
        c1.set(Calendar.DAY_OF_MONTH, c.getActualMaximum(Calendar.DAY_OF_MONTH));
        //将小时至23
        c1.set(Calendar.HOUR_OF_DAY, 23);
        //将分钟至59
        c1.set(Calendar.MINUTE, 59);
        //将秒至59
        c1.set(Calendar.SECOND,59);
        //将毫秒至999
        c1.set(Calendar.MILLISECOND, 999);

        List<CalendarStudyVo> clCalendarStudyVos = findDates(c.getTimeInMillis()/1000,c1.getTimeInMillis()/1000);
        Long secAll = 0L;
        Long sumUp = 0L;
        for (Long aLong : bo.getGoodsId()) {
            //最近考试时间七天前到现在的天数，学习视频时长
            Date date1 = new Date(bo.getEndTime() * 1000L);
            //获得相隔天数
            int dutyDays = getDutyDays(new Date(), date1, bo.getStudyCount(), bo.getStudyDay());
            if (dutyDays < 1){
                throw new IllegalArgumentException("没有学习天数，请认真填写开始结束时间");
            }
            List<Long> seLongs = baseMapper.selectGoods(aLong);
            Long allNum = 0L;
            for (Long seLong : seLongs) {
                allNum += seLong;
            }
            sumUp = allNum;
            //计算每天需要学习多少节课
            int Sec = (int) Math.ceil((double) allNum / dutyDays);
            secAll+=Sec;
            for (CalendarStudyVo clCalendarStudyVo : clCalendarStudyVos) {
                for (DayStudyVo dayStudyVo : clCalendarStudyVo.getDayStudyList()) {
                    if (Arrays.asList(bo.getStudyCount()).contains(dayStudyVo.getStudyDay())){
                        if (allNum < 0){
                            break;
                        }
                        Calendar c5 = Calendar.getInstance();
                        c.setTime(new Date(bo.getStartTime()));
                        if (dayStudyVo.getDate() <= c5.get(Calendar.DAY_OF_MONTH) && clCalendarStudyVo.getMonth() == (c5.get(Calendar.MONTH) + 1) && clCalendarStudyVo.getYear() == (c5.get(Calendar.YEAR))){
                            continue;
                        }

                        if (dayStudyVo.getStudyCourseKnob() != null) {
                            if (allNum < Sec) {
                                dayStudyVo.setStudyCourseKnob(dayStudyVo.getStudyCourseKnob() + allNum);
                            } else{
                                dayStudyVo.setStudyCourseKnob(dayStudyVo.getStudyCourseKnob() + Sec);
                            }
                        }else {
                            if (allNum < Sec) {
                                dayStudyVo.setStudyCourseKnob(allNum);
                            } else {
                                dayStudyVo.setStudyCourseKnob(Convert.toLong(Sec));
                            }
                        }

                        dayStudyVo.setPerform(0);
                        List<DaySectionVo> daySectionList = new ArrayList<>();
                        if (!CollectionUtils.isEmpty(dayStudyVo.getDaySectionList())) {
                            daySectionList = dayStudyVo.getDaySectionList();
                        }
                        DaySectionVo daySectionVo = new DaySectionVo();
                        daySectionVo.setGoodsId(aLong);
                        if (allNum < Sec) {
                            daySectionVo.setStudyGoodsKnob(Convert.toLong(allNum));
                        } else{
                            daySectionVo.setStudyGoodsKnob(Convert.toLong(Sec));
                        }

                        daySectionVo.setGoodsPerform(0);
                        daySectionList.add(daySectionVo);
                        dayStudyVo.setDaySectionList(daySectionList);
                        allNum -= Sec;

                    }
                }
            }
        }
        String s = JSON.toJSONString(clCalendarStudyVos);
        String s1 = JSON.toJSONString(bo.getStudyCount());
        userPlan.setUserId(bo.getUserId());
        userPlan.setSchedule(s);
        userPlan.setStudyCount(s1);
        userPlan.setPitchNum(sumUp);
        userPlan.setStudyDay(bo.getStudyDay());
        userPlan.setStudyNum(0L);
        userPlan.setCreateTime(DateUtils.getNowTime());
        userPlan.setUpdateTime(DateUtils.getNowTime());
        userPlan.setExamDate(bo.getExamDate());
        userPlan.setStatus(1);
        userPlan.setUserId(bo.getUserId());
        userPlan.setStartTime(bo.getStartTime());
        userPlan.setEndTime(bo.getEndTime());
        userPlan.setReminderTime(bo.getReminderTime());
        this.save(userPlan);
        for (Long goodsId : bo.getGoodsId()) {
            UserPlanGoodsAddBo userPlanGoodsAddBo = new UserPlanGoodsAddBo();
            userPlanGoodsAddBo.setPlanId(userPlan.getPlanId());
            userPlanGoodsAddBo.setSourceId(goodsId);
            userPlanGoodsAddBo.setCreateTime(DateUtils.getNowTime());
            userPlanGoodsAddBo.setUpdateTime(DateUtils.getNowTime());
            userPlanGoodsService.insertByAddBo(userPlanGoodsAddBo);
        }
        return true;
    }

    @Override
    public Boolean updateByEditBo(UserPlanEditBo bo) throws ParseException {
        UserPlan userPlan = new UserPlan();
        if (bo.getStatus().equals(-1)){
            userPlan.setPlanId(bo.getPlanId());
            userPlan.setStatus(-1);
            userPlan.setUpdateTime(DateUtils.getNowTime());
            this.updateById(userPlan);
            return true;
        }
        Calendar c = Calendar.getInstance();
        c.setTime(new Date(bo.getStartTime()*1000));

        //设置为1号,当前日期既为本月第一天
        c.set(Calendar.DAY_OF_MONTH, 1);
        //将小时至0
        c.set(Calendar.HOUR_OF_DAY, 0);
        //将分钟至0
        c.set(Calendar.MINUTE, 0);
        //将秒至0
        c.set(Calendar.SECOND,0);
        //将毫秒至0
        c.set(Calendar.MILLISECOND, 0);

        Calendar c1 = Calendar.getInstance();
        c1.setTime(new Date(bo.getEndTime()*1000));
        //设置为当月最后一天
        c1.set(Calendar.DAY_OF_MONTH, c.getActualMaximum(Calendar.DAY_OF_MONTH));
        //将小时至23
        c1.set(Calendar.HOUR_OF_DAY, 23);
        //将分钟至59
        c1.set(Calendar.MINUTE, 59);
        //将秒至59
        c1.set(Calendar.SECOND,59);
        //将毫秒至999
        c1.set(Calendar.MILLISECOND, 999);

        List<CalendarStudyVo> clCalendarStudyVos = findDates(c.getTimeInMillis()/1000,c1.getTimeInMillis()/1000);
        Long secAll = 0L;
        Long sumUp = 0L;
        for (Long aLong : bo.getGoodsId()) {
            //最近考试时间七天前到现在的天数，学习视频时长
            Date date1 = new Date(bo.getEndTime() * 1000L);
            //获得相隔天数
            int dutyDays = getDutyDays(new Date(), date1, bo.getStudyCount(), bo.getStudyDay());
            if (dutyDays < 1){
                throw new IllegalArgumentException("没有学习天数，请认真填写开始结束时间");
            }
            List<Long> seLongs = baseMapper.selectGoods(aLong);
            Long allNum = 0L;
            for (Long seLong : seLongs) {
                allNum += seLong;
            }
            sumUp = allNum;
            //计算每天需要学习多少节课
            int Sec = (int) Math.ceil((double) allNum / dutyDays);
            secAll+=Sec;
            for (CalendarStudyVo clCalendarStudyVo : clCalendarStudyVos) {
                for (DayStudyVo dayStudyVo : clCalendarStudyVo.getDayStudyList()) {
                    if (Arrays.asList(bo.getStudyCount()).contains(dayStudyVo.getStudyDay())){
                        if (allNum < 0){
                            break;
                        }
                        Calendar c5 = Calendar.getInstance();
                        c.setTime(new Date(bo.getStartTime()));
                        if (dayStudyVo.getDate() <= c5.get(Calendar.DAY_OF_MONTH) && clCalendarStudyVo.getMonth() == (c5.get(Calendar.MONTH) + 1) && clCalendarStudyVo.getYear() == (c5.get(Calendar.YEAR))){
                            continue;
                        }

                        if (dayStudyVo.getStudyCourseKnob() != null) {
                            if (allNum < Sec) {
                                dayStudyVo.setStudyCourseKnob(dayStudyVo.getStudyCourseKnob() + allNum);
                            } else{
                                dayStudyVo.setStudyCourseKnob(dayStudyVo.getStudyCourseKnob() + Sec);
                            }
                        }else {
                            if (allNum < Sec) {
                                dayStudyVo.setStudyCourseKnob(allNum);
                            } else {
                                dayStudyVo.setStudyCourseKnob(Convert.toLong(Sec));
                            }
                        }

                        dayStudyVo.setPerform(0);
                        List<DaySectionVo> daySectionList = new ArrayList<>();
                        if (!CollectionUtils.isEmpty(dayStudyVo.getDaySectionList())) {
                            daySectionList = dayStudyVo.getDaySectionList();
                        }
                        DaySectionVo daySectionVo = new DaySectionVo();
                        daySectionVo.setGoodsId(aLong);
                        if (allNum < Sec) {
                            daySectionVo.setStudyGoodsKnob(Convert.toLong(allNum));
                        } else{
                            daySectionVo.setStudyGoodsKnob(Convert.toLong(Sec));
                        }

                        daySectionVo.setGoodsPerform(0);
                        daySectionList.add(daySectionVo);
                        dayStudyVo.setDaySectionList(daySectionList);
                        allNum -= Sec;

                    }
                }
            }
        }
        String s = JSON.toJSONString(clCalendarStudyVos);
        String s1 = JSON.toJSONString(bo.getStudyCount());
        userPlan.setUserId(bo.getUserId());
        userPlan.setSchedule(s);
        userPlan.setStudyCount(s1);
        userPlan.setPitchNum(sumUp);
        userPlan.setStudyDay(bo.getStudyDay());
        userPlan.setStudyNum(0L);
        userPlan.setCreateTime(DateUtils.getNowTime());
        userPlan.setUpdateTime(DateUtils.getNowTime());
        userPlan.setExamDate(bo.getExamDate());
        userPlan.setStatus(1);
        userPlan.setUserId(bo.getUserId());
        userPlan.setStartTime(bo.getStartTime());
        userPlan.setEndTime(bo.getEndTime());
        userPlan.setReminderTime(bo.getReminderTime());
        userPlan.setPlanId(bo.getPlanId());
        this.updateById(userPlan);
        LambdaQueryWrapper<UserPlanGoods> lqw = Wrappers.lambdaQuery();
        lqw.eq(UserPlanGoods::getPlanId, userPlan.getPlanId());
        userPlanGoodsService.remove(lqw);
        for (Long goodsId : bo.getGoodsId()) {
            UserPlanGoodsAddBo userPlanGoodsAddBo = new UserPlanGoodsAddBo();
            userPlanGoodsAddBo.setPlanId(userPlan.getPlanId());
            userPlanGoodsAddBo.setSourceId(goodsId);
            userPlanGoodsAddBo.setCreateTime(DateUtils.getNowTime());
            userPlanGoodsAddBo.setUpdateTime(DateUtils.getNowTime());
            userPlanGoodsService.insertByAddBo(userPlanGoodsAddBo);
        }
        return true;
    }

    /**
     * 保存前的数据校验
     *
     * @param entity 实体类数据
     */
    private void validEntityBeforeSave(UserPlan entity){
        //TODO 做一些数据校验,如唯一约束
    }

    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return this.removeByIds(ids);
    }

    @Override
    public UserPlanVo listPlan(UserPlanEditBo bo) throws ParseException {
        UserPlanVo userPlanVo = new UserPlanVo();
        Calendar c = Calendar.getInstance();
        c.setTime(new Date(bo.getStartTime()*1000));

        //设置为1号,当前日期既为本月第一天
        c.set(Calendar.DAY_OF_MONTH, 1);
        //将小时至0
        c.set(Calendar.HOUR_OF_DAY, 0);
        //将分钟至0
        c.set(Calendar.MINUTE, 0);
        //将秒至0
        c.set(Calendar.SECOND,0);
        //将毫秒至0
        c.set(Calendar.MILLISECOND, 0);

        Calendar c1 = Calendar.getInstance();
        c1.setTime(new Date(bo.getEndTime()*1000));
        //设置为当月最后一天
        c1.set(Calendar.DAY_OF_MONTH, c.getActualMaximum(Calendar.DAY_OF_MONTH));
        //将小时至23
        c1.set(Calendar.HOUR_OF_DAY, 23);
        //将分钟至59
        c1.set(Calendar.MINUTE, 59);
        //将秒至59
        c1.set(Calendar.SECOND,59);
        //将毫秒至999
        c1.set(Calendar.MILLISECOND, 999);

        List<CalendarStudyVo> clCalendarStudyVos = findDates(c.getTimeInMillis()/1000,c1.getTimeInMillis()/1000);
        Long secAll = 0L;
        for (Long aLong : bo.getGoodsId()) {
            //最近考试时间七天前到现在的天数，学习视频时长
            Date date1 = new Date(bo.getEndTime() * 1000L);
            //获得相隔天数
            int dutyDays = getDutyDays(new Date(), date1, bo.getStudyCount(), bo.getStudyDay());
            if (dutyDays < 1){
                throw new IllegalArgumentException("没有学习天数，请认真填写开始结束时间");
            }
            List<Long> seLongs = baseMapper.selectGoods(aLong);
            Long allNum = 0L;
            for (Long seLong : seLongs) {
                allNum += seLong;
            }
            //计算每天需要学习多少节课
            int Sec = (int) Math.ceil((double) allNum / dutyDays);
            secAll+=Sec;
            for (CalendarStudyVo clCalendarStudyVo : clCalendarStudyVos) {
                for (DayStudyVo dayStudyVo : clCalendarStudyVo.getDayStudyList()) {
                    if (Arrays.asList(bo.getStudyCount()).contains(dayStudyVo.getStudyDay())){
                        if (allNum < 0){
                            break;
                        }
                        Calendar c5 = Calendar.getInstance();
                        c.setTime(new Date(bo.getStartTime()));
                        if (dayStudyVo.getDate() <= c5.get(Calendar.DAY_OF_MONTH) && clCalendarStudyVo.getMonth() == (c5.get(Calendar.MONTH) + 1) && clCalendarStudyVo.getYear() == (c5.get(Calendar.YEAR))){
                            continue;
                        }

                        if (dayStudyVo.getStudyCourseKnob() != null) {
                            if (allNum < Sec) {
                                dayStudyVo.setStudyCourseKnob(dayStudyVo.getStudyCourseKnob() + allNum);
                            } else{
                                dayStudyVo.setStudyCourseKnob(dayStudyVo.getStudyCourseKnob() + Sec);
                            }
                        }else {
                            if (allNum < Sec) {
                                dayStudyVo.setStudyCourseKnob(allNum);
                            } else {
                                dayStudyVo.setStudyCourseKnob(Convert.toLong(Sec));
                            }
                        }

                        dayStudyVo.setPerform(0);
                        List<DaySectionVo> daySectionList = new ArrayList<>();
                        if (!CollectionUtils.isEmpty(dayStudyVo.getDaySectionList())) {
                            daySectionList = dayStudyVo.getDaySectionList();
                        }
                        DaySectionVo daySectionVo = new DaySectionVo();
                        daySectionVo.setGoodsId(aLong);
                        if (allNum < Sec) {
                            daySectionVo.setStudyGoodsKnob(Convert.toLong(allNum));
                        } else{
                            daySectionVo.setStudyGoodsKnob(Convert.toLong(Sec));
                        }

                        daySectionVo.setGoodsPerform(0);
                        daySectionList.add(daySectionVo);
                        dayStudyVo.setDaySectionList(daySectionList);
                        allNum -= Sec;

                    }
                }
            }
        }
        userPlanVo.setCalendarStudyVo(clCalendarStudyVos);
        userPlanVo.setStudyCourseKnob(secAll);
        return userPlanVo;
    }

    //获得日历
    public static List<CalendarStudyVo> findDates(Long dBegin, Long dEnd) throws ParseException, java.text.ParseException {
        Long timeStamp = System.currentTimeMillis();  //获取当前时间戳
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
        String dBeginS = sdf.format(new Date(Long.parseLong(String.valueOf(dBegin*1000))));      // 时间戳转换成时间
        String dEndS = sdf.format(new Date(Long.parseLong(String.valueOf(dEnd*1000))));      // 时间戳转换成时间

        //日期工具类准备
        DateFormat format = new SimpleDateFormat("yyyy-MM-dd");

        //设置开始时间
        Calendar calBegin = Calendar.getInstance();
        calBegin.setTime(format.parse(dBeginS));

        //设置结束时间
        Calendar calEnd = Calendar.getInstance();
        calEnd.setTime(format.parse(dEndS));

        //装返回的日期集合容器
        List<CalendarStudyVo> Datelist = new ArrayList<CalendarStudyVo>();

        CalendarStudyVo calendarStudyVo = new CalendarStudyVo();
        List<DayStudyVo> dayStudyList = new ArrayList<>();
        // 每次循环给calBegin日期加一天，直到calBegin.getTime()时间等于dEnd
        while (format.parse(dEndS).after(calBegin.getTime()))  {
            if (calendarStudyVo.getMonth() == null){
                calendarStudyVo.setMonth(Convert.toLong(calBegin.get(java.util.Calendar.MONTH)+1));
                calendarStudyVo.setYear(Convert.toLong(calBegin.get(java.util.Calendar.YEAR)));
            }
            if (calendarStudyVo.getMonth() != null && calendarStudyVo.getMonth() != (calBegin.get(java.util.Calendar.MONTH)+1)){
                calendarStudyVo.setDayStudyList(dayStudyList);
                Datelist.add(calendarStudyVo);
                calendarStudyVo = new CalendarStudyVo();
                dayStudyList = new ArrayList<>();
                calendarStudyVo.setMonth(Convert.toLong(calBegin.get(java.util.Calendar.MONTH)+1));
                calendarStudyVo.setYear(Convert.toLong(calBegin.get(java.util.Calendar.YEAR)));
            }
            DayStudyVo dayStudyVo = new DayStudyVo();
            dayStudyVo.setDate(Convert.toLong(calBegin.get(Calendar.DATE)));
            dayStudyVo.setStudyDay(Convert.toLong(calBegin.get(Calendar.DAY_OF_WEEK)-1));
            dayStudyList.add(dayStudyVo);
            // 根据日历的规则，为给定的日历字段添加或减去指定的时间量
            calBegin.add(Calendar.DAY_OF_MONTH, 1);
        }
        calendarStudyVo.setDayStudyList(dayStudyList);
        Datelist.add(calendarStudyVo);
        return Datelist;
    }

    //获得可用学习天数
    private static int getDutyDays(Date  startDateStr, Date endDateStr,Long[] longs,Long studyDay)  {
        int result = 0;
        Date endDate = endDateStr;
        Calendar c = Calendar.getInstance();
        c.setTime(endDate);
        c.add(Calendar.DATE, - Convert.toInt(studyDay));
        endDate = c.getTime();

        Date startDate = startDateStr;
        int day = startDate.getDay();
        while (startDate.compareTo(endDate) <= 0) {
            for (Long integer : longs) {
                if (startDate.getDay() == integer) {
                    result++;
                    break;
                }
            }
            startDate.setDate(startDate.getDate() + 1);
        }
        return result-1;
    }

    @Override
    public List<GoodsVo> listGoods(UserPlanQueryBo bo) {
        return baseMapper.listGoods(bo);
    }

    @Override
    public List<UserPlanVo> userPlanSeven(UserPlanQueryBo bo) throws ParseException {
        LambdaQueryWrapper<UserPlan> lqw = Wrappers.lambdaQuery();
        lqw.eq(StrUtil.isNotBlank(bo.getSchedule()), UserPlan::getSchedule, bo.getSchedule());
        lqw.eq(bo.getUserId() != null, UserPlan::getUserId, bo.getUserId());
        lqw.eq(bo.getExamDate() != null, UserPlan::getExamDate, bo.getExamDate());
        lqw.eq(StrUtil.isNotBlank(bo.getReminderTime()), UserPlan::getReminderTime, bo.getReminderTime());
        lqw.eq(StrUtil.isNotBlank(bo.getStudyCount()), UserPlan::getStudyCount, bo.getStudyCount());
        lqw.eq(bo.getStudyDay() != null, UserPlan::getStudyDay, bo.getStudyDay());
        lqw.eq(bo.getEndTime() != null, UserPlan::getEndTime, bo.getEndTime());
        lqw.eq(bo.getStartTime() != null, UserPlan::getStartTime, bo.getStartTime());
        lqw.in(bo.getStatus() != null, UserPlan::getStatus, bo.getStatus());
        lqw.eq(bo.getPitchNum() != null, UserPlan::getPitchNum, bo.getPitchNum());
        lqw.eq(bo.getStudyNum() != null, UserPlan::getStudyNum, bo.getStudyNum());
        List<UserPlan> userPlans = this.list(lqw);
        List<UserPlanVo> userPlanVos = new ArrayList<>();
        for (UserPlan userPlan : userPlans) {
            //得到日历日期
            UserPlanVo userPlanVo = new UserPlanVo();
            userPlanVo.setUserId(userPlan.getUserId());
            userPlanVo.setExamDate(userPlan.getExamDate());
            userPlanVo.setReminderTime(userPlan.getReminderTime());
            userPlanVo.setStudyDay(userPlan.getStudyDay());
            userPlanVo.setStartTime(userPlan.getStartTime());
            userPlanVo.setEndTime(userPlan.getEndTime());
            userPlanVo.setPitchNum(userPlan.getPitchNum());
            userPlanVo.setStudyNum(userPlan.getStudyNum());
            userPlanVo.setPlanId(userPlan.getPlanId());
            List<GoodsUserVo> goodsVos = userPlanGoodsService.selectGoods(userPlan.getPlanId(), bo.getUserId());
            userPlanVo.setGoodsVos(goodsVos);
            // List转成数组
            Long[] array = new Long[goodsVos.size()];
            // 输出数组
            List<Long> arrys = new ArrayList<>();
            for (GoodsUserVo goodsVo : goodsVos) {
                arrys.add(goodsVo.getGoodsId());
            }
            arrys.toArray(array);
            userPlanVo.setGoodsId(array);
            //得到日历日期
            List<CalendarStudyVo> calendarStudyVos = JSONObject.parseArray(userPlan.getSchedule(), CalendarStudyVo.class);

            Calendar cal = Calendar.getInstance();
            cal.add(Calendar.WEEK_OF_MONTH, 0);
            cal.set(Calendar.DAY_OF_WEEK, 2);
            Long timeInMillisStart = cal.getTimeInMillis() / 1000 - 86400;
            Calendar cal2 = Calendar.getInstance();
            cal2.set(Calendar.DAY_OF_WEEK, cal.getActualMaximum(Calendar.DAY_OF_WEEK));
            cal2.add(Calendar.DAY_OF_WEEK, 1);
            Long timeInMillis = cal2.getTimeInMillis() / 1000;
            List<CalendarStudyVo> sevenDates = findSevenDates(timeInMillisStart, timeInMillis);
            for (CalendarStudyVo sevenDate : sevenDates) {
                for (DayStudyVo dayStudyVo : sevenDate.getDayStudyList()) {
                    List<CalendarStudyVo> collect = calendarStudyVos.stream().filter(CalendarStudyVo -> CalendarStudyVo.getMonth().equals(sevenDate.getMonth())).collect(Collectors.toList());
                    if (!CollectionUtils.isEmpty(collect)) {
                        for (CalendarStudyVo calendarStudyVo : collect) {
                            for (DayStudyVo studyVo : calendarStudyVo.getDayStudyList()) {
                                if (studyVo.getDate().equals(dayStudyVo.getDate())) {
                                    dayStudyVo.setStudyCourseKnob(studyVo.getStudyCourseKnob());
                                    dayStudyVo.setPerform(studyVo.getPerform());
                                    dayStudyVo.setDaySectionList(studyVo.getDaySectionList());
                                    break;
                                }
                            }
                        }
                    }
                }
            }
            //得到学习的周
            List<Long> cont = JSONObject.parseArray(userPlan.getStudyCount(), Long.class);
            Long[] strings = new Long[cont.size()];
            cont.toArray(strings);

            userPlanVo.setCalendarStudyVo(sevenDates);
            userPlanVo.setStudyCount(strings);
            userPlanVos.add(userPlanVo);
        }
        return userPlanVos;
    }


    /**
     * 保存前的数据校验
     *
     * @param bo 实体类数据
     */
    private void validEntityPlanBeforeSave(UserPlanAddBo bo){
        //判断是否商品已被生成过课程
        Integer rank = baseMapper.selectCountGoods(bo);
        if (rank > 0){
            throw new IllegalArgumentException("此网课学习计划正在进行中，若想再次制定请将计划完成或删除");
        }
    }

    //获得日历
    public static List<CalendarStudyVo> findSevenDates(Long dBegin, Long dEnd) throws ParseException, java.text.ParseException {
        Long timeStamp = System.currentTimeMillis();  //获取当前时间戳
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
        String dBeginS = sdf.format(new Date(Long.parseLong(String.valueOf(dBegin*1000))));      // 时间戳转换成时间
        String dEndS = sdf.format(new Date(Long.parseLong(String.valueOf(dEnd*1000))));      // 时间戳转换成时间

        //日期工具类准备
        DateFormat format = new SimpleDateFormat("yyyy-MM-dd");

        //设置开始时间
        Calendar calBegin = Calendar.getInstance();
        calBegin.setTime(format.parse(dBeginS));

        //设置结束时间
        Calendar calEnd = Calendar.getInstance();
        calEnd.setTime(format.parse(dEndS));

        //装返回的日期集合容器
        List<CalendarStudyVo> Datelist = new ArrayList<CalendarStudyVo>();

        CalendarStudyVo calendarStudyVo = new CalendarStudyVo();
        List<DayStudyVo> dayStudyList = new ArrayList<>();
        // 每次循环给calBegin日期加一天，直到calBegin.getTime()时间等于dEnd
        while (format.parse(dEndS).after(calBegin.getTime()))  {
            if (calendarStudyVo.getMonth() == null){
                calendarStudyVo.setMonth(Convert.toLong(calBegin.get(java.util.Calendar.MONTH)+1));
                calendarStudyVo.setYear(Convert.toLong(calBegin.get(java.util.Calendar.YEAR)));
            }
            if (calendarStudyVo.getMonth() != null && calendarStudyVo.getMonth() != (calBegin.get(java.util.Calendar.MONTH)+1)){
                calendarStudyVo.setDayStudyList(dayStudyList);
                Datelist.add(calendarStudyVo);
                calendarStudyVo = new CalendarStudyVo();
                dayStudyList = new ArrayList<>();
                calendarStudyVo.setMonth(Convert.toLong(calBegin.get(java.util.Calendar.MONTH)+1));
                calendarStudyVo.setYear(Convert.toLong(calBegin.get(java.util.Calendar.YEAR)));
            }
            DayStudyVo dayStudyVo = new DayStudyVo();
            dayStudyVo.setDate(Convert.toLong(calBegin.get(Calendar.DATE)));
            dayStudyVo.setStudyDay(Convert.toLong(calBegin.get(Calendar.DAY_OF_WEEK)-1));
            dayStudyList.add(dayStudyVo);
            // 根据日历的规则，为给定的日历字段添加或减去指定的时间量
            calBegin.add(Calendar.DAY_OF_MONTH, 1);
        }
        calendarStudyVo.setDayStudyList(dayStudyList);
        Datelist.add(calendarStudyVo);
        return Datelist;
    }
}
