package cn.com.ty.lift.business.maintenance.service;

import cn.com.ty.lift.business.capital.dao.mapper.CommonMapper;
import cn.com.ty.lift.business.common.CommonRequest;
import cn.com.ty.lift.business.framework.util.MessageUtils;
import cn.com.ty.lift.business.library.dao.entity.Lift;
import cn.com.ty.lift.business.library.service.LiftService;
import cn.com.ty.lift.business.maintenance.dao.entity.MaintenancePlan;
import cn.com.ty.lift.business.maintenance.dao.entity.model.request.MaintenancePlanRequest;
import cn.com.ty.lift.business.maintenance.dao.entity.model.request.MtPlanRequest;
import cn.com.ty.lift.business.maintenance.dao.entity.model.response.LiftPrintResponse;
import cn.com.ty.lift.business.maintenance.dao.entity.model.response.MaintenancePlanPrintResponse;
import cn.com.ty.lift.business.maintenance.dao.entity.model.response.MaintenancePlanResponse;
import cn.com.ty.lift.business.maintenance.dao.entity.model.response.MtPlanResponse;
import cn.com.ty.lift.business.maintenance.dao.mapper.MaintenancePlanMapper;
import cn.com.ty.lift.business.project.dao.entity.Project;
import cn.com.ty.lift.business.project.dao.entity.ProjectLiftRelevance;
import cn.com.ty.lift.business.project.dao.entity.Region;
import cn.com.ty.lift.business.project.dao.entity.model.response.ProjectDetailResponse;
import cn.com.ty.lift.business.project.service.ProjectAppService;
import cn.com.ty.lift.business.project.service.ProjectLiftRelevanceService;
import cn.com.ty.lift.business.project.service.ProjectService;
import cn.com.ty.lift.business.push.service.PushUserService;
import cn.com.ty.lift.common.base.ExportRequest;
import cn.com.ty.lift.common.model.PushMessage;
import cn.com.ty.lift.common.model.PushUserInfo;
import cn.com.ty.lift.common.utils.DateUtils;
import cn.com.xwy.boot.web.dto.RestResponse;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.jms.core.JmsMessagingTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author bieao
 * @date 2019/12/14
 * @description 维保计划业务层
 */
@Service
@Slf4j
public class MaintenancePlanService extends ServiceImpl<MaintenancePlanMapper, MaintenancePlan> {

    @Resource
    private ProjectService projectService;

    @Resource
    private LiftService liftService;

    @Resource
    private CommonMapper commonMapper;

    @Resource
    private ProjectLiftRelevanceService projectLiftRelevanceService;

    @Resource
    private ProjectAppService projectAppService;

    @Resource
    private JmsMessagingTemplate jmsMessagingTemplate;

    @Resource
    private PushUserService pushUserService;

    private Map<String, String> headsMap = new LinkedHashMap<String, String>() {{
        put("projectCode", "项目编号");
        put("projectName", "项目名称");
        put("regionName", "区域名称");
        put("registrationCode", "注册代码");
        put("devicePosition", "电梯位置");
        put("workerName", "维保工");
        put("planInterval", "间隔");
        put("liftStatus", "电梯维保状态");
        put("planDate", "计划时间");
    }};

    //保养类型 1.半月，2.季度，3.半年，4.全年
    private int[] maintenanceType = {1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 4};

    /**
     * @param request 维保计划列表
     * @return 1.成功, 0.失败, 消息描述
     * @description 查询维保计划
     * @date 2019/12/24 10:47 AM
     */
    public IPage<MaintenancePlanResponse> list(MaintenancePlanRequest request) {
        return baseMapper.findByCondition(request.getPage(), request);
    }

    public List<Map<String,String>> exportList(List<String> ids){
        return baseMapper.exportList(ids);
    }

    /**
     * @param request 公司id，项目id，电梯id
     * @return 1.成功, 0.失败, 消息描述
     * @description 查询维保计划详情列表
     * @date 2020/1/2 9:43 上午
     */
    public List<MaintenancePlan> detailList(MaintenancePlanRequest request) {
        QueryWrapper<MaintenancePlan> queryWrapper = new QueryWrapper<>();
        LambdaQueryWrapper<MaintenancePlan> lambdaQueryWrapper = queryWrapper.lambda();
        lambdaQueryWrapper.eq(MaintenancePlan::getMtCompanyId, request.getMtCompanyId());
        lambdaQueryWrapper.eq(MaintenancePlan::getProjectId, request.getProjectId());
        lambdaQueryWrapper.eq(MaintenancePlan::getLiftId, request.getLiftId());
        lambdaQueryWrapper.between(MaintenancePlan::getPlanDate, request.getBeginTime(), request.getEndTime());
        lambdaQueryWrapper.orderByAsc(MaintenancePlan::getPlanDate);
        return list(lambdaQueryWrapper);
    }

    /**
     * @param planList 需生成维保计划的电梯列表
     * @param firstTime 首保时间
     * @return 判断结果
     * @description 新增维保计划前置判断条件
     * @date 2020/1/9 3:56 下午
     */
    public boolean preJudgment(List<MaintenancePlan> planList, LocalDate firstTime) {
        Collection<Project> projects = projectService.getProjectList(planList);
        for (Project entry : projects) {
            //若首保时间早于项目开始时间，则不能新增维保计划
            boolean startResult = firstTime.isBefore(entry.getStartDate());
            if (startResult) return false;
            //若首保时间晚于项目结束时间，也不能新增维保计划
            boolean endResult = firstTime.isAfter(entry.getEndDate());
            if (endResult) return false;
        }
        return true;
    }

    public MaintenancePlan getOne(Long id) {
        LambdaQueryWrapper<MaintenancePlan> lambdaQueryWrapper = new QueryWrapper<MaintenancePlan>().lambda();
        lambdaQueryWrapper.eq(MaintenancePlan::getId, id);
        return getOne(lambdaQueryWrapper);
    }

    /**
     * @param liftId 电梯ID
     * @param projectId 项目ID
     * @param mtCompanyId 公司ID
     * @param interval 保养间隔
     * @param planDate 保养时间
     * @param type 保养类型
     * @param liftCharge 电梯负责人
     * @param operator 操作人
     * @return
     * @description 生成保养计划消息推送
     * @date 2020/5/5 9:26 下午
     */
    public void sendCreateMessage(Long liftId, Long projectId, Long mtCompanyId, int interval, LocalDate planDate, int type, String liftCharge, String operator, Long workerId) {
        //消息推送
        List<Long> userIds = new ArrayList<>();
        Region region = pushUserService.findRegionByProject(projectId, mtCompanyId);
        if (Objects.nonNull(region)) {
            userIds.addAll(region.members());
        }
        userIds.add(workerId);
        List<PushUserInfo> pushUserInfos = new ArrayList<>();
        if (!userIds.isEmpty()) {
            List<PushUserInfo> userInfos = pushUserService.listByUserIds(mtCompanyId, userIds);
            pushUserInfos.addAll(userInfos);
        }
        if (!pushUserInfos.isEmpty()) {
            ProjectDetailResponse detail = projectAppService.detail(projectId);
            Optional<Lift> lift = liftService.getOne(null, liftId);
            lift.ifPresent(l ->
                PushMessage.maintainCreatePlan(detail.getAreaName(), detail.getProjectName(), l.getDevicePosition(),
                        l.getRegistrationCode(), interval, planDate, type, liftCharge, operator).sendTokenOnPlatform(jmsMessagingTemplate, pushUserInfos));
        }
    }

    /**
     * @param liftId 电梯ID
     * @param projectId 项目ID
     * @param mtCompanyId 公司ID
     * @param interval 保养间隔
     * @param planDate 保养时间
     * @param type 保养类型
     * @param liftCharge 电梯负责人
     * @param operator 操作人
     * @param workerId 维保工
     * @return
     * @description 修改保养计划消息推送
     * @date 2020/5/8 10:25 上午
     */
    public void sendModifyMessage(Long liftId, Long projectId, Long mtCompanyId, int interval, LocalDate planDate, int type, String liftCharge, String operator, Long workerId) {
        //消息推送
        List<Long> userIds = new ArrayList<>();
        Region region = pushUserService.findRegionByProject(projectId, mtCompanyId);
        if (Objects.nonNull(region)) {
            userIds.addAll(region.members());
        }
        userIds.add(workerId);
        List<PushUserInfo> pushUserInfos = new ArrayList<>();
        if (!userIds.isEmpty()) {
            List<PushUserInfo> userInfos = pushUserService.listByUserIds(mtCompanyId, userIds);
            pushUserInfos.addAll(userInfos);
        }
        if (!pushUserInfos.isEmpty()) {
            ProjectDetailResponse detail = projectAppService.detail(projectId);
            Optional<Lift> lift = liftService.getOne(null, liftId);
            lift.ifPresent(l ->
                    PushMessage.maintainModifyPlan(detail.getAreaName(), detail.getProjectName(), l.getDevicePosition(),
                            l.getRegistrationCode(), interval, planDate, type, liftCharge, operator).sendTokenOnPlatform(jmsMessagingTemplate, pushUserInfos));
        }
    }


    /**
     * @param request 电梯列表
     * @return 是否成功
     * @description 批量生成维保计划
     * @date 2019/12/16 2:14 PM
     */
    public RestResponse insertBatch(MaintenancePlanRequest request) {
        List<MaintenancePlan> planList = request.getPlanList();
        boolean result = preJudgment(planList, request.getFirstTime());
        if (!result) {
            return RestResponse.fail(MessageUtils.get("msg.error.time"));
        }
        List<MaintenancePlan> resultList = addPlan(request);
        boolean ret = saveBatch(resultList, resultList.size());
        if (ret) {
            List<MaintenancePlan> messageList = new ArrayList<>();
            Map<Long, List<MaintenancePlan>> collectMap = resultList.stream().collect(Collectors.groupingBy(MaintenancePlan::getId));
            for (Map.Entry<Long, List<MaintenancePlan>> entry : collectMap.entrySet()) {
                MaintenancePlan plan = entry.getValue().get(0);
                messageList.add(plan);
            }
            //生成维保计划发送推送消息
            MaintenancePlan plan = messageList.get(0);
            String workerName = commonMapper.queryUserNameById(plan.getWorkerId());
            String creatorName = commonMapper.queryUserNameById(plan.getCreatorId());
            sendCreateMessage(plan.getLiftId(), plan.getProjectId(), plan.getMtCompanyId(), request.getInterval(),
                    request.getFirstTime(), plan.getType(), workerName, creatorName, plan.getWorkerId());
            return RestResponse.success(null, MessageUtils.get("msg.add.success"));
        } else {
            return RestResponse.fail(MessageUtils.get("msg.add.fail"));
        }
    }

    /**
     * @param request 需要保养的电梯
     * @return List<MaintenancePlan> 维保计划列表
     * @description 新增维保计划
     * @date 2019/12/16 1:21 PM
     */
    public List<MaintenancePlan> addPlan(MaintenancePlanRequest request) {
        List<MaintenancePlan> plans = request.getPlanList();
        Collection<Project> projects = projectService.getProjectList(request.getPlanList());
        //获取保养间隔
        int interval = request.getInterval();
        //获取从第几期开始
        Integer periods = request.getPeriods();
        //获取首保时间
        LocalDate firstTime = request.getFirstTime();
        List<MaintenancePlan> planList = new ArrayList<>();
        plans.forEach(plan -> {
            Optional<Project> project = projects.stream().filter(p -> p.getId().equals(plan.getProjectId())).findFirst();
            project.ifPresent(entry -> {
                //项目结束时间默认增加三个月
                LocalDate endDate = entry.getEndDate().plusMonths(3);
                planList.addAll(generatePlan(plan, periods, interval, firstTime, endDate));
            });
        });
        //更新项目电梯关联表中电梯的首保时间和保养间隔
        List<ProjectLiftRelevance> entryList = request.getRelevanceList();
        entryList.forEach(entry -> {
            entry.setPlanInterval(interval);
            entry.setFirstTime(firstTime);
        });
        projectLiftRelevanceService.updateBatchById(entryList);
        return planList;
    }

    /**
     * @param interval 保养间隔
     * @param beginTime 开始时间
     * @param endTime 结束时间
     * @return 期数
     * @description 获取维保计划生成期数
     * @date 2020/1/8 8:11 下午
     */
    public int getTimes(int interval, LocalDate beginTime, LocalDate endTime) {
        //计算当前电梯所在项目开始时间到结束时间需要保养的期数
        long days = beginTime.until(endTime, ChronoUnit.DAYS);
        double num = Math.floor(Double.parseDouble(String.valueOf((days / interval))));
        return (int) num;
    }

    /**
     * @param plan 维保计划
     * @param periods 期数
     * @param interval 保养间隔
     * @param beginTime 开始时间
     * @param endTime 结束时间
     * @return 维保计划列表
     * @description 生成维保计划
     * @date 2020/1/8 8:20 下午
     */
    public List<MaintenancePlan> generatePlan(MaintenancePlan plan, Integer periods, int interval, LocalDate beginTime, LocalDate endTime) {
        //返回维保计划列表
        List<MaintenancePlan> planList = new ArrayList<>();
        int times = getTimes(interval, beginTime, endTime);
        log.info("总期数：{},从第{}期开始,保养间隔：{}天,开始时间：{},结束时间：{}", times + 1, periods, interval, beginTime, endTime);
        int length = maintenanceType.length;
        for (int i = 0; i <= times; i++) {
            MaintenancePlan entry = new MaintenancePlan();
            entry.setWorkerId(plan.getWorkerId());
            entry.setLiftId(plan.getLiftId());
            entry.setProjectId(plan.getProjectId());
            entry.setMtCompanyId(plan.getMtCompanyId());
            int mod = periods % length;
            //设置维保类型
            if (mod == 0) {
                entry.setType(maintenanceType[length - 1]);
            } else {
                entry.setType(maintenanceType[mod - 1]);
            }
            if (i == 0) {
                entry.setPlanDate(beginTime);
            } else {
                //设置维护保养时间
                MaintenancePlan maintenancePlan = planList.get(i - 1);
                LocalDate planDate = maintenancePlan.getPlanDate().plusDays(interval);
                entry.setPlanDate(planDate);
            }
            entry.setCount(periods);
            log.info("第{}期,类型：{},计划时间：{}", periods, entry.getType(), entry.getPlanDate());
            periods++;
            planList.add(entry);
        }
        return planList;
    }

    /**
     * @param currentTime 当前时间
     * @param liftId 电梯id
     * @param projectId 项目id
     * @param mtCompanyId 公司id
     * @return List<MaintenancePlan> 维保计划列表
     * @description 查询当前时间之后的维保计划
     * @date 2020/1/7 2:40 下午
     */
    public List<MaintenancePlan> findPlanList(Long liftId, Long projectId, Long mtCompanyId, LocalDate currentTime, String source) {
        QueryWrapper<MaintenancePlan> queryWrapper = new QueryWrapper<>();
        LambdaQueryWrapper<MaintenancePlan> lambdaQueryWrapper = queryWrapper.lambda();
        lambdaQueryWrapper.eq(MaintenancePlan::getLiftId, liftId);
        lambdaQueryWrapper.eq(MaintenancePlan::getProjectId, projectId);
        lambdaQueryWrapper.eq(MaintenancePlan::getMtCompanyId, mtCompanyId);
        if (source.equals("plan")) {
            lambdaQueryWrapper.ge(MaintenancePlan::getPlanDate, currentTime);
        } else {
            lambdaQueryWrapper.gt(MaintenancePlan::getPlanDate, currentTime);
        }
        return list(lambdaQueryWrapper);
    }


    /**
     * @param mtCompanyId 公司id
     * @param liftId 电梯id
     * @return 维保计划列表
     * @description 获取当前期数后的维保计划列表
     * @date 2020/1/8 10:33 上午
     */
    public List<MaintenancePlan> findPlanList(Long mtCompanyId, Long liftId, Integer periods) {
        QueryWrapper<MaintenancePlan> queryWrapper = new QueryWrapper<>();
        LambdaQueryWrapper<MaintenancePlan> lambdaQueryWrapper = queryWrapper.lambda();
        lambdaQueryWrapper.eq(MaintenancePlan::getMtCompanyId, mtCompanyId);
        lambdaQueryWrapper.eq(MaintenancePlan::getLiftId, liftId);
        lambdaQueryWrapper.gt(MaintenancePlan::getCount, periods);
        return list(lambdaQueryWrapper);
    }

    /**
     * @param request 修改维保计划请求
     * @return 是否修改成功
     * @description 修改维保计划
     * @date 2019/12/16 5:25 PM
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean modifyPlan(MaintenancePlanRequest request) {
        //获取公司id
        Long mtCompanyId = request.getMtCompanyId();
        //获取电梯id
        Long liftId = request.getLiftId();
        //获取项目id
        Long projectId = request.getProjectId();
        //获取维保工id
        Long workerId = request.getWorkerId();
        MaintenancePlan plan = new MaintenancePlan();
        plan.setProjectId(projectId);
        plan.setMtCompanyId(mtCompanyId);
        plan.setLiftId(liftId);
        plan.setWorkerId(workerId);
        Optional<Project> optional = projectService.getOne(projectId);
        Project project = new Project();
        if (optional.isPresent()) project = optional.get();
        if (ObjectUtil.isEmpty(project)) return false;
        //项目结束时间默认增加三个月
        LocalDate endDate = project.getEndDate().plusMonths(3);
        //获取当前的保养时间
        LocalDate currentTime = request.getCurrentTime();
        //获取修改的保养时间
        LocalDate updateTime = request.getUpdateTime();
        //获取修改的保养间隔
        Integer updateInterval = request.getInterval();
        //获取当前期数
        Integer periods = request.getPeriods();
        ProjectLiftRelevance relevance = new ProjectLiftRelevance();
        relevance.setId(request.getRelevanceId());
        relevance.setPlanInterval(updateInterval);
        //获取当前电梯的保养间隔
        ProjectLiftRelevance entry = projectLiftRelevanceService.getOne(mtCompanyId, liftId);
        if (ObjectUtil.isEmpty(entry)) return false;
        int interval = entry.getPlanInterval();
        boolean isNotNull = ObjectUtil.isNotEmpty(currentTime) && ObjectUtil.isNotEmpty(updateTime);
        boolean isNull = ObjectUtil.isEmpty(currentTime) && ObjectUtil.isEmpty(updateTime);
        List<MaintenancePlan> planList;
        List<MaintenancePlan> plans = new ArrayList<>();
        if (isNotNull && ObjectUtil.isEmpty(updateInterval)) {
            //获取当前时间后的维保计划列表，并清除计划
            planList = findPlanList(liftId, projectId, mtCompanyId, currentTime, "plan");
            removeByIds(planList.stream().map(MaintenancePlan::getId).collect(Collectors.toList()));
            //按照修改时间重新生成计划
            plans = generatePlan(plan, periods, interval, updateTime, endDate);
        } else if (isNull && ObjectUtil.isNotEmpty(updateInterval)) {
            //获取当前期数后的维保计划列表，并清除计划
            planList = findPlanList(mtCompanyId, liftId, periods);
            LocalDate planDate;
            Optional<MaintenancePlan> planOptional = planList.stream()
                    .filter(entity -> entity.getCount().equals(periods)).findFirst();
            if (planOptional.isPresent()) {
                MaintenancePlan maintenancePlan = planOptional.get();
                planDate = maintenancePlan.getPlanDate();
            } else return false;
            removeByIds(planList.stream().map(MaintenancePlan::getId).collect(Collectors.toList()));
            //更新项目电梯关联表保养间隔
            projectLiftRelevanceService.modify(relevance);
            plans = generatePlan(plan, periods, updateInterval, planDate, endDate);
        } else if (isNotNull && ObjectUtil.isNotEmpty(updateInterval)) {
            //获取当前期数后的维保计划列表，并清除计划
            planList = findPlanList(mtCompanyId, liftId, periods);
            removeByIds(planList.stream().map(MaintenancePlan::getId).collect(Collectors.toList()));
            //更新项目电梯关联表保养间隔
            projectLiftRelevanceService.modify(relevance);
            //按照修改时间重新生成计划
            plans = generatePlan(plan, periods, updateInterval, updateTime, endDate);
        }
        MaintenancePlan newPlan = plans.get(0);
        String workerName = commonMapper.queryUserNameById(workerId);
        String creatorName = commonMapper.queryUserNameById(newPlan.getCreatorId());
        //发送修改计划消息推送
        sendModifyMessage(liftId, projectId, mtCompanyId, interval, newPlan.getPlanDate(), newPlan.getType(), workerName, creatorName, workerId);
        return saveBatch(plans, plans.size());
    }

    /**
     * @param mtCompanyId 公司id
     * @param liftList 电梯id列表
     * @return 是否成功
     * @description 批量清除维保计划
     * @date 2019/12/28 2:00 PM
     */
    public boolean removeMaintenancePlan(Long mtCompanyId, Collection<Long> liftList) {
        QueryWrapper<MaintenancePlan> queryWrapper = new QueryWrapper<>();
        LambdaQueryWrapper<MaintenancePlan> lambdaQueryWrapper = queryWrapper.lambda();
        lambdaQueryWrapper.eq(MaintenancePlan::getMtCompanyId, mtCompanyId);
        lambdaQueryWrapper.in(MaintenancePlan::getLiftId, liftList);
        return remove(queryWrapper);
    }

    /**
     * @param mtCompanyId 公司id
     * @param liftList 电梯id列表
     * @return List<MaintenancePlan> 维保计划列表
     * @description 根据公司id和电梯id列表获取维保计划
     * @date 2020/5/23 3:58 下午
     */
    public List<MaintenancePlan> getPlanList(Long mtCompanyId, Collection<Long> liftList) {
        QueryWrapper<MaintenancePlan> queryWrapper = new QueryWrapper<>();
        LambdaQueryWrapper<MaintenancePlan> lambdaQueryWrapper = queryWrapper.lambda();
        lambdaQueryWrapper.eq(MaintenancePlan::getMtCompanyId, mtCompanyId);
        lambdaQueryWrapper.in(MaintenancePlan::getLiftId, liftList);
        lambdaQueryWrapper.eq(MaintenancePlan::getStatus, 0);
        return list(queryWrapper);
    }

    /**
     * @param mtCompanyId 公司id
     * @param liftId      电梯id
     * @return 是否成功
     * @description 清空维保计划
     * @date 2019/12/21 3:39 PM
     */
    public boolean cleanPlan(Long mtCompanyId, Long liftId) {
        Map<String, Object> columnMap = new HashMap<>(2);
        columnMap.put("mt_company_id", mtCompanyId);
        columnMap.put("lift_id", liftId);
        return removeByMap(columnMap);
    }

    /**
     * @param request 导出维保计划数据列表
     * @return RestResponse 状态码和返回消息
     * @description 导出维保计划
     * @date 2019/12/19 11:27 AM
     */
    public void export(ExportRequest request, HttpServletResponse response) {
        List<String> ids = request.getIds();
        List<Map<String, String>> planList = exportList(ids);
        ExcelWriter writer = new ExcelWriter(true, "维保计划");
        //设置列别名
        headsMap.forEach(writer::addHeaderAlias);
        String fileName = DateUtils.generateCode() + ".xlsx";
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
        try (ServletOutputStream out = response.getOutputStream()) {
            writer.write(planList, true);
            writer.autoSizeColumnAll();
            writer.flush(out, true);
            writer.close();
        } catch (IOException e) {
            log.error("维保计划导出失败", e);
        }
    }

    /**
     * @param mtCompanyId 公司id
     * @param liftIdList 电梯id列表
     * @param beginTime 开始时间
     * @return List<LiftPrintResponse> 电梯维保计划列表
     * @description 根据公司id和电梯id列表查询维保计划列表，并组装电梯列表数据
     * @date 2020/3/2 4:39 下午
     */
    public List<LiftPrintResponse> getLiftMaintenancePlanList(Long mtCompanyId, List<Long> liftIdList, LocalDate beginTime) {
        //根据电梯id列表查询电梯列表
        List<LiftPrintResponse> liftList = liftService.queryLiftListByIdList(liftIdList);

        LocalDate endTime = beginTime.with(TemporalAdjusters.lastDayOfMonth());
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("mtCompanyId", mtCompanyId);
        paramMap.put("liftIdList", liftIdList);
        paramMap.put("beginTime", beginTime);
        paramMap.put("endTime", endTime);
        //根据电梯id、公司id查询维保计划列表
        List<MaintenancePlan> planList = baseMapper.queryPlanListByIds(paramMap);

        //组装电梯列表中的维保计划数据
        for (LiftPrintResponse entry : liftList) {
            List<Map<String, Object>> plans = new ArrayList<>();
            for (MaintenancePlan plan : planList) {
                if (entry.getProjectId().equals(plan.getProjectId())
                        && entry.getLiftId().equals(plan.getLiftId())
                        && entry.getMtCompanyId().equals(plan.getMtCompanyId())) {
                    Map<String, Object> map = new HashMap<>();
                    map.put("planDate", plan.getPlanDate());
                    map.put("type", plan.getType());
                    plans.add(map);
                }
            }
            entry.setPlanList(plans);
        }
        return liftList;
    }


    /**
     * @param request 电梯列表
     * @return List<MaintenancePlanPrintResponse> 维保计划打印列表
     * @description 维保计划打印列表
     * @date 2020/2/13 3:39 下午
     */
    public List<MaintenancePlanPrintResponse> planPrint(MaintenancePlanRequest request) {
        List<Long> liftIdList = request.getLiftList().stream().map(MaintenancePlan::getLiftId).collect(Collectors.toList());

        List<Long> projectIdList = request.getLiftList().stream().map(MaintenancePlan::getProjectId).collect(Collectors.toList());
        //根据项目id列表查询项目列表
        List<MaintenancePlanPrintResponse> projectList = projectService.queryProjectListByIdList(projectIdList);

        List<LiftPrintResponse> liftList = getLiftMaintenancePlanList(request.getMtCompanyId(), liftIdList, request.getBeginTime());
        //组装项目列表中的电梯数据
        for (MaintenancePlanPrintResponse project : projectList) {
            List<LiftPrintResponse> liftPrintResponses = new ArrayList<>();
            for (LiftPrintResponse lift : liftList) {
                if (project.getProjectId().equals(lift.getProjectId())
                        && project.getMtCompanyId().equals(lift.getMtCompanyId())) {
                    liftPrintResponses.add(lift);
                }
            }
            project.setLiftList(liftPrintResponses);
            project.setNum(project.getLiftList().size());
        }
     return projectList;
    }

    /**
     * 根据条件分页查询 维保计划-超期计划
     * @author wcz
     * @param request MtPlanRequest
     * @return IPage<MtPlanResponse>
     */
    public IPage<MtPlanResponse> pagePlanByCondition(MtPlanRequest request){
        return baseMapper.pagePlanByCondition(request.getPage(),request);
    }

    /**
     * 根据条件统计 维保计划-超期计划
     * @author wcz
     * @param request MtPlanRequest
     * @return long
     */
    public long countPlanByCondition(MtPlanRequest request){
        return baseMapper.countPlanByCondition(request);
    }

    /**
     * @param request 公司id，用户id
     * @return 条数
     * @description 根据公司id和用户id查询待保养的任务数量
     * @date 2020/4/25 9:31 上午
     */
    public long countWaitingMaintenanceByUser(CommonRequest request) {
        return baseMapper.countWaitingMaintenanceByUser(request);
    }

    /**
     * 根据条件统计 维保计划-超期计划
     * @author wcz
     * @param limit 条数
     * @return List<MaintenancePlan>
     */
    public boolean updateOverduePlan(int limit){
        LambdaUpdateWrapper<MaintenancePlan> lambdaUpdateWrapper = Wrappers.lambdaUpdate();
        lambdaUpdateWrapper.lt(MaintenancePlan::getPlanDate, LocalDate.now());
        lambdaUpdateWrapper.isNull(MaintenancePlan::getWorkDate);
        lambdaUpdateWrapper.notIn(MaintenancePlan::getStatus, Arrays.asList(-1, 3));
        lambdaUpdateWrapper.last("LIMIT " + limit);
        lambdaUpdateWrapper.set(MaintenancePlan::getStatus, -1);
        return update(lambdaUpdateWrapper);
    }

    public IPage<MaintenancePlan> pageOverduePlan(IPage<MaintenancePlan> page){
        LambdaQueryWrapper<MaintenancePlan> lambdaQueryWrapper = Wrappers.lambdaQuery();
        lambdaQueryWrapper.lt(MaintenancePlan::getPlanDate, LocalDate.now());
        lambdaQueryWrapper.isNull(MaintenancePlan::getWorkDate);
        lambdaQueryWrapper.notIn(MaintenancePlan::getStatus, Arrays.asList(-1, 3));
        return page(page, lambdaQueryWrapper);
    }
}
