package com.mosty.qwzx.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mosty.base.model.dto.rwzx.TbRwTaskDto;
import com.mosty.base.model.dto.rwzx.TbRwTaskUserDto;
import com.mosty.base.model.entity.qwzx.*;
import com.mosty.base.model.entity.rwzx.TbRwTask;
import com.mosty.base.model.query.rwzx.TbRwTaskByYwidQuery;
import com.mosty.base.model.vo.qwzx.TbQwZbpbZqMyVo;
import com.mosty.base.utils.Constant;
import com.mosty.base.utils.DateUtils;
import com.mosty.base.utils.Kit;
import com.mosty.base.utils.UUIDGenerator;
import com.mosty.base.model.vo.base.DeptInfoVo;
import com.mosty.common.base.exception.BusinessException;
import com.mosty.common.token.UserInfo;
import com.mosty.common.token.UserInfoManager;
import com.mosty.common.util.PermissionsUtil;
import com.mosty.base.model.dto.qwzx.TbQwZbpbInsertOrUpdateDto;
import com.mosty.base.model.dto.qwzx.TbQwZbpbZqDto;
import com.mosty.base.model.query.qwzx.TbQwZbpbQuery;
import com.mosty.base.model.query.qwzx.TbQwZbpbSearchMyQuery;
import com.mosty.qwzx.mapper.*;
import com.mosty.qwzx.remote.TbBaseAdaptRemoteService;
import com.mosty.qwzx.remote.TbRwzxAdaptRemoteService;
import com.mosty.qwzx.service.TbQwZbpbService;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

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

/**
 * @author dw
 * @since 2022/8/3
 **/
@Service
@AllArgsConstructor
public class TbQwZbpbServiceImpl extends ServiceImpl<TbQwZbpbMapper, TbQwZbpb> implements TbQwZbpbService {

    private final TbBaseAdaptRemoteService tbBaseAdaptRemoteService;
    private final TbQwZbpbZqMapper tbQwZbpbZqMapper;
    private final TbQwJlMapper tbQwJlMapper;
    private final TbQwZbpbMrjlMapper tbQwZbpbMrjlMapper;
    private final TbQwJjrMapper tbQwJjrMapper;
    private final TbQwZbbbMapper tbQwzbbbMapper;
    private final TbRwzxAdaptRemoteService tbRwzxAdaptRemoteService;
    private final TbQwQxjMapper tbQwQxjMapper;

    @Override
    @Transactional
    public Integer addEntity(TbQwZbpbInsertOrUpdateDto dto) {
        String year = DateUtils.getQueryDateString(new Date(), "13");
        if (!DateUtils.getQueryDateString(dto.getZbpbksrq(), "13").equals(year) || (
                dto.getZbpbjsrq() != null && !DateUtils.getQueryDateString(dto.getZbpbjsrq(), "13").equals(year)
        )) {
            throw new BusinessException("排班开始日期和结束日期必须为本年度！！");
        }
        TbQwZbpb pb = new TbQwZbpb();
        BeanUtils.copyProperties(dto, pb);
        UserInfo user = UserInfoManager.get();
        pb.setId(UUIDGenerator.getUUID());
        pb.setPbrid(String.valueOf(user.getUserId()));
        pb.setPbr(user.getUserName());
        pb.setPbrsfzh(user.getIdEntityCard());
        if ("0".equals(pb.getJsrqlx())) {
            try {
                pb.setZbpbjsrq(new SimpleDateFormat("yyyy-MM-dd").parse("2099-12-31"));
            } catch (ParseException e) {
                e.printStackTrace();
                throw new BusinessException("时间格式转换异常！！");
            }
        }
        if (StringUtils.isBlank(pb.getSsbmid())) throw new BusinessException("请选择值班部门！");
        DeptInfoVo dept = this.tbBaseAdaptRemoteService.getOrgByDeptId(pb.getSsbmid());
        if (dept != null) {
            pb.setSsbm(dept.getDeptname());
            pb.setSsbmid(dept.getDeptid());
            pb.setSsbmdm(dept.getDeptcode());
            pb.setSsxgajdm(dept.getFxjcode());
            pb.setSsxgajid(dept.getFxjid());
            pb.setSsxgaj(dept.getFxjname());
            pb.setSssgaj(dept.getDszname());
            pb.setSssgajdm(dept.getDszcode());
            pb.setSssgajid(dept.getDszid());
        }
        pb.setXtSjly("1");
        // 保存周期表信息和警力信息
        this.setZbpbzq(dto, pb, dept, null);
        return this.baseMapper.insert(pb);
    }

    // 判断是否有时间重合、任务重合的情况，如果存在，则提示给前端
    private void checkZbxx(TbQwZbpbInsertOrUpdateDto dto) {
        // 查询所有的人员，根据人员查询该时间段是否有排班信息
        List<TbQwZbpbZqDto> zqList = dto.getPbzqList();
        if (zqList == null || zqList.size() == 0) {
            throw new BusinessException("请配置周期信息");
        }
        for (int i = 0; i < zqList.size(); i++) {
            TbQwZbpbZqDto zq = zqList.get(i);
            this.checkUserZb(zq, dto, zq.getZbldId(), "01", zq.getZbldXm());
            this.checkUserZb(zq, dto, zq.getZbzhzId(), "01", zq.getZbzhzXm());
            this.checkUserZb(zq, dto, zq.getZzzhzId(), "01", zq.getZzzhzXm());
            this.checkUserZb(zq, dto, zq.getFzzbId(), "01", zq.getFzzbXm());
            List<TbQwJl> jlList = zq.getJlList();
            if (jlList == null || jlList.size() == 0) {
                throw new BusinessException("请配置第" + (i + 1) + "班的警力信息");
            }
            jlList.forEach(jl -> this.checkUserZb(zq, dto, jl.getJlId(), jl.getJllx(), jl.getJlxm()));
        }
    }

    // 检查用户信息是否重合
    private void checkUserZb(TbQwZbpbZqDto zq, TbQwZbpbInsertOrUpdateDto dto, String jlId,
                             String jlLx, String jlxm) {
        // 查询重合的排班信息
        String kssj = DateUtils.getQueryDateString(zq.getKssj(), "02");
        String jssj = "";
        if (zq.getKssj().getTime() > zq.getJssj().getTime()) {
            jssj = "1970-01-02" + " " + DateUtils.getQueryDateString(zq.getJssj(), "10");
        }
        List<TbQwZbpb> pbTempList = this.baseMapper.getZbBySjAndJl
                (DateUtils.getQueryDateString(dto.getZbpbksrq(), "01"),
                        DateUtils.getQueryDateString(dto.getZbpbjsrq(), "01"),
                        jlId, kssj, jssj, dto.getId());
        pbTempList.forEach(pbTemp -> {
            throw new BusinessException(("01".equals(jlLx) ? "民警" : "辅警") + "(" + jlxm + ")在" +
                    "其他排班中时间冲突，冲突排班名称：" + pbTemp.getZbmc());
        });
    }

    @Override
    @Transactional
    public Integer updateEntity(TbQwZbpbInsertOrUpdateDto dto) {
        // 判断是否有时间重合、任务重合的情况，如果存在，则提示给前端
        // this.checkZbxx(dto);
        String year = DateUtils.getQueryDateString(new Date(), "13");
        if (!DateUtils.getQueryDateString(dto.getZbpbksrq(), "13").equals(year)
                || (dto.getZbpbjsrq() != null && !DateUtils.getQueryDateString(dto.getZbpbjsrq(), "13")
                .equals(year)
        )) {
            throw new BusinessException("排班开始日期和结束日期必须为本年度！！");
        }
        TbQwZbpb pb = new TbQwZbpb();
        BeanUtils.copyProperties(dto, pb);
        if ("0".equals(pb.getJsrqlx())) {
            try {
                pb.setZbpbjsrq(new SimpleDateFormat("yyyy-MM-dd").parse("2099-12-31"));
            } catch (ParseException e) {
                e.printStackTrace();
                throw new BusinessException("时间格式转换异常！！");
            }
        }
        if (StringUtils.isBlank(pb.getSsbmid())) throw new BusinessException("请选择值班部门！");
        DeptInfoVo dept = this.tbBaseAdaptRemoteService.getOrgByDeptId(pb.getSsbmid());
        if (dept != null) {
            pb.setSsbm(dept.getDeptname());
            pb.setSsbmid(dept.getDeptid());
            pb.setSsbmdm(dept.getDeptcode());
            pb.setSsxgajdm(dept.getFxjcode());
            pb.setSsxgajid(dept.getFxjid());
            pb.setSsxgaj(dept.getFxjname());
            pb.setSssgaj(dept.getDszname());
            pb.setSssgajdm(dept.getDszcode());
            pb.setSssgajid(dept.getDszid());
        }
        // 删除排班表的数据
        this.deleteZbpb(pb.getId());
        // 添加排班表数据
        this.setZbpbzq(dto, pb, dept, dto.getId());
        return this.baseMapper.updateById(pb);
    }

    @Override
    @Transactional
    public void deleteBatch(List<String> ids) {
        if (ids.size() > 0) {
            ids.forEach(id -> {
                // 删除值班排班周期和警力信息
                this.deleteZbpb(id);
                // 删除排班信息
                this.baseMapper.deleteById(id);
            });
        }
    }

    @Override
    @Transactional
    public void deleteEntity(String id) {
        // 删除值班排班周期和警力信息
        this.deleteZbpb(id);
        // 删除排班信息
        this.baseMapper.deleteById(id);
    }

    @Override
    public IPage<TbQwZbpbInsertOrUpdateDto> selectPage(TbQwZbpbQuery dto) {
        QueryWrapper<TbQwZbpb> qw = new QueryWrapper<>();
//        UserInfo userInfo = UserInfoManager.get();
//        PermissionsUtil.queryWrapperUtil(qw, userInfo);
        dto.setSsbmdm(this.tbBaseAdaptRemoteService.getSsbm(dto.getSsbmdm(), null));
        qw.lambda().eq(StringUtils.isNotBlank(dto.getJsrqlx()), TbQwZbpb::getJsrqlx, dto.getJsrqlx())
                .eq(dto.getXhzq() != null, TbQwZbpb::getXhzq, dto.getXhzq())
                .eq(StringUtils.isNotBlank(dto.getXhlx()), TbQwZbpb::getXhlx, dto.getXhlx())
                .eq(dto.getMrbc() != null, TbQwZbpb::getMrbc, dto.getMrbc())
                .likeRight(StringUtils.isNotBlank(dto.getSsbmdm()), TbQwZbpb::getSsbmdm, dto.getSsbmdm())
                .like(StringUtils.isNotBlank(dto.getZbmc()), TbQwZbpb::getZbmc, dto.getZbmc())
                .like(StringUtils.isNotBlank(dto.getZbms()), TbQwZbpb::getZbms, dto.getZbms());
        if (dto.getZbpbksrq() != null && dto.getZbpbjsrq() != null) {
            qw.lambda().and(
                    it -> it.between(TbQwZbpb::getZbpbksrq, dto.getZbpbksrq(), dto.getZbpbjsrq()).or()
                            .between(TbQwZbpb::getZbpbjsrq, dto.getZbpbksrq(), dto.getZbpbjsrq())
            );
        }
        IPage<TbQwZbpb> page = new Page<>(dto.getPageCurrent(), dto.getPageSize());
        page = this.baseMapper.selectPage(page, qw);
        IPage<TbQwZbpbInsertOrUpdateDto> rPage = new Page<>(dto.getPageCurrent(), dto.getPageSize());
        List<TbQwZbpb> list = page.getRecords();
        List<TbQwZbpbInsertOrUpdateDto> rList = new ArrayList<>();
        list.forEach(item -> {
            TbQwZbpbInsertOrUpdateDto entity = new TbQwZbpbInsertOrUpdateDto();
            BeanUtils.copyProperties(item, entity);
            // 查询排班周期
            List<TbQwZbpbZq> zqList = this.tbQwZbpbZqMapper.selectList(
                    new LambdaQueryWrapper<TbQwZbpbZq>().eq(TbQwZbpbZq::getPbId, item.getId())
            );
            List<TbQwZbpbZqDto> zqDtoList = new ArrayList<>();
            zqList.forEach(zqItem -> {
                TbQwZbpbZqDto zqDto = new TbQwZbpbZqDto();
                BeanUtils.copyProperties(zqItem, zqDto);
                // 查询警力列表
                List<TbQwJl> jlList = this.tbQwJlMapper.selectList(
                        new LambdaQueryWrapper<TbQwJl>().eq(TbQwJl::getYwid, zqDto.getId())
                );
                zqDto.setJlList(jlList);
                zqDtoList.add(zqDto);
            });
            entity.setPbzqList(zqDtoList);
            rList.add(entity);
        });
        rPage.setRecords(rList);
        rPage.setTotal(page.getTotal());
        return rPage;
    }

    @Override
    public TbQwZbpbInsertOrUpdateDto getInfo(String id) {
        TbQwZbpb item = this.baseMapper.selectById(id);
        if (item != null) {
            TbQwZbpbInsertOrUpdateDto entity = new TbQwZbpbInsertOrUpdateDto();
            BeanUtils.copyProperties(item, entity);
            // 查询排班周期
            List<TbQwZbpbZq> zqList = this.tbQwZbpbZqMapper.selectList(
                    new LambdaQueryWrapper<TbQwZbpbZq>().eq(TbQwZbpbZq::getPbId, item.getId())
            );
            List<TbQwZbpbZqDto> zqDtoList = new ArrayList<>();
            zqList.forEach(zqItem -> {
                TbQwZbpbZqDto zqDto = new TbQwZbpbZqDto();
                BeanUtils.copyProperties(zqItem, zqDto);
                // 查询警力列表
                List<TbQwJl> jlList = this.tbQwJlMapper.selectList(
                        new LambdaQueryWrapper<TbQwJl>().eq(TbQwJl::getYwid, zqDto.getId())
                );
                zqDto.setJlList(jlList);
                zqDtoList.add(zqDto);
            });
            entity.setPbzqList(zqDtoList);
            return entity;
        }
        return null;
    }

    @Override
    public IPage<TbQwZbpbInsertOrUpdateDto> getMyZbpb(TbQwZbpbSearchMyQuery dto) {
        IPage<TbQwZbpbInsertOrUpdateDto> page = new Page<>(dto.getPageCurrent(), dto.getPageSize());
        Map<String, Object> map = new HashMap<>();
        UserInfo userInfo = UserInfoManager.get();
        map.put("dto", dto);
        map.put("pageIndex", (dto.getPageCurrent() - 1) * dto.getPageSize());
        map.put("pageSize", dto.getPageSize());
        map.put("ryid", String.valueOf(userInfo.getUserId()));
        int count = this.baseMapper.getCount(map);
        List<TbQwZbpb> list = this.baseMapper.getList(map);
        List<TbQwZbpbInsertOrUpdateDto> rList = new ArrayList<>();
        list.forEach(item -> {
            TbQwZbpbInsertOrUpdateDto entity = new TbQwZbpbInsertOrUpdateDto();
            BeanUtils.copyProperties(item, entity);
            // 查询排班周期
            List<TbQwZbpbZq> zqList = this.tbQwZbpbZqMapper.selectList(
                    new LambdaQueryWrapper<TbQwZbpbZq>().eq(TbQwZbpbZq::getPbId, item.getId())
            );
            List<TbQwZbpbZqDto> zqDtoList = new ArrayList<>();
            zqList.forEach(zqItem -> {
                TbQwZbpbZqDto zqDto = new TbQwZbpbZqDto();
                BeanUtils.copyProperties(zqItem, zqDto);
                // 查询警力列表
                List<TbQwJl> jlList = this.tbQwJlMapper.selectList(
                        new LambdaQueryWrapper<TbQwJl>().eq(TbQwJl::getYwid, zqDto.getId())
                );
                zqDto.setJlList(jlList);
                zqDtoList.add(zqDto);
            });
            entity.setPbzqList(zqDtoList);
            rList.add(entity);
        });
        page.setTotal(count);
        page.setRecords(rList);
        return page;
    }

    @Override
    public void checkThisTimeZbpb() {
        List<TbQwZbpbMrjl> list = this.baseMapper.checkThisTimeZbpb();
        TbRwTaskDto task = new TbRwTaskDto();
        List<TbRwTaskUserDto> userDtoList = new ArrayList<>();
        if (list.size() > 0) {
            list.forEach(item -> {
                // 查询是否发送消息，如果发送则无需发送了
                TbRwTaskByYwidQuery query = new TbRwTaskByYwidQuery();
                query.setYwid(item.getId());
                query.setRwxl("04");
                TbRwTask temp = this.tbRwzxAdaptRemoteService.getRwByYwid(query);
                if (temp == null) {
                    // 判断本次排班是否报备,如果没有报备就不需要提醒了
                    int count = this.tbQwzbbbMapper.selectCount(
                            new LambdaQueryWrapper<TbQwZbbb>()
                                    .eq(TbQwZbbb::getZbpbId, item.getPbId())
                                    .eq(TbQwZbbb::getBbzt, "0")
                                    .eq(TbQwZbbb::getZbrq, new Date())
                    );
                    TbQwZbpbZq zq = this.tbQwZbpbZqMapper.selectById(item.getPbzqId());
                    if (count == 0) {
                        // 需要发出提醒
                        // 值班领导
                        if (StringUtils.isNotBlank(zq.getZbldId())) {
                            this.addZbld(zq, userDtoList);
                        }
                        // 值班指挥长
                        if (StringUtils.isNotBlank(zq.getZbzhzId())) {
                            this.addZbzhz(zq, userDtoList);
                        }
                        // 专职指挥长
                        if (StringUtils.isNotBlank(zq.getZzzhzId())) {
                            this.addZzzhz(zq, userDtoList);
                        }
                        // 法制值班
                        if (StringUtils.isNotBlank(zq.getFzzbId())) {
                            this.addFzzb(zq, userDtoList);
                        }
                        List<TbQwJl> jlList = this.tbQwJlMapper.selectList(
                                new LambdaQueryWrapper<TbQwJl>()
                                        .eq(TbQwJl::getYwid, item.getPbzqId())
                                        .eq(TbQwJl::getJllx, "01")
                        );
                        if (!CollectionUtils.isEmpty(jlList)) {
                            jlList.forEach(jl -> {
                                TbRwTaskUserDto itemDtos = new TbRwTaskUserDto();
                                itemDtos.setRwzflx("1");
                                itemDtos.setJsrid(jl.getJlId());
                                itemDtos.setJsrmc(jl.getJlxm());
                                itemDtos.setJsrsfzh(jl.getSfzh());
                                itemDtos.setJsrlxdh(jl.getLxdh());
                                DeptInfoVo deptVo = this.tbBaseAdaptRemoteService.getDeptInfoByUserId(jl.getJlId());
                                if (deptVo != null) {
                                    itemDtos.setSsbm(deptVo.getDeptname());
                                    itemDtos.setSsbmid(deptVo.getDeptid());
                                }
                                // 判断重复数据
                                List<TbRwTaskUserDto> tempList = userDtoList.stream().filter(t -> t.getJsrid().equals(jl.getJlId())).collect(Collectors.toList());
                                if (tempList.size() == 0) {
                                    userDtoList.add(itemDtos);
                                }
                            });
                        }
                    }
                    if (userDtoList.size() > 0) {
                        task.setSsbmid(zq.getSsbmid());
                        task.setSsbmdm(zq.getSsbmdm());
                        task.setRwmc("值班报备提醒");
                        task.setRwnr("根据值班排班安排，请您于" + new SimpleDateFormat("HH:mm").format(zq.getKssj()) + "前，" +
                                "进行值班报备！！");
                        task.setRwjsdx("01");
                        task.setRwlx("2");
                        task.setRwxl("04");
                        task.setRwjjcd("3");
                        task.setSfaqwc("1");
                        task.setRwms("1");
                        task.setCjrid("-1");
                        task.setCjrxm("系统");
                        Date sj;
                        // 跨天
                        if (zq.getJssj().getTime() <= zq.getKssj().getTime()) {
                            sj = DateUtils.getNextDate(
                                    DateUtils.strToDate(
                                            DateUtils.getQueryDateString(
                                                    DateUtils.getNextDate(new Date(), "D", +1), "01") + " " +
                                                    DateUtils.getQueryDateString(zq.getJssj(), "10"), "02"
                                    ), "H", +2
                            );
                        } else {
                            sj = DateUtils.getNextDate(
                                    DateUtils.strToDate(
                                            DateUtils.getQueryDateString(new Date(), "01") + " " +
                                                    DateUtils.getQueryDateString(zq.getJssj(), "10"), "02"
                                    ), "H", +2
                            );
                        }
                        task.setRwyqwcsj(sj);
                        task.setCjrlxdh("");
                        task.setYwid(item.getId());
                        task.setUserDtoList(userDtoList);
                        this.tbRwzxAdaptRemoteService.addRw(task);
                    }
                }
            });
        }
    }

    @Override
    public TbQwZbpbZqMyVo getMyZbpbToday() {
        UserInfo user = UserInfoManager.get();
        return this.tbQwZbpbZqMapper.getMyZbpbToday(String.valueOf(user.getUserId()));
    }

    @Override
    public TbQwZbpbZqDto getZbpbZqInfo(String id) {
        TbQwZbpbZq zqItem = this.tbQwZbpbZqMapper.selectById(id);
        if (zqItem == null) {
            return null;
        }
        TbQwZbpbZqDto zqDto = new TbQwZbpbZqDto();
        BeanUtils.copyProperties(zqItem, zqDto);
        List<TbQwJl> jlList = this.tbQwJlMapper.selectList(
                new LambdaQueryWrapper<TbQwJl>()
                        .eq(TbQwJl::getYwid, zqDto.getId())
        );
        zqDto.setJlList(jlList);
        return zqDto;
    }

    @Override
    public void addMrjl() {
        // 查询值班排班信息
        List<TbQwZbpb> pbList = this.baseMapper.selectList(
                new LambdaQueryWrapper<TbQwZbpb>()
                        .eq(TbQwZbpb::getXtSjzt, "1")
                        .eq(TbQwZbpb::getJsrqlx, "0")
        );
        if (!CollectionUtils.isEmpty(pbList)) {
            pbList.forEach(zb -> {
                List<TbQwZbpbZq> zqList = this.tbQwZbpbZqMapper.selectList(
                        new LambdaQueryWrapper<TbQwZbpbZq>()
                                .eq(TbQwZbpbZq::getPbId, zb.getId())
                                .eq(TbQwZbpbZq::getXtSjzt, "1")
                );
                zqList.forEach(zq -> {
                    // 获取本年的第一天
                    Date firstDay = DateUtils.strToDate(DateUtils.getQueryDateString(new Date(), "13") + "-01-01", "01");
                    zb.setZbpbksrq(firstDay);
                    // 获取本年最后一天的数据
                    Date lastDay = DateUtils.strToDate(DateUtils.getQueryDateString(new Date(), "13") + "-12-31", "01");
                    if (lastDay.getTime() >= zb.getZbpbjsrq().getTime()) {
                        lastDay = zb.getZbpbjsrq();
                    }
                    zb.setZbpbjsrq(lastDay);
                    this.setZbpbMrjlOther(zb, zq);
                });
            });
        }
    }

    @Override
    public List<Map<String, Object>> exportData(String time, String pbid) {
        List<TbQwZbpbMrjl> list = this.tbQwZbpbMrjlMapper.selectList(
                new LambdaQueryWrapper<TbQwZbpbMrjl>()
                        .isNotNull(TbQwZbpbMrjl::getId)
                        .eq(TbQwZbpbMrjl::getPbId, pbid)
                        .last(" and date_format(zbrq,'%Y-%m') = '" + time + "' order by zbrq")
        );
        List<Map<String, Object>> rList = new ArrayList<>();
        list.forEach(item -> {
            TbQwZbpbZq zq = this.tbQwZbpbZqMapper.selectById(item.getPbzqId());
            if (zq != null) {
                Map<String, Object> map = new HashMap<>();
                map.put("time", DateUtils.getQueryDateString(item.getZbrq(), "01"));
                map.put("zbldXm", zq.getZbldXm());
                map.put("zbzhzXm", zq.getZbzhzXm());
                map.put("zzzhzXm", zq.getZzzhzXm());
                map.put("fzzbXm", zq.getFzzbXm());
                map.put("zbmj", zq.getZbmj());
                map.put("zbfj", zq.getZbfj());
                rList.add(map);
            }
        });
        return rList;
    }

    @Override
    public List<Map<String, Object>> getDeptByMonth(String time) {
        UserInfo user = UserInfoManager.get();
        String ssbmid = String.valueOf(user.getDeptId());
        List<Map<String, Object>> rList = new ArrayList<>();
        Date kssj = DateUtils.strToDate(time + "-01", "01");
        Date jssj = DateUtils.getThisMonthLastDay(time);
        while (kssj.getTime() <= jssj.getTime()) {
            // 查询排班情况
            Date now = DateUtils.strToDate(DateUtils.getQueryDateString(new Date(), "01"), "01");
            Map<String, Object> map = new HashMap<>();
            map.put("time", DateUtils.getQueryDateString(kssj, "01"));
            // 过去,有值班展示值班信息，没有就不展示
            if (now.getTime() > kssj.getTime()) {
                List<TbQwZbbb> bbList = this.tbQwzbbbMapper.selectList(
                        new LambdaQueryWrapper<TbQwZbbb>()
                                .eq(TbQwZbbb::getZbrq, kssj)
                                .eq(TbQwZbbb::getXtSjzt, "1")
                                .eq(TbQwZbbb::getSsbmid, ssbmid)
                );
                if (bbList != null && bbList.size() != 0) {
                    map.put("type", "01");
                    map.put("list", bbList);
                } else {
                    map.put("type", "00");
                }
                // 当天，有报备展示报备，没有报备展示排班
            } else if (now.getTime() == kssj.getTime()) {
                List<TbQwZbbb> bbList = this.tbQwzbbbMapper.selectList(
                        new LambdaQueryWrapper<TbQwZbbb>()
                                .eq(TbQwZbbb::getZbrq, kssj)
                                .eq(TbQwZbbb::getXtSjzt, "1")
                                .eq(TbQwZbbb::getSsbmid, ssbmid)
                );
                if (bbList != null && bbList.size() != 0) {
                    map.put("type", "02");
                    map.put("list", bbList);
                } else {
                    List<TbQwZbpbZq> zqList = this.tbQwZbpbZqMapper.getDeptByMonth(kssj, ssbmid);
                    if (zqList != null && zqList.size() > 0) {
                        map.put("type", "03");
                        map.put("list", zqList);
                    } else {
                        map.put("type", "04");
                    }
                }
            } else {
                List<TbQwZbpbZq> zqList = this.tbQwZbpbZqMapper.getDeptByMonth(kssj, ssbmid);
                if (zqList != null && zqList.size() > 0) {
                    map.put("type", "05");
                    map.put("list", zqList);
                } else {
                    map.put("type", "06");
                }
            }
            rList.add(map);
            kssj = DateUtils.getNextDate(kssj, "D", +1);
        }
        return rList;
    }

    @Override
    public List<Map<String, Object>> getZbbbByMonth(String time) {
        UserInfo user = UserInfoManager.get();
        String userId = String.valueOf(user.getUserId());
        List<Map<String, Object>> rList = new ArrayList<>();
        Date kssj = DateUtils.strToDate(time + "-01", "01");
        Date jssj = DateUtils.getThisMonthLastDay(time);
        while (kssj.getTime() <= jssj.getTime()) {
            // 查询排班情况
            List<TbQwZbpbZq> zqList = this.tbQwZbpbZqMapper.getMyZbpbByTime(kssj, userId);
            Map<String, Object> map = new HashMap<>();
            map.put("day", DateUtils.getQueryDateString(kssj, "12"));
            List<Map<String, Object>> dayList = new ArrayList<>();
            if (!CollectionUtils.isEmpty(zqList)) {
                Date finalKssj = kssj;
                List<Map<String, Object>> finalDayList = dayList;
                zqList.forEach(zq -> {
                    Map<String, Object> dayMap = new HashMap<>();
                    dayMap.put("zt", "01");
                    dayMap.put("time", DateUtils.getQueryDateString(zq.getKssj(), "09") + "-"
                            + DateUtils.getQueryDateString(zq.getJssj(), "09"));
                    dayMap.put("id", zq.getId());
                    // 查询是否报备，如果报备，则覆盖排班信息，改为报备信息
                    TbQwZbbb zbbb = this.tbQwzbbbMapper.selectOne(
                            new LambdaQueryWrapper<TbQwZbbb>()
                                    .eq(TbQwZbbb::getZbpbId, zq.getId())
                                    .eq(TbQwZbbb::getZbrq, finalKssj)
                                    .orderByDesc(TbQwZbbb::getXtCjsj)
                                    .last(" limit 1")
                    );
                    if (zbbb != null) {
                        if ("0".equals(zbbb.getBbzt())) {
                            dayMap.put("zt", "02");
                            dayMap.put("time", DateUtils.getQueryDateString(zbbb.getBbkssj(), "09") + "-当前");
                            dayMap.put("id", zbbb.getId());
                        } else if ("1".equals(zbbb.getBbzt())) {
                            dayMap.put("zt", "03");
                            dayMap.put("time", DateUtils.getQueryDateString(zbbb.getBbkssj(), "09") + "-" +
                                    DateUtils.getQueryDateString(zbbb.getBbjssj(), "09"));
                            dayMap.put("id", zbbb.getId());
                        }
                    }
                    finalDayList.add(dayMap);
                });
            }
            // 查询其他的报备信息
            List<TbQwZbbb> bbList = this.tbQwzbbbMapper.getMybbTodayByTime(String.valueOf(user.getUserId()),
                    DateUtils.getQueryDateString(kssj, "01"));
            for (TbQwZbbb item : bbList) {
                Map<String, Object> dayMap = new HashMap<>();
                dayMap.put("zt", "0".equals(item.getBbzt()) ? "02" : "03");
                dayMap.put("time", DateUtils.getQueryDateString(item.getKssj(), "09") + "-"
                        + DateUtils.getQueryDateString(item.getJssj(), "09"));
                dayMap.put("id", item.getId());
                dayList.add(dayMap);
            }
            // 查询请休假信息
            TbQwQxj qxj = this.tbQwQxjMapper.selectOne(
                    new LambdaQueryWrapper<TbQwQxj>()
                            .eq(TbQwQxj::getSqrId, userId)
                            .le(TbQwQxj::getKssj, kssj)
                            .ge(TbQwQxj::getJssj, kssj)
                            .last(" limit 1")
            );
            if (qxj != null) {
                Map<String, Object> dayMap = new HashMap<>();
                dayMap.put("zt", "04");
                dayMap.put("time", "00:00-23:59");
                dayList = new ArrayList<>();
                dayList.add(dayMap);
            }
            map.put("list", dayList);
            rList.add(map);
            kssj = DateUtils.getNextDate(kssj, "D", +1);
        }
        return rList;
    }

    // 保存时间段累的所有的警力的数据
    private void setZbpbMrjlOther(TbQwZbpb zb, TbQwZbpbZq zq) {
        Date kssj = DateUtils.getNextDate(zb.getZbpbksrq(), "D", zq.getZbzq() - 1);
        Date jssj = zb.getZbpbjsrq();
        int a = -1;
        while (kssj.getTime() <= jssj.getTime()) {
            a++;
            if (a % zb.getXhzq() != 0) {
                kssj = DateUtils.getNextDate(kssj, "D", +1);
                continue;
            }
            if ("1".equals(zb.getXhlx())) {
                // 排除今天是休息日的情况，则需要查询今天是否是休息日
                boolean flag = this.checkXxr(kssj);
                if (flag) {
                    kssj = DateUtils.getNextDate(kssj, "D", +1);
                    continue;
                }
            } else if ("2".equals(zb.getXhlx())) {
                // 排除今天是工作日的情况，则需要查询今天是否是工作日
                boolean flag = this.checkXxr(kssj);
                if (!flag) {
                    kssj = DateUtils.getNextDate(kssj, "D", +1);
                    continue;
                }
            }
            TbQwZbpbMrjl mrjl = new TbQwZbpbMrjl();
            mrjl.setPbId(zb.getId());
            mrjl.setPbzqId(zq.getId());
            String zbksskTime = DateUtils.getQueryDateString(kssj, "01") + " "
                    + DateUtils.getQueryDateString(zq.getKssj(), "10");
            mrjl.setZbkssj(DateUtils.strToDate(zbksskTime, "02"));
            // 判断排班的开始时间是否大于排班的结束时间，如果大于 那么巡防的结束时间需要加一天
            if (zq.getKssj().getTime() > zq.getJssj().getTime()) {
                Date tempTime = DateUtils.getNextDate(kssj, "D", +1);
                String xfjsskTime = DateUtils.getQueryDateString(tempTime, "01") + " "
                        + DateUtils.getQueryDateString(zq.getJssj(), "10");
                mrjl.setZbjssj(DateUtils.strToDate(xfjsskTime, "02"));
            } else {
                String xfjsskTime = DateUtils.getQueryDateString(kssj, "01") + " "
                        + DateUtils.getQueryDateString(zq.getJssj(), "10");
                mrjl.setZbjssj(DateUtils.strToDate(xfjsskTime, "02"));
            }
            mrjl.setZbrq(kssj);
            this.tbQwZbpbMrjlMapper.insert(mrjl);
            kssj = DateUtils.getNextDate(kssj, "D", +1);
        }
    }

    // 发送给法制值班
    private void addFzzb(TbQwZbpbZq zq, List<TbRwTaskUserDto> userDtoList) {
        TbRwTaskUserDto itemDto = new TbRwTaskUserDto();
        itemDto.setRwzflx("1");
        itemDto.setJsrid(zq.getFzzbId());
        itemDto.setJsrmc(zq.getFzzbXm());
        itemDto.setJsrsfzh(zq.getFzzbSfzh());
        DeptInfoVo dept = this.tbBaseAdaptRemoteService.getDeptInfoByUserId(zq.getFzzbId());
        if (dept != null) {
            itemDto.setSsbm(dept.getDeptname());
            itemDto.setSsbmid(dept.getDeptid());
        }
        userDtoList.add(itemDto);
    }

    // 发送给专职指挥长
    private void addZzzhz(TbQwZbpbZq zq, List<TbRwTaskUserDto> userDtoList) {
        TbRwTaskUserDto itemDto = new TbRwTaskUserDto();
        itemDto.setRwzflx("1");
        itemDto.setJsrid(zq.getZzzhzId());
        itemDto.setJsrmc(zq.getZzzhzXm());
        itemDto.setJsrsfzh(zq.getZzzhzSfzh());
        DeptInfoVo dept = this.tbBaseAdaptRemoteService.getDeptInfoByUserId(zq.getZzzhzId());
        if (dept != null) {
            itemDto.setSsbm(dept.getDeptname());
            itemDto.setSsbmid(dept.getDeptid());
        }
        userDtoList.add(itemDto);
    }

    // 发送给值班指挥长
    private void addZbzhz(TbQwZbpbZq zq, List<TbRwTaskUserDto> userDtoList) {
        TbRwTaskUserDto itemDto = new TbRwTaskUserDto();
        itemDto.setRwzflx("1");
        itemDto.setJsrid(zq.getZbzhzId());
        itemDto.setJsrmc(zq.getZbzhzXm());
        itemDto.setJsrsfzh(zq.getZbzhzSfzh());
        DeptInfoVo dept = this.tbBaseAdaptRemoteService.getDeptInfoByUserId(zq.getZbzhzId());
        if (dept != null) {
            itemDto.setSsbm(dept.getDeptname());
            itemDto.setSsbmid(dept.getDeptid());
        }
        userDtoList.add(itemDto);
    }

    // 发送给值班领导
    private void addZbld(TbQwZbpbZq zq, List<TbRwTaskUserDto> userDtoList) {
        TbRwTaskUserDto itemDto = new TbRwTaskUserDto();
        itemDto.setRwzflx("1");
        itemDto.setJsrid(zq.getZbldId());
        itemDto.setJsrmc(zq.getZbldXm());
        itemDto.setJsrsfzh(zq.getZbldSfzh());
        DeptInfoVo dept = this.tbBaseAdaptRemoteService.getDeptInfoByUserId(zq.getZbldId());
        if (dept != null) {
            itemDto.setSsbm(dept.getDeptname());
            itemDto.setSsbmid(dept.getDeptid());
        }
        userDtoList.add(itemDto);
    }

    // 删除值班报备数据
    public void deleteZbpb(String id) {
        List<TbQwZbpbZq> zqList = this.tbQwZbpbZqMapper.selectList(
                new LambdaQueryWrapper<TbQwZbpbZq>()
                        .eq(TbQwZbpbZq::getPbId, id)
        );
        if (!CollectionUtils.isEmpty(zqList)) {
            zqList.forEach(zq -> {
                // 删除警力信息
                this.tbQwJlMapper.deleteByYwid(zq.getId());
                // 删除每日警力数据
                this.tbQwZbpbMrjlMapper.deleteByYwid(id, zq.getId());
            });
        }
        this.tbQwZbpbZqMapper.deleteByPbId(id);
    }

    //保存值班排班周期表数据
    public void setZbpbzq(TbQwZbpbInsertOrUpdateDto dto, TbQwZbpb pb, DeptInfoVo dept, String pbid) {
        List<TbQwZbpbZqDto> list = dto.getPbzqList();
        if (!CollectionUtils.isEmpty(list)) {
            for (TbQwZbpbZqDto item : list) {
                TbQwZbpbZq zq = new TbQwZbpbZq();
                BeanUtils.copyProperties(item, zq);
                zq.setPbId(pb.getId());
                zq.setId(UUIDGenerator.getUUID());
                List<TbQwJl> jlList = item.getJlList();
                List<TbQwJl> mjList = new ArrayList<>(), fjList = new ArrayList<>();
                if (!CollectionUtils.isEmpty(jlList)) {
                    for (TbQwJl jl : jlList) {
                        if ("01".equals(jl.getJllx())) {
                            mjList.add(jl);
                        } else if ("02".equals(jl.getJllx())) {
                            fjList.add(jl);
                        }
                        // 保存警力信息
                        jl.setId(UUIDGenerator.getUUID());
                        jl.setYwid(zq.getId());
                        jl.setZblx("1");
                        jl.setJlzt("1");
                        jl.setXtSjly("1");
                        if (dept != null) {
                            jl.setSsbm(dept.getDeptname());
                            jl.setSsbmid(dept.getDeptid());
                            jl.setSsbmdm(dept.getDeptcode());
                            jl.setSsxgajdm(dept.getFxjcode());
                            jl.setSsxgajid(dept.getFxjid());
                            jl.setSsxgaj(dept.getFxjname());
                            jl.setSssgaj(dept.getDszname());
                            jl.setSssgajdm(dept.getDszcode());
                            jl.setSssgajid(dept.getDszid());
                        }
                        this.tbQwJlMapper.insert(jl);
                    }
                }
                zq.setMjsl(mjList.size());
                zq.setFjsl(fjList.size());
                zq.setZbmj(JSONArray.toJSONString(mjList));
                zq.setZbfj(JSONArray.toJSONString(fjList));
                zq.setBcs(item.getBcs());
                if (dept != null) {
                    zq.setSsbm(dept.getDeptname());
                    zq.setSsbmid(dept.getDeptid());
                    zq.setSsbmdm(dept.getDeptcode());
                    zq.setSsxgajdm(dept.getFxjcode());
                    zq.setSsxgajid(dept.getFxjid());
                    zq.setSsxgaj(dept.getFxjname());
                    zq.setSssgaj(dept.getDszname());
                    zq.setSssgajdm(dept.getDszcode());
                    zq.setSssgajid(dept.getDszid());
                }
                zq.setXtSjly("1");
                this.tbQwZbpbZqMapper.insert(zq);
                // 保存时间段内的所有的警力数据
                List<String> jlIds = jlList.stream().map(TbQwJl::getJlId).collect(Collectors.toList());
                if (StringUtils.isNotBlank(zq.getZbldId())) {
                    jlIds.add(zq.getZbldId());
                }
                if (StringUtils.isNotBlank(zq.getZbzhzId())) {
                    jlIds.add(zq.getZbzhzId());
                }
                if (StringUtils.isNotBlank(zq.getZzzhzId())) {
                    jlIds.add(zq.getZzzhzId());
                }
                if (StringUtils.isNotBlank(zq.getFzzbId())) {
                    jlIds.add(zq.getFzzbId());
                }
                this.setZbpbMrjl(pb, zq, jlIds, pbid);
            }
        }
    }

    // 保存时间段内的所有的警力数据
    private void setZbpbMrjl(TbQwZbpb pb, TbQwZbpbZq zq, List<String> jlIds, String pbid) {
        Date kssj = DateUtils.getNextDate(pb.getZbpbksrq(), "D", zq.getZbzq() - 1);
        Date jssj = pb.getZbpbjsrq();
        if (kssj != null && jssj != null) {
            // 判断结束时间和开始时间的年份是否一样，如果一样，保存所有数据，
            // 如果不一样暂时保存本年数据
            if (!DateUtils.getQueryDateString(kssj, "13")
                    .equals(DateUtils.getQueryDateString(jssj, "13"))) {
                jssj = DateUtils.strToDate(DateUtils.getQueryDateString(kssj, "13") + "-12-31", "01");
            }
            int a = -1;
            while (kssj.getTime() <= jssj.getTime()) {
                a++;
                if (a % pb.getXhzq() != 0) {
                    kssj = DateUtils.getNextDate(kssj, "D", +1);
                    continue;
                }
                if ("1".equals(pb.getXhlx())) {
                    // 排除今天是休息日的情况，则需要查询今天是否是休息日
                    boolean flag = this.checkXxr(kssj);
                    if (flag) {
                        kssj = DateUtils.getNextDate(kssj, "D", +1);
                        continue;
                    }
                } else if ("2".equals(pb.getXhlx())) {
                    // 排除今天是工作日的情况，则需要查询今天是否是工作日
                    boolean flag = this.checkXxr(kssj);
                    if (!flag) {
                        kssj = DateUtils.getNextDate(kssj, "D", +1);
                        continue;
                    }
                }
                TbQwZbpbMrjl mrjl = new TbQwZbpbMrjl();
                mrjl.setPbId(pb.getId());
                mrjl.setPbzqId(zq.getId());
                String zbksskTime = DateUtils.getQueryDateString(kssj, "01") + " "
                        + DateUtils.getQueryDateString(zq.getKssj(), "10");
                mrjl.setZbkssj(DateUtils.strToDate(zbksskTime, "02"));
                // 判断排班的开始时间是否大于排班的结束时间，如果大于 那么巡防的结束时间需要加一天
                if (zq.getKssj().getTime() > zq.getJssj().getTime()) {
                    Date tempTime = DateUtils.getNextDate(kssj, "D", +1);
                    String xfjsskTime = DateUtils.getQueryDateString(tempTime, "01") + " "
                            + DateUtils.getQueryDateString(zq.getJssj(), "10");
                    mrjl.setZbjssj(DateUtils.strToDate(xfjsskTime, "02"));
                } else {
                    String xfjsskTime = DateUtils.getQueryDateString(kssj, "01") + " "
                            + DateUtils.getQueryDateString(zq.getJssj(), "10");
                    mrjl.setZbjssj(DateUtils.strToDate(xfjsskTime, "02"));
                }
                mrjl.setZbrq(kssj);
                // 判断时间是否重合，如果重合则抛出异常给前端
                this.checkTime(mrjl, jlIds, pbid);
                this.tbQwZbpbMrjlMapper.insert(mrjl);
                kssj = DateUtils.getNextDate(kssj, "D", +1);
            }
        }

    }

    // 判断时间是否重合，如果重合则抛出异常给前端
    private void checkTime(TbQwZbpbMrjl mrjl, List<String> jlIds, String pbid) {
        List<TbQwZbpbMrjl> mrjlList = this.tbQwZbpbMrjlMapper.getMrjlByTime(DateUtils.getQueryDateString(mrjl.getZbkssj(), "02"),
                DateUtils.getQueryDateString(mrjl.getZbjssj(), "02"), pbid);
        if (mrjlList != null && mrjlList.size() > 0) {
            mrjlList.forEach(m -> {
                TbQwZbpbZq zq = this.tbQwZbpbZqMapper.selectById(m.getPbzqId());
                if (zq != null) {
                    TbQwZbpb zbpb = this.baseMapper.selectById(zq.getPbId());
                    if (zbpb != null) {
                        if (jlIds.indexOf(zq.getZbldId()) != -1) {
                            throw new BusinessException(("值班领导(" + zq.getZbldXm() + ")在" +
                                    "其他排班中时间冲突，冲突排班名称：" + zbpb.getZbmc()));
                        }
                        System.err.println(zq.getZbzhzId());
                        if (jlIds.indexOf(zq.getZbzhzId()) != -1) {
                            throw new BusinessException(("值班指挥长(" + zq.getZbzhzXm() + ")在" +
                                    "其他排班中时间冲突，冲突排班名称：" + zbpb.getZbmc()));
                        }
                        if (jlIds.indexOf(zq.getZzzhzId()) != -1) {
                            throw new BusinessException(("综合指挥长(" + zq.getZzzhzXm() + ")在" +
                                    "其他排班中时间冲突，冲突排班名称：" + zbpb.getZbmc()));
                        }
                        if (jlIds.indexOf(zq.getFzzbId()) != -1) {
                            throw new BusinessException(("法制值班(" + zq.getFzzbXm() + ")在" +
                                    "其他排班中时间冲突，冲突排班名称：" + zbpb.getZbmc()));
                        }
                        // 其他警力
                        List<TbQwJl> jlList = this.tbQwJlMapper.selectList(
                                new LambdaQueryWrapper<TbQwJl>()
                                        .eq(TbQwJl::getYwid, zq.getId())
                                        .eq(TbQwJl::getXtSjzt, "1")
                        );
                        jlList.forEach(jl -> {
                            if (jlIds.indexOf(jl.getJlId()) != -1) {
                                throw new BusinessException(("01".equals(jl.getJllx()) ? "民警" : "辅警") + "(" + jl.getJlxm() + ")在" +
                                        "其他排班中时间冲突，冲突排班名称：" + zbpb.getZbmc());
                            }
                        });
                    }
                }
            });
        }
    }

    // 判断今天是否是工作日
    private boolean checkGzr(Date kssj) {
        int week = DateUtils.dateToWeek(kssj);
        if (week == 0 || week == 6) {
            TbQwJjr jjr = this.tbQwJjrMapper.selectOne(
                    new LambdaQueryWrapper<TbQwJjr>()
                            .eq(TbQwJjr::getJjrq, kssj)
                            .eq(TbQwJjr::getRqlx, "1")
            );
            if (jjr != null) return true;
        }
        TbQwJjr jjr = this.tbQwJjrMapper.selectOne(
                new LambdaQueryWrapper<TbQwJjr>()
                        .eq(TbQwJjr::getJjrq, kssj)
                        .eq(TbQwJjr::getRqlx, "0")
        );
        return jjr == null;
    }

    // 判断今天是否是节假日或休息日
    private boolean checkXxr(Date kssj) {
        TbQwJjr jjr = this.tbQwJjrMapper.selectOne(
                new LambdaQueryWrapper<TbQwJjr>()
                        .eq(TbQwJjr::getJjrq, kssj)
                        .eq(TbQwJjr::getRqlx, "0")
        );
        if (jjr != null) return true;
        int week = DateUtils.dateToWeek(kssj);
        if (week == 0 || week == 6) {
            jjr = this.tbQwJjrMapper.selectOne(
                    new LambdaQueryWrapper<TbQwJjr>()
                            .eq(TbQwJjr::getJjrq, kssj)
                            .eq(TbQwJjr::getRqlx, "1")
            );
            return jjr == null;
        }
        return false;
    }
}
