package com.yeejoin.amos.maintenance.business.service.impl;

import com.alibaba.fastjson.JSON;
import com.google.common.base.Joiner;
import com.yeejoin.amos.boot.biz.common.enums.RuleTypeEnum;
import com.yeejoin.amos.boot.biz.common.utils.RedisUtils;
import com.yeejoin.amos.feign.privilege.Privilege;
import com.yeejoin.amos.feign.privilege.model.AgencyUserModel;
import com.yeejoin.amos.feign.privilege.model.RoleModel;
import com.yeejoin.amos.feign.systemctl.Systemctl;
import com.yeejoin.amos.feign.systemctl.model.MessageModel;
import com.yeejoin.amos.maintenance.business.constants.XJConstant;
import com.yeejoin.amos.maintenance.business.dao.mapper.InputItemMapper;
import com.yeejoin.amos.maintenance.business.dao.mapper.PlanMapper;
import com.yeejoin.amos.maintenance.business.dao.mapper.PlanTaskDetailMapper;
import com.yeejoin.amos.maintenance.business.dao.mapper.PlanTaskMapper;
import com.yeejoin.amos.maintenance.business.dao.repository.*;
import com.yeejoin.amos.maintenance.business.entity.mybatis.CheckChkExListBo;
import com.yeejoin.amos.maintenance.business.feign.JCSFeignClient;
import com.yeejoin.amos.maintenance.business.param.CheckPtListPageParam;
import com.yeejoin.amos.maintenance.business.param.PlanTaskPageParam;
import com.yeejoin.amos.maintenance.business.service.intfc.IPlanTaskService;
import com.yeejoin.amos.maintenance.business.util.CommonResponse;
import com.yeejoin.amos.maintenance.business.util.CommonResponseUtil;
import com.yeejoin.amos.maintenance.business.util.PlanTaskUtil;
import com.yeejoin.amos.maintenance.business.util.Toke;
import com.yeejoin.amos.maintenance.business.vo.CalDateVo;
import com.yeejoin.amos.maintenance.business.vo.PlanTaskVo;
import com.yeejoin.amos.maintenance.common.enums.PlanTaskDetailIsFinishEnum;
import com.yeejoin.amos.maintenance.common.enums.PlanTaskFinishStatusEnum;
import com.yeejoin.amos.maintenance.core.common.request.CommonPageable;
import com.yeejoin.amos.maintenance.core.util.DateUtil;
import com.yeejoin.amos.maintenance.core.util.StringUtil;
import com.yeejoin.amos.maintenance.dao.entity.*;
import com.yeejoin.amos.maintenance.exception.YeeException;
import com.yeejoin.amos.maintenance.feign.RemoteSecurityService;
import com.yeejoin.amos.maintenance.quartz.IJobService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.tomcat.jni.Time;
import org.assertj.core.util.Lists;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.typroject.tyboot.core.foundation.context.RequestContext;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;
import org.typroject.tyboot.core.restful.utils.ResponseModel;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalTime;
import java.util.*;
import java.util.concurrent.CompletionException;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service("planTaskService")
public class PlanTaskServiceImpl implements IPlanTaskService {
    private final Logger log = LoggerFactory.getLogger(PlanTaskServiceImpl.class);
    @Autowired
    PlanTaskMapper planTaskMapper;
    @Autowired
    PlanTaskDetailMapper planTaskDetailMapper;
    @Autowired
    PlanMapper planMapper;
    @Autowired
    IPlanTaskDao iplanTaskDao;
    @Autowired
    IPlanDao iplanDao;
    @Autowired
    private RemoteSecurityService remoteSecurityService;
    @Autowired
    private IPlanTaskDetailDao planTaskDetail;
    @Autowired
    IRoutePointDao iRoutePointDao;
    @Autowired
    IJobService jobService;
    @Autowired
    IPointDao iPointDao;
    @Autowired
    IPlanTaskDetailDao iPlanTaskDetailDao;
    @Autowired
    InputItemMapper inputItemMapper;
    @Autowired
    RulePlanService rulePlanService;

    @Autowired
    JCSFeignClient jcsFeignClient;

    @Autowired
    ICheckInputDao checkInputDao;

    @Autowired
    RedisUtils redisUtils;

    private final String MAINTENANCE_PLAN_TASK_KEY = "MAINTENANCE_PLAN_ID:";

    @Override
    public Page<HashMap<String, Object>> getPlanTaskInfo(PlanTaskPageParam params) {
        long total = planTaskMapper.countPlanTask(params);
        List<HashMap<String, Object>> content = planTaskMapper.getPlanTaskInfo(params);
        return new PageImpl<>(content, params, total);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void reGenPlanTask(HashMap<String, Object> param) throws ParseException {
        //1.公共参数准备
        String planId = param.get("planId").toString();//重做的计划编号id
        String strBeginDate = param.get("beginDate").toString();//开始日期（yyyy-MM-dd）
        String strEndDate = param.get("endDate").toString();//结束日期（yyyy-MM-dd）
        String flag = param.get("changeFlag").toString();//是否记为合格标记：0-否，1-是
        Plan plan = iplanDao.findById(Long.parseLong(planId)).get();//
        if (StringUtil.isNotEmpty(plan.getUserId())) {
            //2.数据必输校验，不满足直接return，不再向下进行
            Boolean fileFlag = PlanTaskUtil.checkMustFile(plan);
            if (!fileFlag) {
                return;
            }

            //3.计算生成数据的日期区间（前10位：yyyy-MM-dd）
            CalDateVo vo = PlanTaskUtil.reGenPlanTaskData(plan, strBeginDate, strEndDate);
            //计划未开始,则结束
            if (null == vo) {
                return;
            }
            //日期不符合条件直接结束
            if (!vo.getIsGenData()) {
                return;
            }

            //4.删除planTask表，按照计划id+日期
            deletePlanTaskAndDet(param);

            //5.执行数据生成（具体时间 + 人员）
            List<HashMap<String, Object>> list = genAllExeDate(plan, vo, XJConstant.REGEN_FLAG);

            //6.插入planTask及planTaskDetail
            insertPlanTaskAndDet(list, plan, flag, new Date());
        }
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void planTaskDet(String[] strArry) {
        if (strArry.length <= 0) {
            throw new YeeException("删除数据内容不能为空");
        }
        Set<Long> taskNos = new HashSet<>();
        for (String id : strArry) {
            PlanTaskDetail planTkDet = planTaskDetail.findById(Long.parseLong(id)).get();
            if (null != planTkDet) {
                taskNos.add(planTkDet.getTaskNo());
            }
        }
        planTaskMapper.planTaskDet(strArry);// 删除数据
        HashMap<String, Object> param = new HashMap<String, Object>();
        param.put("IDS", new ArrayList<>(taskNos));
        param.put("FINISH_YES", XJConstant.PLAN_TASK_DET_FINISH_YES);
        planTaskMapper.updatePlanTaskPtInfo(param);// 更新主表，点数量，完成数量
    }

    @Override
    public List<PlanTaskVo> planTaskReport(String toke, String product, String appKey, PlanTaskPageParam param) {
        List<PlanTaskVo> content = planTaskMapper.getPlanTaskInfoList(param);

        String userIds = "";
        String deptIds = "";
        Set<String> set = new HashSet<>();
        Set<String> deptIdSet = new HashSet<>();
        content.forEach(s -> {
            if (s.getUserName() != null) {
                set.add(s.getUserName());
            }
            if (s.getDeptId() > 0) {
                deptIdSet.add(s.getDeptId() + "");
            }
        });

        List<String> userList = new ArrayList<>(set);
        List<String> deptList = new ArrayList<>(deptIdSet);

        Map<String, String> LoginName = new HashMap<>();
        Map<String, String> userMap = new HashMap<>();
        Map<String, String> depMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(userList)) {
            userIds = String.join(",", userList);
            List<AgencyUserModel> userModelList = remoteSecurityService.listUserByUserIds(toke, product, appKey, userIds);
            userMap = userModelList.stream().collect(Collectors.toMap(AgencyUserModel::getUserId, AgencyUserModel::getRealName, (k1, k2) -> k2));
            for (AgencyUserModel agencyUserModel : userModelList) {
                LoginName.put(agencyUserModel.getUserId(), agencyUserModel.getMobile() != null ? agencyUserModel.getMobile() : agencyUserModel.getLandlinePhone());
            }
        }
//        if(!CollectionUtils.isEmpty(deptList)){
//        String	dept = String.join(",", deptList);
//            List<LinkedHashMap> deptL = remoteSecurityService.listDepartmentByDeptIds(toke, product, appKey,dept);
//            if(deptL!=null&&deptL.size()>0){
//            	  //新安全
//            	content.forEach(s -> {
//            		deptL.forEach(s1 -> {
//                        if ((s.getDeptId()+"").equals(s1.get("sequenceNbr")+"")) {
//                            s.setDeptName(s1.get("departmentName")+"");
//                        }
//                    });
//
//                });
//            }
//        }
        //新安全
        content.forEach(s -> {
            StringBuffer buffer = new StringBuffer();
            if (s.getUserDept().indexOf("@") > 0) {
                String[] dept = s.getUserDept().split(",");
                Arrays.asList(dept).stream().forEach(x -> {
                    String[] deptTemp = x.split("@");
                    List<LinkedHashMap> deptL = remoteSecurityService.listDepartmentByDeptIds(toke, product, appKey, deptTemp[1]);
                    if (deptL.size() > 0) {
                        buffer.append(deptL.get(0).get("departmentName")).append(",");
                    } else {
                        buffer.append("其他").append(",");
                    }

                });
            } else {
                String[] deptTemp = s.getUserDept().split(",");
                List<LinkedHashMap> deptL = remoteSecurityService.listDepartmentByDeptIds(toke, product, appKey, deptTemp[1]);
                if (deptL.size() > 0) {
                    buffer.append(deptL.get(0).get("departmentName")).append(",");
                } else {
                    buffer.append("其他").append(",");
                }

            }
            s.setDeptName(buffer.substring(0, buffer.length() - 1));
        });
        Map<String, String> finalUserMap = userMap;
        content.forEach(c -> {
            StringBuilder userNames = new StringBuilder("");
            List<String> userIdsList = Arrays.asList(c.getUserName().split(","));
            for (String userId : userIdsList) {
                userNames.append(finalUserMap.get(userId));
                userNames.append(",");
            }
            c.setUserName(userNames.toString());
        });


        return content;
    }

    /**
     * startTime > stopTime 且 startTime 与 stopTime相差1小时内返回true
     * @param startTime
     * @param stopTime
     * @return
     */
    public static boolean getTimeDifference(LocalTime startTime, LocalTime stopTime) {
        int startSecond = startTime.getHour() * 3600 + startTime.getMinute() * 60 + startTime.getSecond();
        int stopSecond = stopTime.getHour() * 3600 + stopTime.getMinute() * 60 + stopTime.getSecond();
        BigDecimal bigDecimal = BigDecimal.valueOf((float) (startSecond - stopSecond) / 3600).setScale(3, BigDecimal.ROUND_HALF_UP);
        BigDecimal bigDecimal1 = new BigDecimal(1).setScale(3, BigDecimal.ROUND_HALF_UP);
        return bigDecimal.compareTo(bigDecimal1) <= 0 && bigDecimal.compareTo(new BigDecimal(0)) >= 0;
    }


    //bug 5980 待办任务消息应只触发执行中的任务，漏检的任务和未开始的任务不需要触发待办任务消息.
    @Override
    @Transactional
    public void taskMessage(String runDate) {
        SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss");
        //1.扫描plan表查询，需要生成执行数据的任务信息，无则return
        Date now = new Date();//今天
        String format = df.format(now);
        if (runDate != null) {//上送则已上送的为准
            runDate = runDate + " " + format;
            now = DateUtil.str2Date(runDate, "yyyyMMdd HH:mm:ss");
        }
        List<Plan> planIdsByDate = planTaskMapper.getPlanIdsByDate(now);
        List<PlanTask> planTaskList = planTaskMapper.getPlanTaskList(now);
        Map<Long, Plan> collect = planIdsByDate.stream().collect(Collectors.toMap(Plan::getId, t -> t));

        for (PlanTask planTask : planTaskList) {
            if (!redisUtils.hasKey(MAINTENANCE_PLAN_TASK_KEY + planTask.getId())) {
                try {
                    sendMessage(collect.get(planTask.getPlanId()), planTask);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                redisUtils.set(MAINTENANCE_PLAN_TASK_KEY + planTask.getId(), 1, (long) collect.get(planTask.getPlanId()).getDuration() * 60);
            }
        }
    }

    private void updateTaskStatus(Plan plan){
        Toke toke=  remoteSecurityService.getServerToken();
        RequestContext.setToken(toke.getToke());
        RequestContext.setProduct(toke.getProduct());
        RequestContext.setAppKey(toke.getAppKey());
        MessageModel model = new MessageModel();
        model.setRelationId(String.valueOf(plan.getId()));
        model.setMsgType("patrolSystem");
        model.setIsRead(true);
        log.info("修改待办任务参数-->{}", JSON.toJSON(model));
        Systemctl.messageClient.update(model);
    }

    /**
     * 自动任务执行
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void taskExecution(String runDate) {
        //1.扫描plan表查询，需要生成执行数据的任务信息，无则return
        Date now = new Date();//今天
        if (runDate != null) {//上送则已上送的为准
            now = DateUtil.str2Date(runDate, "yyyyMMdd");
        }
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        String strDate = df.format(now);
        String tomorrow = DateUtil.getIntervalDateStr(now, 1, "yyyy-MM-dd");//下一天
        List<Plan> planList = iplanDao.queryScheduledPlan(strDate, XJConstant.PLAN_STATUS_START);
        if (planList == null || planList.size() <= 0) {
            log.info(strDate + " " + " 暂无待生成执行数据的计划");
            return;
        }
        //2.循环遍历执行
        HashMap<String, Object> paramMap = new HashMap<String, Object>();
        for (Plan plan : planList) {
            if (StringUtils.isEmpty(plan.getUserId())) {
                continue;
            }
            paramMap.clear();
            paramMap.put("id", plan.getId());
            //2.1计划数据合法性校验
            Boolean fileFlag = PlanTaskUtil.checkMustFile(plan);
            if (!fileFlag) {
                paramMap.put("next_gen_date", tomorrow);
                planMapper.updPlanStatusOrGenDate(paramMap);//更新为明天
                continue;
            }
            //2.2.计算生成数据的日期区间
            CalDateVo vo = PlanTaskUtil.reGenPlanTaskData(plan, tomorrow, tomorrow);

            //计划未开始，则更新生成时间为明天
            if (null == vo) {
                paramMap.put("next_gen_date", tomorrow);
                planMapper.updPlanStatusOrGenDate(paramMap);//更新为明天
                continue;
            }
            //计划已过期,则更新status = 1,停用
            if (!vo.getIsGenData()) {
                paramMap.put("status", XJConstant.PLAN_STATUS_STOP);
                planMapper.updPlanStatusOrGenDate(paramMap);
                updateTaskStatus(plan);
                continue;
            }

            //2.3.执行数据生成（具体时间 + 人员）
            List<HashMap<String, Object>> list = genAllExeDate(plan, vo, XJConstant.SCHED_FLAG);

            if (XJConstant.UPD_PLAN_GEN_DATE.equals(vo.getUpdFlag())) {
                paramMap.put("next_gen_date", tomorrow);
                planMapper.updPlanStatusOrGenDate(paramMap);//更新为明天
                continue;
            } else if (XJConstant.UPD_PLAN_STATUS.equals(vo.getUpdFlag())) {
                paramMap.put("status", XJConstant.PLAN_STATUS_STOP);
                planMapper.updPlanStatusOrGenDate(paramMap);//更新status = 1,停用
                continue;
            }

            //2.4.删除今天可能重做生成的数据（计划重做后进行了计划的编辑）
            if (iplanTaskDao.findById(plan.getPlanTaskId()).isPresent() && plan.getFirstFlag() == XJConstant.PLAN_FIRST_STATUS_YES) {
                if (iplanTaskDao.existsById(plan.getPlanTaskId())) {
                    iplanTaskDao.deleteById(plan.getPlanTaskId());
                }
            }

            //2.5.插入planTask及planTaskDetail
            insertPlanTaskAndDet(list, plan, XJConstant.SCHED_FLAG, now);

        }
    }

    /**
     * 删除plantask及det
     *
     * @param param
     */
    public void deletePlanTaskAndDet(HashMap<String, Object> param) {
        param.put("beginDate", param.get("beginDate") + " " + "00:00:00");
        param.put("endDate", param.get("endDate") + " " + "23:59:59");
        List<Long> ids = planTaskMapper.getGenPlanTask(param);
        for (long id : ids) {
            iplanTaskDao.deleteById(id);
            ;
        }

    }

    /**
     * 执行数据生成
     *
     * @param plan
     * @param vo
     * @return
     */
    public List<HashMap<String, Object>> genAllExeDate(Plan plan, CalDateVo vo, String flag) {
        //1.生成前8位日期（yyyy-MM-dd）
        List<HashMap<String, Date>> list = PlanTaskUtil.genExeDate(plan, vo, flag);
        if (list == null || list.size() <= 0) {
            vo.setUpdFlag(XJConstant.UPD_PLAN_GEN_DATE);
            return null;
        }
        //2.生成完整时间（yyyy-MM-dd HH:mm:ss）
        List<HashMap<String, Object>> timeList = PlanTaskUtil.genWholeExeDate(list, plan);
        if (timeList == null || timeList.size() <= 0) {
            vo.setUpdFlag(XJConstant.UPD_PLAN_STATUS);
        }
        //3.生成含有人员信息的日期执行数据
        return PlanTaskUtil.genWholeExeData(timeList, plan);
    }


    /**
     * plantask及det入库
     *
     * @param list
     * @param plan
     * @param flag 是否初始状态0-初始 1-非初始
     */
    public void insertPlanTaskAndDet(List<HashMap<String, Object>> list, Plan plan, String flag, Date now) {
        if (list == null || list.size() <= 0) {
            HashMap<String, Object> paramMap = new HashMap<String, Object>();
            paramMap.put("id", plan.getId());
            paramMap.put("next_gen_date", DateUtil.formatDatrToStr(now, "yyyy-MM-dd"));
            // 更新下次任务生成日期
            planMapper.updPlanStatusOrGenDate(paramMap);
        }
        try {
            // 是否固定日期
            String isFixDate = plan.getIsFixedDate();
            List<Long> pointIdList = iRoutePointDao.queryRoutePointIds(plan.getRouteId());
            int pointNum = iRoutePointDao.countRoutePoint(plan.getRouteId());
            long batchNo = now.getTime();
            for (int i = 0; i < list.size(); i++) {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String startTime = list.get(i).get("BEGIN_TIME").toString();
                String endTime = list.get(i).get("END_TIME").toString();
                String userId = list.get(i).get("USER_ID") == null ? "-1" : list.get(i).get("USER_ID").toString();
                String userName = list.get(i).get("USER_NAME") == null ? "" : list.get(i).get("USER_NAME").toString();
                PlanTask planTask = iplanTaskDao.findByUserIdAndBeginTimeAndEndTimeAndPlanIdAndRouteId(userId, startTime, endTime, plan.getId(), plan.getRouteId());
                if (planTask != null) {
                    continue;
                }
                planTask = new PlanTask();
                planTask.setOrgCode(plan.getOrgCode());
                planTask.setUserName(userName);
                planTask.setPlanId(plan.getId());
                planTask.setBatchNo(batchNo);
                planTask.setCompanyId(plan.getCompanyId());
                planTask.setCompanyName(plan.getCompanyName());
                planTask.setRouteId(plan.getRouteId());
                planTask.setInOrder(plan.getInOrder());
                planTask.setUserId(userId);
                planTask.setPointNum(pointNum);
                if (XJConstant.FIX_DATE_NO.equals(isFixDate)) {
                    if (sdf.parse(startTime).getTime() <= now.getTime() && sdf.parse(endTime).getTime() >= now.getTime()) {
                        planTask.setFinishStatus(XJConstant.TASK_STATUS_DEAL);
                        planTask.setFinishNum(0);
                    } else {
                        if (sdf.parse(endTime).getTime() < now.getTime()) {
                            planTask.setFinishStatus(XJConstant.TASK_STATUS_TIMEOUT);
                            planTask.setFinishNum(0);
                        }
                    }
                } else {
                    if (sdf.parse(startTime).getTime() <= now.getTime() && sdf.parse(endTime).getTime() >= now.getTime()) {
                        planTask.setFinishStatus(XJConstant.TASK_STATUS_DEAL);
                        planTask.setFinishNum(0);
                    }
                    if (sdf.parse(endTime).getTime() < now.getTime()) {
                        planTask.setFinishStatus(XJConstant.TASK_STATUS_TIMEOUT);
                        planTask.setFinishNum(0);
                    }
                }
                if (XJConstant.CHECK_CHANGE_YES.equals(flag)) {
                    planTask.setFinishStatus(XJConstant.TASK_STATUS_FINISH);
                    planTask.setFinishNum(pointNum);
                }
                if (XJConstant.FIX_DATE_YES.equals(isFixDate) || (XJConstant.FIX_DATE_NO.equals(isFixDate)
                        && XJConstant.PLAN_TYPE_DAY.equals(plan.getPlanType()))) {
                    planTask.setCheckDate(list.get(i).get("BEGIN_TIME").toString().substring(0, 10));
                }
                planTask.setBeginTime(startTime);
                planTask.setEndTime(endTime);
                // 1.保存执行数据主表
                iplanTaskDao.saveAndFlush(planTask);
                long planId = planTask.getId();
                for (Number pointId : pointIdList) {
                    PlanTaskDetail planTaskDetailInstance = new PlanTaskDetail();
                    planTaskDetailInstance.setPointId(pointId.longValue());
                    planTaskDetailInstance.setTaskNo(planId);
                    planTaskDetailInstance.setStatus("0");
                    if (XJConstant.TASK_STATUS_TIMEOUT == planTask.getFinishStatus()) {
                        planTaskDetailInstance.setIsFinish(Integer.parseInt(XJConstant.PLAN_TASK_DET_FINISH_OUT));
                        planTaskDetailInstance.setStatus("3");
                    }
                    if (XJConstant.CHECK_CHANGE_YES.equals(flag)) {
                        planTaskDetailInstance.setIsFinish(Integer.parseInt(XJConstant.PLAN_TASK_DET_FINISH_YES));
                        planTaskDetailInstance.setStatus("1");
                    }
                    // 2.保存执行数据明细表
                    planTaskDetail.saveAndFlush(planTaskDetailInstance);
                }
                //bug 5980 待办任务消息应只触发执行中的任务，漏检的任务和未开始的任务不需要触发待办任务消息.
                //（重写定时任务去发送消息）
//                sendMessage(plan);
                // 定时任务监控
                jobService.planTaskAddJob(planTask);
            }

            // 3.如果为自动任务调用,则更新id，如果重做或且下次时间大于等于明天，则更新planTaskId到plan表 ,下次生成日期
            Date genDate = DateUtil.str2Date(list.get(list.size() - 1).get("NEXT_GEN_DATE").toString(), "yyyy-MM-dd");
            //明天
            Date tomorrow = DateUtil.getIntervalDate(now, 1);
            String strGenDate = list.get(list.size() - 1).get("NEXT_GEN_DATE").toString().substring(0, 10);
            HashMap<String, Object> paramMap = new HashMap<String, Object>();
            paramMap.put("id", plan.getId());
            paramMap.put("next_gen_date", strGenDate);
            if (XJConstant.SCHED_FLAG.equals(flag)) {
                //修改为初始值
                paramMap.put("plan_task_id", 0);
                paramMap.put("first_flag", XJConstant.PLAN_FIRST_STATUS_NO);
            } else if (genDate.getTime() - tomorrow.getTime() >= 0 && XJConstant.FIX_DATE_NO.equals(plan.getIsFixedDate())) {
                //更新日期及plantaskId到plan表
                long planTaskId = iplanTaskDao.findMaxIdByBatchNo(batchNo);
                // 更新新的任务id到plan
                paramMap.put("plan_task_id", planTaskId);
                paramMap.put("first_flag", XJConstant.PLAN_FIRST_STATUS_NO);
            }
            if (DateUtil.str2Date(strGenDate, "yyyy-MM-dd").getTime() - now.getTime() < 0 || org.apache.commons.lang.StringUtils.isBlank(strGenDate)) {
                paramMap.put("next_gen_date", DateUtil.formatDatrToStr(now, "yyyy-MM-dd"));
            }
            // 更新下次任务生成日期
            planMapper.updPlanStatusOrGenDate(paramMap);

        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }

    public void sendMessage(Plan plan, PlanTask planTask) throws Exception {
        // 查询检查对象对应防火监督负责人id
        List<String> extraUserIds = com.google.common.collect.Lists.newArrayList();
//
        log.info(String.format("计划对象：%s", JSON.toJSON(plan)));
/*        // 规则推送消息
        rulePlanService.addPlanRule(plan, null, RuleTypeEnum.消息型计划生成, extraUserIds);*/
        // NOTIFY
        String userIdString = planTask.getUserId();
        if (org.apache.commons.lang3.StringUtils.isNotBlank(userIdString)) {
            String[] userIdArr = userIdString.split(",");
            List<String> userIdList = Arrays.asList(userIdArr);
            // 规则推送消息
            try {
                if (CollectionUtils.isNotEmpty(userIdList)) {
                    ResponseModel<List<String>> amosOrgIdsByIds = jcsFeignClient.getAmosOrgIdsByIds(userIdList);
                    extraUserIds = amosOrgIdsByIds.getResult();
                }
            } catch (Exception e) {
                e.printStackTrace();
                log.error(e.getMessage(), e);
            }
            if (CollectionUtils.isNotEmpty(extraUserIds)) {
                log.info("接收人ID:{}", extraUserIds);
                rulePlanService.addPlanRule(plan, planTask, RuleTypeEnum.任务型计划生成, extraUserIds);
            }
        }

    }


    @Override
    public List<PlanTask> getPlanTaskByRouteId(Long routeId) {
        return planTaskMapper.getPlanTaskByRouteId(routeId);
    }

    @Override
    public void disablePlanTask(Long[] planTaskIds) {
        // planTask表中status字段置为1
        for (long planTaskId : planTaskIds) {
            List<PlanTask> planTaskList = getPlanTaskByRouteId(planTaskId);
            for (PlanTask planTask : planTaskList) {
                planTask.setStatus((byte) 1);
                iplanTaskDao.save(planTask);
            }
        }
    }


    @Override
    public Page<Map<String, Object>> getPlanTasks(Map<String, Object> params, CommonPageable pageParam) {
        List<Map<String, Object>> content = Lists.newArrayList();
        long total = planTaskMapper.getPlanTasksCount(params);
        if (total == 0) {
            return new PageImpl<>(content, pageParam, total);
        }
        params.put("offset", pageParam.getOffset());
        params.put("pageSize", pageParam.getPageSize());
        content = planTaskMapper.getPlanTasks(params);
        content.forEach(c -> {
            if (c.containsKey("finishStatus")) {
                String finishStatusDesc = PlanTaskFinishStatusEnum.getName(Integer.parseInt(c.get("finishStatus").toString()));
                c.put("finishStatusDesc", finishStatusDesc);
            }
        });
        return new PageImpl<>(content, pageParam, total);
    }

    @Override
    public List<Map<String, Object>> getPlanTaskPoints(Map<String, Object> param) {
        List<Map<String, Object>> result = planTaskMapper.getPlanTaskPoints(param);
        result.forEach(r -> {
            if (r.containsKey("isFinish")) {
                String isFinishDesc = PlanTaskDetailIsFinishEnum.getName(Integer.parseInt(r.get("isFinish").toString()));
                r.put("isFinishDesc", isFinishDesc);
            }
        });
        return result;
    }

    @Override
    public List<PlanTaskVo> getPlanTaskListByIds(String toke, String product, String appKey, Long[] ids) {
        List<PlanTaskVo> content = planTaskMapper.getPlanTaskListByIds(ids);

        String userIds = "";
        String deptIds = "";
        Set<String> set = new HashSet<>();
        Set<String> deptIdSet = new HashSet<>();
        Map<Long, Set<String>> deptMap = new HashMap<>();
        content.forEach(s -> {
            String userDept = s.getUserDept();
            if (!ValidationUtil.isEmpty(userDept)) {
                String[] udStrs = userDept.split(",");
                for (String udStr : udStrs) {
                    try {
                        String[] split = udStr.split("@");
                        set.add(split[0]);
                        if (split.length > 1) {
                            if (!"-1".equals(split[1])) {
                                deptIdSet.add(split[1]);
                            }
                            if (!deptMap.containsKey(s.getId())) {
                                deptMap.put(s.getId(), new HashSet<>());
                            }
                            deptMap.get(s.getId()).add(split[1]);
                        }
                    } catch (Exception e) {
                    }
                }
            }
        });
        List<String> userList = new ArrayList<>(set);
        List<String> deptList = new ArrayList<>(deptIdSet);

        Map<String, String> LoginName = new HashMap<>();
        Map<String, String> userMap = new HashMap<>();
        Map<String, String> depMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(userList)) {
            userIds = String.join(",", userList);
            List<AgencyUserModel> userModelList = remoteSecurityService.listUserByUserIds(toke, product, appKey, userIds);
            userMap = userModelList.stream().collect(Collectors.toMap(AgencyUserModel::getUserId, AgencyUserModel::getRealName, (k1, k2) -> k2));
            for (AgencyUserModel agencyUserModel : userModelList) {
                LoginName.put(agencyUserModel.getUserId(), agencyUserModel.getMobile() != null ? agencyUserModel.getMobile() : agencyUserModel.getLandlinePhone());
            }
        }
        if (!CollectionUtils.isEmpty(deptList)) {
            String dept = String.join(",", deptList);
            List<LinkedHashMap> deptL = remoteSecurityService.listDepartmentByDeptIds(toke, product, appKey, dept);
            if (deptL != null && deptL.size() > 0) {
                //新安全
                content.forEach(s -> {
                    Set<String> set1 = deptMap.get(s.getId());
                    if (!ValidationUtil.isEmpty(set1)) {
                        deptL.forEach(s1 -> {
                            if (set1.contains(s1.get("sequenceNbr"))) {
                                if (!ValidationUtil.isEmpty(s.getDeptName())) {
                                    s.setDeptName(s.getDeptName() + "," + s1.get("departmentName"));
                                } else {
                                    s.setDeptName(s1.get("departmentName").toString());
                                }
                            }
                        });
                        if (set1.contains("-1")) {
                            if (!ValidationUtil.isEmpty(s.getDeptName())) {
                                s.setDeptName(s.getDeptName() + "," + "其他");
                            } else {
                                s.setDeptName("其他");
                            }
                        }
                    }
                });
            }
        }
        Map<String, String> finalUserMap = userMap;
        content.forEach(c -> {
            StringBuilder userNames = new StringBuilder("");
            List<String> userIdsList = Arrays.asList(c.getUserName().split(","));
            for (String userId : userIdsList) {
                userNames.append(finalUserMap.get(userId));
                userNames.append(",");
            }
            c.setUserName(userNames.toString());
        });
        return content;
    }

    @Override
    public Page<CheckChkExListBo> getChkExList(String toke, String product, String appKey, CheckPtListPageParam param) {
        long total = planTaskMapper.countChkExListData(param);
        List<CheckChkExListBo> content = planTaskMapper.getChkExList(param);

        //获取用户联系方式
        String userIds = "";
        Set<String> set = new HashSet<>();
        content.forEach(s -> {
            if (s.getRealName() != null) {
                String[] sArr = s.getRealName().split(",");
                set.addAll(Arrays.asList(sArr));
            }
        });
        List<String> userList = new ArrayList<>(set);
        Map<String, AgencyUserModel> agencyUserModelMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(userList)) {
            userIds = String.join(",", userList);
            List<AgencyUserModel> userModelList = remoteSecurityService.listUserByUserIds(toke, product, appKey, userIds);
            agencyUserModelMap = userModelList.stream().collect(Collectors.toMap(AgencyUserModel::getUserId, Function.identity()));
        }
        for (CheckChkExListBo bo : content) {
            ArrayList<String> names = new ArrayList<>();
            ArrayList<String> mobiles = new ArrayList<>();
            String nameStrings = String.join(",", names);

            String[] realNames = bo.getRealName().split(",");
            if (realNames.length > 1) {
                System.out.println("asd");
            }
            for (int i = 0; i < realNames.length; i++) {
                if (agencyUserModelMap.containsKey(realNames[i])) {
                    AgencyUserModel agencyUserModel = agencyUserModelMap.get(realNames[i]);
                    names.add(agencyUserModel.getRealName());
                    if (StringUtil.isNotEmpty(agencyUserModel.getMobile())) {
                        mobiles.add(agencyUserModel.getMobile());
                    }
                }

            }
            bo.setRealName(String.join(",", names));
            if (mobiles.size() > 0) {
                bo.setLoginName(String.join(",", mobiles));
            }
        }
        Page<CheckChkExListBo> result = new PageImpl<CheckChkExListBo>(content, param, total);
        return result;
    }


    @Override
    public String getCumulativePlanCountByOrgCode(String loginOrgCode) {
        return planTaskMapper.getCumulativePlanCountByOrgCode(loginOrgCode);
    }


    @Override
    public PlanTask selectPlanTaskStatus(Long id) {
        // TODO Auto-generated method stub
        if (iplanTaskDao.existsById(id)) {
            return iplanTaskDao.findById(id).get();
        }
        return null;
    }

    @Override
    public void initPlanStatusOrGenDate() {
        planMapper.initUpdatePlanStatus();
        planMapper.initUpdatePlanNextGenDate();
    }


    @Override
    public Map<String, Object> planTaskPointDetail(String planTaskDetailId, String routePointId) {
        Map<String, Object> result = new LinkedHashMap<>();
        Optional<RoutePoint> rOp = iRoutePointDao.findById(Long.parseLong(routePointId));
        RoutePoint routePoint = rOp.orElseThrow(() -> new RuntimeException("计划清单不存在该点"));
        Point point = iPointDao.findById(routePoint.getPointId()).orElseThrow(() -> new RuntimeException("维保项不存在"));
        PlanTaskDetail planTaskDetail = iPlanTaskDetailDao.findById(Long.parseLong(planTaskDetailId)).orElseThrow(() -> new RuntimeException("任务不存在"));
        PlanTask planTask = iplanTaskDao.findById(planTaskDetail.getTaskNo()).orElseThrow(() -> new RuntimeException("主任务不存在"));
        Map<String, Object> facility = this.buildFacilityDetail(point, planTask);
        List<Map<String, Object>> itemList = this.buildCheckInputItem(routePointId);
        // 修复bug：6131
        CheckInput checkInput = checkInputDao.findByCheckId(Long.valueOf(planTaskDetailId));
        Map<String, Object> map = itemList.get(0);
        map.put("inputValue", ObjectUtils.isEmpty(checkInput) ? "" : checkInput.getInputValue());
        result.put("facility", facility);
        result.put("itemList", itemList);
        return result;
    }

    @Override
    public Boolean getByTaskDetailId(Long planTaskDetailId) {
        HashMap<String, Object> resultMap = new HashMap<>();
        PlanTaskDetail planTaskDetail = iPlanTaskDetailDao.findById(planTaskDetailId).orElseThrow(() -> new RuntimeException("任务不存在"));
        resultMap.put("isFinish", planTaskDetail.getIsFinish());
        PlanTask planTask = iplanTaskDao.findById(planTaskDetail.getTaskNo()).orElseThrow(() -> new RuntimeException("任务不存在"));
        return 0 == planTaskDetail.getIsFinish() && 1 == planTask.getFinishStatus();
    }

    private List<Map<String, Object>> buildCheckInputItem(String routePointId) {
        return inputItemMapper.queryInputItemInRountPoint(routePointId);
    }

    private Map<String, Object> buildFacilityDetail(Point point, PlanTask planTask) {
        Map<String, Object> facility = new LinkedHashMap<>();
        facility.put("name", point.getName());
        facility.put("pointId", point.getId());
        facility.put("pointNo", point.getPointNo());
        facility.put("position", point.getBuildingName() + point.getAddress());
        facility.put("userName", planTask.getUserName());
        facility.put("planTaskId", planTask.getId());
        facility.put("riskAndManage", point.getRemark());
        return facility;
    }
}
