package com.hzu.labbooking.service.impl;

import java.util.*;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hzu.labbooking.constant.Constants;
import com.hzu.labbooking.constant.RecordStatusConstants;
import com.hzu.labbooking.constant.WeekStatusConstants;
import com.hzu.labbooking.domain.*;
import com.hzu.labbooking.domain.component.MapKey;
import com.hzu.labbooking.domain.component.RecordTableKey;
import com.hzu.labbooking.domain.vo.*;
import com.hzu.labbooking.mapper.LabWeekMapper;
import com.hzu.labbooking.service.*;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.web.service.TokenService;
import com.ruoyi.system.service.ISysDeptService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.hzu.labbooking.mapper.LabMapper;

/**
 * 实验室信息Service业务层处理
 *
 * @author yezihao
 * @date 2021-04-29
 */
@Service
public class LabServiceImpl extends ServiceImpl<LabMapper, Lab> implements ILabService {

    @Autowired
    private LabMapper labMapper;
    @Autowired
    private ILabRecordService recordService;
    @Autowired
    private ILabWeekService weekService;
    @Autowired
    private ICourseService courseService;
    @Autowired
    private TokenService tokenService;
    @Autowired
    private ISysDeptService deptService;
    @Autowired
    private IRecordWeekService recordWeekService;
    @Autowired
    private LabWeekMapper weekMapper;

    /**
     * 查询实验室信息
     *
     * @param id 实验室信息ID
     * @return 实验室信息
     */
    @Override
    public Lab selectLabById(Long id) {
        return labMapper.selectLabById(id);
    }

    /**
     * 查询实验室信息列表
     *
     * @param lab 实验室信息
     * @return 实验室信息
     */
    @Override
    public List<LabVO> selectBookLabList(Lab lab) {

        // 1.获取当前用户所属学院及公共学院的所有实验室信息
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        Long deptId = loginUser.getUser().getDeptId();
        Long parentDeptId = deptService.getParentDeptId(deptId);
        List<LabVO> voList = labMapper.selectBookLabList(lab, deptId, parentDeptId);

        // 2.封装学院名称到list中
        List<Long> deptIdList = new ArrayList<>();
        //遍历voList,获取学院id集合
        for (LabVO labVO : voList) {
            deptIdList.add(labVO.getDeptId());
        }

        if (voList.size() > 0) {
            //通过学院id集合获取学院列表
            List<SysDept> deptList = deptService.selectDeptNameByIds(deptIdList);
            //创建Map，通过遍历deptList获取以学院id和学院名字为键值对的集合
            Map<Long, String> map = new HashMap<>();
            for (SysDept sysDept : deptList) {
                map.put(sysDept.getDeptId(), sysDept.getDeptName());
            }
            //遍历voList，通过map,添加学院名称
            for (LabVO labVO : voList) {
                labVO.setDeptName(map.get(labVO.getDeptId()));
            }
        }

        return voList;
    }

    /**
     * 管理员查询实验室信息列表
     *
     * @param lab 实验室信息
     * @return 实验室信息
     */
    @Override
    public List<MyLabVO> selectLabList(Lab lab) {
        // 1.获取当前用户所属学院及公共学院的所有实验室信息
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        Long userId = loginUser.getUser().getUserId();
        Long deptId = loginUser.getUser().getDeptId();

        Long parentDeptId = deptService.getParentDeptId(deptId);
        // 通过lab、学院id和用户名查询实验室列表
        List<MyLabVO> voList = labMapper.selectLabList(lab, deptId, parentDeptId, userId);
        // 2.封装学院名称到list中
        List<Long> deptIdList = new ArrayList<>();
        // 遍历voList,获取学院id集合
        for (MyLabVO myLabVO : voList) {
            deptIdList.add(myLabVO.getDeptId());
        }

        if (voList.size() > 0) {
            // 通过学院id集合获取学院列表
            List<SysDept> deptList = deptService.selectDeptNameByIds(deptIdList);
            // 创建Map，通过遍历deptList获取以学院id和学院名字为键值对的集合
            Map<Long, String> map = new HashMap<>();
            for (SysDept sysDept : deptList) {
                map.put(sysDept.getDeptId(), sysDept.getDeptName());
            }
            // 遍历voList，通过map,添加学院名称
            for (MyLabVO myLabVO : voList) {
                myLabVO.setDeptName(map.get(myLabVO.getDeptId()));
            }
        }

        return voList;
    }

    /**
     * 新增实验室信息
     *
     * @param lab 实验室信息
     * @return 结果
     */
    @Override
    public int insertLab(Lab lab) {
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        //获取登录用户的用户名
        Long userId = loginUser.getUser().getUserId();
        lab.setUserId(userId);

        QueryWrapper<Lab> wrapper = new QueryWrapper<>();
        wrapper.eq("name", lab.getName()).or().eq("location", lab.getLocation());
        List<Lab> labs = labMapper.selectList(wrapper);
        if (StringUtils.isNotEmpty(labs)) {
            return -1;
        } else {
            return labMapper.insert(lab);
        }
    }

    /**
     * 修改实验室信息
     *
     * @param lab 实验室信息
     * @return 结果
     */
    @Override
    public int updateLab(Lab lab) {
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        //获取登录用户的用户名
        Long userId = loginUser.getUser().getUserId();

        //表单校验
        //1. 实验室名称和位置相同，直接修改
        QueryWrapper<Lab> wrapper1 = new QueryWrapper<>();
        wrapper1.eq("user_id", userId).eq("name", lab.getName())
                .eq("location", lab.getLocation()).eq("id", lab.getId());
        List<Lab> labs1 = labMapper.selectList(wrapper1);
        if (StringUtils.isNotEmpty(labs1)) {
            return labMapper.updateLab(lab);
        }

        //2. 实验室名称相同，位置不同，对位置进行校验，不重复时修改
        QueryWrapper<Lab> wrapper2 = new QueryWrapper<>();
        wrapper2.eq("user_id", userId).eq("name", lab.getName())
                .ne("location", lab.getLocation()).eq("id", lab.getId());
        List<Lab> labs2 = labMapper.selectList(wrapper2);
        if (StringUtils.isNotEmpty(labs2)) {
            List<Lab> list = labMapper.selectList(new QueryWrapper<Lab>().eq("location", lab.getLocation()).ne("id", lab.getId()));
            if (StringUtils.isNotEmpty(list)) {
                return -1;
                //throw new BaseException("实验室名字相同~~~~~~~~~~~~~~~~~~");
            } else {
                return labMapper.updateLab(lab);
            }
        }

        //3. 实验室名称不同，位置相同，对名称进行校验，不重复时修改
        QueryWrapper<Lab> wrapper3 = new QueryWrapper<>();
        wrapper2.eq("user_id", userId).ne("name", lab.getName())
                .eq("location", lab.getLocation()).eq("id", lab.getId());
        List<Lab> labs3 = labMapper.selectList(wrapper3);
        if (StringUtils.isNotEmpty(labs3)) {
            List<Lab> list = labMapper.selectList(new QueryWrapper<Lab>().eq("name", lab.getName()).ne("id", lab.getId()));
            if (StringUtils.isNotEmpty(list)) {
                return -2;
            } else {
                return labMapper.updateLab(lab);
            }
        }

        //4. 实验室名称不同，位置不同，对名称或位置进行校验，不重复时修改
        QueryWrapper<Lab> wrapper4 = new QueryWrapper<>();
        wrapper2.eq("user_id", userId).ne("name", lab.getName())
                .ne("location", lab.getLocation()).eq("id", lab.getId());
        List<Lab> labs4 = labMapper.selectList(wrapper4);
        if (StringUtils.isNotEmpty(labs4)) {
            List<Lab> list = labMapper.selectList(new QueryWrapper<Lab>().eq("name", lab.getName()).or().eq("location", lab.getLocation()));
            if (StringUtils.isNotEmpty(list)) {
                return -3;
            } else {
                return labMapper.updateLab(lab);
            }
        }
        return -4;
    }

    /**
     * 获取当前用户的课表
     */
    @Override
    public List<LabTableVO> getAllLabTable(Long year, Long term) {
        // 1.获取当前用户信息
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        Long userId = loginUser.getUser().getUserId();
        String nickName = loginUser.getUser().getNickName();

        // 2.根据user_id在record查出该条预约记录
        QueryWrapper<LabRecord> recordQueryWrapper = new QueryWrapper<>();
        recordQueryWrapper
                .eq("user_id", userId)
                .eq("year", year).eq("term", term)
                .ne("status", RecordStatusConstants.REJECTED)
                .ne("status", RecordStatusConstants.CANCELLED);
        List<LabRecord> recordList = recordService.list(recordQueryWrapper); // 当前学年学期所有预约记录

        if (recordList == null || recordList.size() == 0) {
            return null; // 课表为空
        }

        // 3.根据预约记录id获取对应的weekIdList，并封装聚合课程
        Map<RecordTableKey, List<LabWeek>> recordWeekMap = new HashMap<>();
        for (LabRecord record : recordList) {
            List<Long> weekIdList = recordWeekService.selectWeekList(record.getId());

            QueryWrapper<LabWeek> weekQueryWrapper = new QueryWrapper<>();
            weekQueryWrapper.in("id", weekIdList);
            weekQueryWrapper.eq("status", WeekStatusConstants.CLOSED);

            // 获取当前预约所有周次
            List<LabWeek> labWeekList = weekMapper.selectList(weekQueryWrapper);

            if (labWeekList.isEmpty()) {
                continue;
            }

            RecordTableKey recordTableKey = new RecordTableKey();
            recordTableKey.setCourseId(record.getCourseId());
            recordTableKey.setLabId(record.getLabId());
            recordTableKey.setDay(record.getDay());
            recordTableKey.setTime(record.getTime());
            recordTableKey.setUserId(record.getUserId());
            recordTableKey.setId(0L);
            //BeanUtils.copyProperties(record, recordTableKey);

            // 若遇到相同预约，不同周次，将其添加到周次中
            if (!recordWeekMap.containsKey(recordTableKey)) {
                List<LabWeek> weeks = new ArrayList<>(labWeekList);
                recordWeekMap.put(recordTableKey, weeks);
            } else {
                recordWeekMap.get(recordTableKey).addAll(labWeekList);
            }
        }

        // 封装每个daytime中课程/dataList数据
        Map<MapKey, List<LabTableDataVO>> mp = new HashMap<>();
        for (Map.Entry<RecordTableKey, List<LabWeek>> recordWeek : recordWeekMap.entrySet()) {
            RecordTableKey key = recordWeek.getKey();

            Lab lab = this.getById(key.getLabId());
            //判断实验室是否关闭
            //if (lab.getStatus()==0) {
            //    continue;
            //}
            Course course = courseService.getById(key.getCourseId());

            // 获取到该预约记录预约周次
            List<Long> weekList = new ArrayList<>();
            for (LabWeek week : recordWeek.getValue()) {
                weekList.add(week.getWeek());
            }

            LabTableDataVO dataVO = new LabTableDataVO();
            dataVO.setCourseId(key.getCourseId());
            dataVO.setClassName(course.getClassName());
            dataVO.setCourseName(course.getName());
            dataVO.setTeacherName(nickName);
            dataVO.setLabId(lab.getId());
            dataVO.setLocation(lab.getLocation());
            dataVO.setDay(key.getDay());
            dataVO.setTime(key.getTime());
            dataVO.setWeekList(weekList);
            dataVO.setWeek(convert(weekList));

            List<LabTableDataVO> dataList = new ArrayList<>();

            MapKey mapKey = new MapKey();
            mapKey.setDay(key.getDay());
            mapKey.setTime(key.getTime());

            // 如果存在(day,time)相同，则加到其的list中，否则new list加入
            if (!mp.containsKey(mapKey)) {
                dataList.add(dataVO);
                mp.put(mapKey, dataList);
            } else {
                mp.get(mapKey).add(dataVO);
            }
        }

        // 封装结果
        List<LabTableVO> voList = new ArrayList<>();
        for (MapKey key : mp.keySet()) {
            List<LabTableDataVO> dataList = mp.get(key);

            LabTableVO vo = new LabTableVO();
            vo.setDay(key.getDay());
            vo.setTime(key.getTime());
            vo.setDataList(dataList);

            voList.add(vo);
        }

        return voList;
    }

    @Override
    public LabTableDetailsVO getTableDetails(Long labId) {
        LabTableDetailsVO vo = new LabTableDetailsVO();
        Lab lab = this.getById(labId);
        LabRecord record = recordService.getById(labId);
        Course course = courseService.getById(record.getCourseId());
        vo.setRequirement(lab.getRequirement());
        vo.setCapacity(lab.getCapacity());
        vo.setLabRemark(lab.getRemarks());
        vo.setNumber(course.getNumber());
        vo.setCourseRemark(course.getRemarks());
        return vo;
    }

    /**
     * 该实验室这个学年学期，被预约具体周的个数，1周相当于1节也就是2课时
     * 获取这个学期所有预约记录，找到对应的week，并且状态必须为0，表示已占用；
     * 使用率=不可用时间段/总实验室提供学时（18周*7天*5节*2学时=1260学时/学期），1条week=2学时
     * 1.查出指定学年学期所有预约记录
     * 2.通过lab_id查出week个数，且其状态为0表示已被占用；封装 resultMap(labId=week个数*2)
     * 3.封装数据并排序
     * 最后统计出占用学时：不可用时间段useTime=useCount*2
     */
    @Override
    public List<LabUseVO> getLabUseRate(Long year, Long term) {
        // 1.查出指定学年学期所有预约记录
        QueryWrapper<LabRecord> recordQueryWrapper = new QueryWrapper<>();
        recordQueryWrapper
                .eq("year", year).eq("term", term)
                .ne("status", RecordStatusConstants.REJECTED)
                .ne("status", RecordStatusConstants.CANCELLED);
        List<LabRecord> tmpRecordList = recordService.list(recordQueryWrapper);

        if (tmpRecordList.isEmpty()) {
            return new ArrayList<>();
        }

        // 2.通过lab_id查出week个数，且其状态为0表示已被占用；封装 resultMap(labId=week个数*2)
        Map<Long, Integer> resultMap = new HashMap<>();
        for (LabRecord record : tmpRecordList) {
            QueryWrapper<RecordWeek> wrapper = new QueryWrapper<>();
            wrapper.select("week_id").eq("record_id", record.getId());
            List<RecordWeek> weekList = recordWeekService.list(wrapper);

            List<Long> weekIdList = new ArrayList<>();
            for (RecordWeek weekId : weekList) {
                weekIdList.add(weekId.getWeekId());
            }
            QueryWrapper<LabWeek> weekQueryWrapper = new QueryWrapper<>();
            weekQueryWrapper.in("id", weekIdList);
            weekQueryWrapper.eq("status", WeekStatusConstants.CLOSED);
            int count = weekService.count(weekQueryWrapper);
            resultMap.put(record.getLabId(), resultMap.getOrDefault(record.getLabId(), 0) + count);
        }

        List<LabUseVO> vos = new ArrayList<>();
        for (Long labId : resultMap.keySet()) {
            QueryWrapper<Lab> w = new QueryWrapper<>();
            w.select("name").eq("id", labId);
            Lab lab = this.getOne(w);

            LabUseVO labUseVO = new LabUseVO();
            labUseVO.setLabName(lab.getName()); //每个实验室名称
            labUseVO.setUse(resultMap.get(labId)); //每个实验室被预约使用时间 status=0
            labUseVO.setAll();
            labUseVO.setRate();
            vos.add(labUseVO);
        }

        vos.sort(new Comparator<LabUseVO>() {
            @Override
            public int compare(LabUseVO o1, LabUseVO o2) {
                return -(o1.getUse() - o2.getUse());
            }
        });

        return vos;
    }

    /**
     * 获取某个实验室的可预约课表
     * 1. 根据lab_id, year, term, status=0在lab_time查出所有记录(lab_id, week, day, time)
     * 这个查出来的记录表示已占用的，我们之后对无法预约的时间求绝对补集得到所有可预约时间
     * 2. 维护一个HashMap，key是(day,time)，value是list<week>
     * 3. 双重遍历day和time，从HashMap取出list<week>，然后取这个list的补集，再转化成String放到LabWeekVO
     */
    @Override
    public List<LabTableVO> getAllApplyTable(long labId, long year, long term) {
        /*
        获取某个实验室的可预约课表
        1.找出所有不可预约的时间，之后求补集
        2.通过record_id获取week_id，封装key(day,time)=value(week)
        3.双重遍历day和time，从HashMap取出weekList，然后取这个list的补集，再转化成String放到 LabTableVO
         */

        // 1.找出所有不可预约的时间，之后求补集
        QueryWrapper<LabRecord> recordQueryWrapper = new QueryWrapper<>();
        recordQueryWrapper
                .eq("lab_id", labId)
                .eq("year", year)
                .eq("term", term)
                .ne("status", RecordStatusConstants.REJECTED)
                .ne("status", RecordStatusConstants.CANCELLED);
        List<LabRecord> recordList = recordService.list(recordQueryWrapper);

        // 2.通过record_id获取week_id，封装key(day,time)=value(week)
        Map<MapKey, List<Long>> mp = new HashMap<>();
        for (LabRecord record : recordList) {
            List<Long> weekIdList = recordWeekService.selectWeekList(record.getId());

            QueryWrapper<LabWeek> weekQueryWrapper = new QueryWrapper<>();
            weekQueryWrapper.in("id", weekIdList);
            weekQueryWrapper.eq("status", WeekStatusConstants.CLOSED);

            // 获取当前预约所有周次
            List<LabWeek> labWeekList = weekMapper.selectList(weekQueryWrapper);

            if (labWeekList.isEmpty()) {
                continue;
            }

            List<Long> weekList = new ArrayList<>();
            for (LabWeek week : labWeekList) {
                weekList.add(week.getWeek());
            }

            MapKey key = new MapKey(record.getDay(), record.getTime());

            // 若遇到相同预约，不同周次，将其添加到周次中
            if (!mp.containsKey(key)) {
                mp.put(key, weekList);
            } else {
                mp.get(key).addAll(weekList);
            }
        }

        // 3.双重遍历day和time，从HashMap取出weekList，然后取这个list的补集，再转化成String放到 LabTableVO
        List<LabTableVO> voList = new ArrayList<>();
        for (long day = 1; day <= Constants.DAY_SIZE; day++) {
            for (long time = 1; time <= Constants.TIME_SIZE; time++) {
                LabTableVO vo = new LabTableVO();

                List<Long> weekList = new ArrayList<>();
                MapKey key = new MapKey(day, time);
                if (!mp.containsKey(key)) {
                    for (long i = 1; i <= Constants.WEEK_SIZE; i++) {
                        weekList.add(i);
                    }
                } else {
                    List<Long> tmpList = mp.get(key);
                    for (long i = 1; i <= Constants.WEEK_SIZE; i++) {
                        boolean f = true;
                        for (Long tmp : tmpList) {
                            if (i == tmp) {
                                f = false;
                                break;
                            }
                        }
                        if (f) {
                            weekList.add(i);
                        }
                    }
                }
                vo.setLabId(labId);
                vo.setDay(day);
                vo.setTime(time);
                vo.setWeekList(weekList);
                if (weekList.isEmpty()) {
                    vo.setWeek("已满");
                } else {
                    vo.setWeek(convert(weekList) + " 可预约");
                }
                voList.add(vo);
            }
        }

        return voList;
    }

    @Override
    public List<LabTableVO> getAllAppliedTable(long labId, long year, long term) {
        // 1.找出所有不可预约的时间，之后求补集
        QueryWrapper<LabRecord> recordQueryWrapper = new QueryWrapper<>();
        recordQueryWrapper
                .eq("lab_id", labId)
                .eq("year", year)
                .eq("term", term)
                .ne("status", RecordStatusConstants.REJECTED)
                .ne("status", RecordStatusConstants.CANCELLED);
        List<LabRecord> recordList = recordService.list(recordQueryWrapper);

        // 2.通过record_id获取week_id，封装key(day,time)=value(week)
        Map<MapKey, List<Long>> mp = new HashMap<>();
        for (LabRecord record : recordList) {
            List<Long> weekIdList = recordWeekService.selectWeekList(record.getId());

            QueryWrapper<LabWeek> weekQueryWrapper = new QueryWrapper<>();
            weekQueryWrapper.in("id", weekIdList);
            weekQueryWrapper.eq("status", WeekStatusConstants.CLOSED);

            // 获取当前预约所有周次
            List<LabWeek> labWeekList = weekMapper.selectList(weekQueryWrapper);

            if (labWeekList.isEmpty()) {
                continue;
            }

            List<Long> weekList = new ArrayList<>();
            for (LabWeek week : labWeekList) {
                weekList.add(week.getWeek());
            }

            MapKey key = new MapKey(record.getDay(), record.getTime());

            // 若遇到相同预约，不同周次，将其添加到周次中
            if (!mp.containsKey(key)) {
                mp.put(key, weekList);
            } else {
                mp.get(key).addAll(weekList);
            }
        }

        // 3.双重遍历day和time，从HashMap取出weekList，然后取这个list的补集，再转化成String放到 LabTableVO
        List<LabTableVO> voList = new ArrayList<>();
        for (long day = 1; day <= Constants.DAY_SIZE; day++) {
            for (long time = 1; time <= Constants.TIME_SIZE; time++) {
                LabTableVO vo = new LabTableVO();

                List<Long> weekList = new ArrayList<>();
                MapKey key = new MapKey(day, time);
                if (mp.containsKey(key)) {
                    List<Long> tmpList = mp.get(key);
                    for (long i = 1; i <= Constants.WEEK_SIZE; i++) {
                        boolean f = false;
                        for (Long tmp : tmpList) {
                            if (i == tmp) {
                                f = true;
                                break;
                            }
                        }
                        if (f) {
                            weekList.add(i);
                        }
                    }
                }
                vo.setLabId(labId);
                vo.setDay(day);
                vo.setTime(time);
                vo.setWeekList(weekList);
                if (weekList.isEmpty()) {
                    vo.setWeek("无");
                } else {
                    vo.setWeek(convert(weekList) + " 已预约");
                }
                voList.add(vo);
            }
        }

        return voList;
    }

    @Override
    public int updateLabStatus(Lab lab) {
        return baseMapper.updateLab(lab);
    }

    /* 将week数组转化为String显示，连续的数字用'-'连接 */
    // [1,2,3,4,5,7]  --> [1-5,7]
    // [1,2,3,5,6,8,16] --> [1-3,5-6,8,16]
    // [2,4,6,8,10] --> [2,4,6,8,10]
    // [2,4,6,8,10,12] --> [1-12]双
    public String convert(List<Long> week) {

        Collections.sort(week);
        StringBuilder ans = new StringBuilder();
        if (week == null || week.isEmpty()) {
            return "";
        }

        int sz = week.size();
        if (sz >= 6) {
            boolean f = false;
            for (int i = 1; i < sz; i++) {
                if (week.get(i) - week.get(i - 1) != 2) {
                    f = true;// true表示不连续
                    break;
                }
            }
            if (!f) {
                Long s = week.get(0);
                Long e = week.get(sz - 1);
                if (s == 2) {
                    s--;
                }
                if (e == 15 || e == 17) {
                    e++;
                }
                ans.append("[").append(s);
                ans.append("-");
                ans.append(e).append("周]");
                if (week.get(0) % 2 == 0) {
                    ans.append("双");
                } else {
                    ans.append("单");
                }
                return ans.toString();
            }
        }

        int len = 1; // len表示连续的个数，要求>=2才处理
        int idx = 1; // 周次索引
        long s = 0; // 连续的起点

        ans.append("[");

        while (idx < week.size()) {
            if (week.get(idx) == week.get(idx - 1) + 1) { // 连续
                len++;
                if (len == 2) {
                    s = week.get(idx - 1); //len==2，开始连续，s记录起点
                }
            } else { //不连续
                if (len >= 2) {
                    ans.append(s);
                    ans.append("-");
                    ans.append(week.get(idx - 1));
                } else { //len < 2
                    ans.append(week.get(idx - 1));
                }
                ans.append(",");
                len = 1;
            }
            idx++;
        }

        //最后剩余的一个数字
        if (len >= 2) {
            ans.append(s).append("-");
        }
        ans.append(week.get(idx - 1)).append("周]");

        return ans.toString();
    }

    private String convert3day(List<Long> week) {

        Collections.sort(week);
        StringBuilder ans = new StringBuilder();
        if (week == null || week.isEmpty()) return "";

        int len = 1; //len表示连续的个数，要求>=3才处理
        int idx = 1;
        long s = 0; //连续的起点

        ans.append("[");

        while (idx < week.size()) {
            if (week.get(idx) == week.get(idx - 1) + 1) {
                len++;
                if (len == 3) {
                    s = week.get(idx - 2); //len==3，开始连续，s先记录一下起点
                }
            } else {
                if (len >= 3) {
                    ans.append(s);
                    ans.append("-");
                    ans.append(week.get(idx - 1));
                } else if (len == 2) {
                    ans.append(week.get(idx - 2));
                    ans.append(", ");
                    ans.append(week.get(idx - 1));
                } else {
                    ans.append(week.get(idx - 1));
                }
                ans.append(", ");
                len = 1;
            }
            idx++;
        }
        //最后处理一下
        if (len >= 3) {
            ans.append(s);
            ans.append("-");
        } else if (len == 2) {
            ans.append(week.get(idx - 2));
            ans.append(", ");
        }
        ans.append(week.get(idx - 1));
        ans.append("周]");

        return ans.toString();
    }

}
