package com.yeejoin.amos.patrol.quartz;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.yeejoin.amos.component.feign.config.InnerInvokException;
import com.yeejoin.amos.component.feign.model.FeignClientResult;
import com.yeejoin.amos.component.robot.AmosRequestContext;
import com.yeejoin.amos.feign.privilege.Privilege;
import com.yeejoin.amos.feign.privilege.model.AgencyUserModel;
import com.yeejoin.amos.feign.systemctl.Systemctl;
import com.yeejoin.amos.feign.systemctl.model.MessageModel;
import com.yeejoin.amos.patrol.business.bo.PlanTaskSyncBo;
import com.yeejoin.amos.patrol.business.constants.XJConstant;
import com.yeejoin.amos.patrol.business.dao.mapper.*;
import com.yeejoin.amos.patrol.business.dao.repository.*;
import com.yeejoin.amos.patrol.business.entity.mybatis.PlanTaskPointInputItemBo;
import com.yeejoin.amos.patrol.business.entity.mybatis.PointCheckDetailBo;
import com.yeejoin.amos.patrol.business.feign.JcsFeignClient;
import com.yeejoin.amos.patrol.business.param.CheckInputParam;
import com.yeejoin.amos.patrol.business.param.CheckRecordParam;
import com.yeejoin.amos.patrol.business.service.intfc.IMessageService;
import com.yeejoin.amos.patrol.business.service.intfc.IPatrolDataSyncService;
import com.yeejoin.amos.patrol.business.service.intfc.IPlanService;
import com.yeejoin.amos.patrol.business.util.DateUtil;
import com.yeejoin.amos.patrol.common.enums.*;
import com.yeejoin.amos.patrol.core.async.AsyncTask;
import com.yeejoin.amos.patrol.core.common.response.AppCheckInputRespone;
import com.yeejoin.amos.patrol.core.common.response.AppPointCheckRespone;
import com.yeejoin.amos.patrol.dao.entity.*;
import com.yeejoin.amos.patrol.feign.RemoteSecurityService;
import com.yeejoin.amos.patrol.mqtt.WebMqttComponent;
import org.quartz.Job;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.typroject.tyboot.core.foundation.context.RequestContext;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;

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

import static com.alibaba.fastjson.JSON.toJSONString;
import static com.yeejoin.amos.patrol.common.enums.NotifyBusinessTypeEum.planTask;

@Service("jobService")
@EnableAsync
public class JobService implements IJobService {

    private final Logger log = LoggerFactory.getLogger(JobService.class);

    @Autowired
    ESPlanTaskList esPlanTaskList;

    @Autowired
    IPlanService planService;

    @Autowired
    ESTaskDetail esTaskDetail;

    @Autowired
    private ITaskDao iTaskDao;

    @Autowired
    private IPlanTaskDao iPlanTaskDao;
    @Autowired
    private IPlanDao planDao;

    @Autowired
    private IPlanTaskDetailDao iPlanTaskDetailDao;

    @Autowired
    private IMessageService messageService;

    @Autowired
    private PlanTaskMapper planTaskMapper;

    @Autowired
    private MsgMapper msgMapper;

    @Autowired
    private ICheckDao iCheckDao;

    @Autowired
    private ICheckInputDao iCheckInputDao;

    @Autowired
    private AsyncTask asyncTask;

    @Autowired
    private IMsgDao iMsgDao;

    @Autowired
    private CheckMapper checkMapper;

    @Autowired
    private ITaskFeedbackDao taskFeedbackDao;

    @Autowired
    private IPatrolDataSyncService patrolDataSyncService;

    @Autowired
    private CheckInputMapper checkInputMapper;

    @Autowired
    private RemoteSecurityService remoteSecurityService;

    @Value("${amosRefresh.patrol.topic}")
    private String patrolTopic;
    @Autowired
    private WebMqttComponent webMqttComponent;

    @Autowired
    IInputItemDao inputItemDao;

    @Autowired
    IRoutePointDao iRoutePointDao;

    @Autowired
    AmosRequestContext amosRequestContext;

    @Autowired
    JcsFeignClient jcsFeignClient;

    private String P_STATIC_DAY = "p_static_day";

    private String P_STATIC_MONTH = "p_static_month";

    private String P_STATIC_WEEK = "p_static_week";

    @Override
    @Transactional
    public void initScheduler() {
        // TODO Auto-generated method stub
        log.debug("======================initScheduler===========================");
        initTaskJob();
        initPlanTaskJob();
//        initMsgJob();
    }

    @Override
    public void addJob(String name, String jobType, long id, Date time) {
        String jobName = name + "-" + jobType + "-" + id;
        if (time != null && time.getTime() > new Date().getTime()) {
            SimpleDateFormat formatter = new SimpleDateFormat("ss mm HH dd MM ? yyyy");
            String cronDate = formatter.format(time);
            log.error("addJob==jobName==" + jobName);

            QuartzManager.addJob(jobName, jobType, id, getJobInstance(name).getClass(), cronDate);
        }
    }

    /**
     * 初始化任务job
     */
    private void initTaskJob() {
        List<Task> taskList = iTaskDao.findAllByStatus(TaskStatusEnum.UNDERWAY.getValue());
        List<Task> updateTask = new ArrayList<Task>();
        taskList.forEach(task -> {
            Date finishTime = task.getFinishTime();
            if (finishTime != null) {
                if (finishTime.getTime() > new Date().getTime()) {
                    taskAddJob(task);
                } else {
                    task.setStatus(TaskStatusEnum.OVERTIME.getValue());
                    updateTask.add(task);
                }
            }
        });
        iTaskDao.saveAll(updateTask);
    }

    /**
     * 初始化计划执行job
     */
    private void initPlanTaskJob() {
        List<Integer> statusList = new ArrayList<Integer>();
        statusList.add(PlanTaskFinishStatusEnum.NOTSTARTED.getValue());
        statusList.add(PlanTaskFinishStatusEnum.UNDERWAY.getValue());
        List<PlanTask> planTaskList = planTaskMapper.getInitPlanTaskList();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        log.error("项目初始化执行开始添加定时任务监控========");
        boolean flag = false;

        for (PlanTask planTask : planTaskList) {
            try {
                Date beginTime = sdf.parse(planTask.getBeginTime());
                Date endTime = sdf.parse(planTask.getEndTime());
                long timestamp = new Date().getTime();
                List<String> ids = new ArrayList<>();
                if (PlanTaskFinishStatusEnum.NOTSTARTED.getValue() == planTask.getFinishStatus()) {
                    if (beginTime.getTime() > timestamp) {
                        planTaskAddJob(planTask);
                        log.error("项目初始化未开始监听器任务监控========");
                    } else if (beginTime.getTime() < timestamp && endTime.getTime() > timestamp) {
                        log.error("项目初始化进行中监听器任务监控========");
                        ids = planTaskMapper.selectPlanTaskIdList(planTask.getPlanId(), PlanTaskFinishStatusEnum.NOTSTARTED.getValue());
                        if (!ObjectUtils.isEmpty(ids)) {
                            flag = true;
                            if (ids.size() > 10000) {
                                int index = 10000;
                                for (int i = 0; i < ids.size(); i += 10000) {
                                    if (i + 10000 > ids.size()) {
                                        index = ids.size() - i;
                                    }
                                    List<String> newList = ids.subList(i, i + index);
                                    planTaskMapper.updatePlanTaskList(newList, PlanTaskFinishStatusEnum.UNDERWAY.getValue());
                                    updateEsPlanTaskList(newList, PlanTaskFinishStatusEnum.UNDERWAY.getValue(), "notApp", null);
                                }
                            } else {
                                planTaskMapper.updatePlanTaskList(ids, PlanTaskFinishStatusEnum.UNDERWAY.getValue());
                                updateEsPlanTaskList(ids, PlanTaskFinishStatusEnum.UNDERWAY.getValue(), "notApp", null);
                            }
                        }
                        planTaskAddJob(planTask);
                    } else if (endTime.getTime() < timestamp) {
                        flag = true;
                        log.error("修改为漏检生成记录========");
                        updatePlanTaskAndDetailStatus(planTask);
                    }
                } else {
                    if (endTime.getTime() < timestamp) {
                        log.error("项目初始化进行中监听器任务监控2222========");
                        ids = planTaskMapper.selectPlanTaskIdList(planTask.getPlanId(), PlanTaskFinishStatusEnum.NOTSTARTED.getValue());
                        if (!ObjectUtils.isEmpty(ids)) {
                            flag = true;
                            if (!ObjectUtils.isEmpty(ids)) {
                                if (ids.size() > 10000) {
                                    int index = 10000;
                                    for (int i = 0; i < ids.size(); i += 10000) {
                                        if (i + 10000 > ids.size()) {
                                            index = ids.size() - i;
                                        }
                                        List<String> newList = ids.subList(i, i + index);
                                        planTaskMapper.updatePlanTaskList(newList, PlanTaskFinishStatusEnum.UNDERWAY.getValue());
                                        updateEsPlanTaskList(newList, PlanTaskFinishStatusEnum.UNDERWAY.getValue(), "notApp", null);
                                    }
                                } else {
                                    planTaskMapper.updatePlanTaskList(ids, PlanTaskFinishStatusEnum.UNDERWAY.getValue());
                                    updateEsPlanTaskList(ids, PlanTaskFinishStatusEnum.UNDERWAY.getValue(), "notApp", null);
                                }
                            }
                        }
                        planTaskAddJob(planTask);
                    } else {
                        flag = true;
                        log.error("修改为漏检生成记录2222========");
                        updatePlanTaskAndDetailStatus(planTask);
                    }
                }
            } catch (ParseException e) {
                // TODO Auto-generated catch block
                log.info(e.getMessage());
                e.printStackTrace();
            }
        }
        // 重新更新统计表 -- 只更新当天统计的数据
        if (flag) {
            patrolDataSyncService.taskStatic(null);
        }
    }

    @Autowired
    PointMapper pointMapper;

    public void updateEsPlanTaskList(List<String> ids, int status, String isApp, CheckRecordParam requestParam) {
        String type = "save";
        if ("app".equals(isApp)) {
            type = "update";
        }
        List<ESPlanTaskListDto> esPlanTaskListDtos = new ArrayList<>();
        for (String id : ids) {
            ESPlanTaskListDto esPlanTaskListDto = esPlanTaskList.findById(id).get();
            esPlanTaskListDto.setFinishStatus(String.valueOf(status));
            Map task = planTaskMapper.queryPlanTaskById(Long.valueOf(id));
            esPlanTaskListDto.setFinshNum(ObjectUtils.isEmpty(task.get("finshNum")) ? "0" : task.get("finshNum").toString());
            esPlanTaskListDto.setOmission(ObjectUtils.isEmpty(task.get("omission")) ? "0" : task.get("omission").toString());
            esPlanTaskListDto.setUnqualified(ObjectUtils.isEmpty(task.get("unqualified")) ? "0" : task.get("unqualified").toString());
            esPlanTaskListDto.setUnplan(ObjectUtils.isEmpty(task.get("unplan")) ? "0" : task.get("unplan").toString());
            esPlanTaskListDto.setTaskPlanNum(ObjectUtils.isEmpty(task.get("taskPlanNum")) ? "0" : task.get("taskPlanNum").toString());
            List<PlanTaskDetail> planTaskDetailList = planTaskMapper.selectTaskDetails("('" + id + "')");
            Long routId = planTaskMapper.selectRoutId(id);
            List<ESTaskDetailDto> esTaskDetailDtos = new ArrayList<>();
            for (PlanTaskDetail taskDetail : planTaskDetailList) {
                AppPointCheckRespone appPointCheckRespone = planService.queryPointPlanTaskDetail(null, null, null, taskDetail.getTaskNo(), taskDetail.getPointId());
                ESTaskDetailDto esTaskDetailDto = esTaskDetail.findById(String.valueOf(appPointCheckRespone.getId())).get();
                JSONObject jsonObject = getCheckInput(routId, taskDetail.getPointId(), type, requestParam);
                esTaskDetailDto.setPointStatus((status == 0 || status == 1) ? "0" : status == 2 ? "1" : "2");
                esTaskDetailDto.setTaskStatus(String.valueOf(status));
                appPointCheckRespone.setAppCheckInput(jsonObject);
                esTaskDetailDto.setPointImgUrls(ObjectUtils.isEmpty(requestParam) ? new ArrayList<>() : requestParam.getCheckRecordImg());
                esTaskDetailDtos.add(esTaskDetailDto);
            }
            esTaskDetail.saveAll(esTaskDetailDtos);
            esPlanTaskListDto.setPoints(planTaskDetailList);
            esPlanTaskListDtos.add(esPlanTaskListDto);
        }
        esPlanTaskList.saveAll(esPlanTaskListDtos);
    }

    private void updatePlanTaskAndDetailStatus(PlanTask planTask) {
        List<String> esIds = planTaskMapper.selectPlanTaskIdLists(planTask.getPlanId(), PlanTaskFinishStatusEnum.UNDERWAY.getValue(), PlanTaskFinishStatusEnum.NOTSTARTED.getValue());
        if (esIds.size() > 0) {
            if (esIds.size() > 10000) {
                int index = 10000;
                for (int i = 0; i < esIds.size(); i += 10000) {
                    if (i + 10000 > esIds.size()) {
                        index = esIds.size() - i;
                    }
                    List<String> newList = esIds.subList(i, i + index);
                    planTaskMapper.updatePlanTaskList(newList, PlanTaskFinishStatusEnum.OVERTIME.getValue());
                    updateEsPlanTaskList(newList, PlanTaskFinishStatusEnum.OVERTIME.getValue(), "notApp", null);
                    List<PlanTask> planTaskList = planTaskMapper.selectTaskList(newList);
                    if (!ObjectUtils.isEmpty(planTaskList)) {
                        for (PlanTask task : planTaskList) {
                            createOmissionCheckRecord(task);
                        }
                    }
                }
            } else {
                planTaskMapper.updatePlanTaskList(esIds, PlanTaskFinishStatusEnum.OVERTIME.getValue());
                updateEsPlanTaskList(esIds, PlanTaskFinishStatusEnum.OVERTIME.getValue(), "notApp", null);
                List<PlanTask> planTaskList = planTaskMapper.selectTaskList(esIds);
                if (!ObjectUtils.isEmpty(planTaskList)) {
                    for (PlanTask task : planTaskList) {
                        createOmissionCheckRecord(task);
                    }
                }
            }
            List<Long> ids = new ArrayList<>();
            ids.add(planTask.getId());
            if (!ValidationUtil.isEmpty(ids)) {
                planTaskMapper.updatePlanTaskDetailsByPlanId(ids);
            }
        }
    }

    private void initMsgJob() {
        List<Msg> msgList = iMsgDao.findAllByIsImmediatelyTrueAndStatus(0);
        if (!msgList.isEmpty()) {
            msgList.forEach(msg -> {
                addJob("msg", XJConstant.MESSAGE_PUSH, msg.getId(), msg.getFixedTime());
            });
        }
    }

    private void updatePlanTaskStatus(PlanTask planTask, int status) {
        planTask.setFinishStatus(status);
        iPlanTaskDao.save(planTask);
        List<PlanTaskDetail> planTaskDetails = iPlanTaskDetailDao.findAllByTaskNoAndStatus(planTask.getId(), PlanTaskDetailStatusEnum.NOTSTARTED.getValue());
        if (!planTaskDetails.isEmpty()) {
            planTaskDetails.stream().forEach(action -> {
                action.setIsFinish(PlanTaskDetailIsFinishEnum.OVERTIME.getValue());
                action.setStatus(PlanTaskDetailStatusEnum.OMISSION.getValue());
                iPlanTaskDetailDao.saveAndFlush(action);
            });
        }
        log.info("更新plan_task 和 plan_task_detail表完成，planTask:{}", planTask);
//        //  巡检站端与中心级数据同步
//        TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
//            @Override
//            public void afterCommit() {
//                // 事物提交后业务逻辑
//                patrolDataSyncService.planTaskDetailDataSync(planTaskDetails);
//            }
//        });
        if (PlanTaskFinishStatusEnum.OVERTIME.getValue() == status) {
            createOmissionCheckRecord(planTask);
        }
    }

    private void updateTaskStatus(Plan plan) {
        RequestContext.setToken(amosRequestContext.getToken());
        RequestContext.setProduct(amosRequestContext.getProduct());
        RequestContext.setAppKey(amosRequestContext.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);
    }


    /**
     * 创建漏检检查记录
     *
     * @param planTask
     */
    private void createOmissionCheckRecord(PlanTask planTask) {
        List<PlanTaskPointInputItemBo> planTaskPointInputItems = planTaskMapper.getPlanTaskPointInputItemByPlanTaskId(planTask.getId(), PlanTaskDetailStatusEnum.OMISSION.getValue());
        Map<Long, Check> checkMap = new HashMap<>();
        Set<Long> checkIds = new HashSet<Long>();
        Map<String, String> deptMap = new HashMap<>();
        StringBuffer deptName = new StringBuffer();
        StringBuffer deptId = new StringBuffer();
        StringBuffer userName = new StringBuffer();
        if (planTask.getUserDept().indexOf(",") > 0) {
            List<String> ids = Arrays.asList(planTask.getUserId().split(","));
            List<String> depts = Arrays.asList(planTask.getUserDept().split(","));
            depts.stream().forEach(dept -> {
                deptMap.put(dept.split("@")[0], dept.split("@")[2]);
                deptName.append(dept.split("@")[2]).append(",");
                deptId.append(dept.split("@")[0]).append(",");
            });
            Set<String> departmentOrgCode = new HashSet<>();
            for (String key : deptMap.keySet()) {
                departmentOrgCode.add(deptMap.get(key));
            }
            StringBuffer deptIds = new StringBuffer();
            Iterator it = departmentOrgCode.iterator();
            while (it.hasNext()) {
                deptIds.append(it.next()).append(",");
            }

            String realNames = "";

        }

        List<Check> checkList = new ArrayList<>();
        List<Long> checkInputIdList = new ArrayList<>();
        for (PlanTaskPointInputItemBo arg : planTaskPointInputItems) {
            Check check = new Check();
            if (checkMap.get(arg.getPointId()) == null) {
                check.setOrgCode(arg.getOrgCode());
                check.setUserId(planTask.getUserId());
                int len = userName.toString().indexOf(",");
                if (len != -1) {
                    check.setUserName(userName.toString());
                } else {
                    check.setUserName(userName.toString());
                }
                // check.setDepId(deptId.toString().substring(0, deptId.length() - 1));
                check.setDepName(deptName.toString());
                check.setPointId(arg.getPointId());

                check.setPointName(arg.getPointName());
                check.setRouteName(arg.getRouteName());
                check.setPlanName(arg.getPlanName());
                check.setErrorClassify(arg.getClassifyName());

                check.setUploadTime(new Date());
                check.setPlanId(arg.getPlanId());
                check.setPlanTaskId(arg.getPlanTaskId());
                check.setPlanTaskDetailId(arg.getPlanTaskDetailId());
                check.setRouteId(arg.getRouteId());
                check.setCheckTime(arg.getEndTime());
                check.setIsOk(CheckStatusEnum.OMISSION.getCode());
                try {
                    check = iCheckDao.save(check);
                } catch (InnerInvokException e) {
                    e.printStackTrace();
                }
                iCheckDao.flush();
                checkList.add(check);
                checkMap.put(arg.getPointId(), check);
                checkIds.add(check.getId());
            } else {
                check = checkMap.get(arg.getPointId());
            }
            if (arg.getInputItemId() != null) {
                CheckInput checkInput = new CheckInput();
                checkInput.setCheckId(check.getId());
                checkInput.setInputId(arg.getInputItemId());
                checkInput.setIsOk(CheckStatusEnum.OMISSION.getCode());
                checkInput.setRoutePointItemId(arg.getRoutePointItemId());
                checkInput.setOrderNo(arg.getOrderNo());
                checkInput.setOrgCode(arg.getOrgCode());
                checkInput.setInputName(arg.getInputName());
                checkInput.setPointClassifyId(arg.getClassifyId());
                checkInput.setPointClassifyName(arg.getClassifyName());
                CheckInput checkInput1 = iCheckInputDao.saveAndFlush(checkInput);
                checkInputIdList.add(checkInput1.getId());
            }
        }

    }

    public JSONObject getCheckInput(Long routeId, Long pointId, String type, CheckRecordParam requestParam) {

        List<AppCheckInputRespone> appCheckInputResponeList = new ArrayList<AppCheckInputRespone>();
        List<PointCheckDetailBo> pointInputs = planTaskMapper.getPointInputByRouteIdAndPointId(routeId, pointId);
        JSONObject appResponeMap = new JSONObject();
        pointInputs.forEach(action -> {
            AppCheckInputRespone input = new AppCheckInputRespone();

            if ("save".equals(type)) {
                input.setInputValue(null);
                input.setPointInputImgUrls(new ArrayList<>());
            } else {
                InputItem inputItem = inputItemDao.findById(action.getInputItemId()).get();
                CheckInput checkInput = new CheckInput();

                if (!ValidationUtil.isEmpty(requestParam)) {
                    List<CheckInputParam> checkItems = requestParam.getCheckItems();
                    for (CheckInputParam x : checkItems) {
                        if (x.getInputItemId() == action.getInputItemId()) {
                            input.setInputValue(x.getInputValue());
                            break;
                        }
                    }
                } else {
                    if (XJConstant.INPUT_ITEM_SELECT.equals(inputItem.getItemType())) {
                        checkInput = paraseSelect(checkInput, inputItem.getDataJson(), inputItem.getIsScore());
                        input = JSONObject.parseObject(toJSONString(checkInput),
                                AppCheckInputRespone.class);
                    } else if (XJConstant.INPUT_ITEM_NUMBER.equals(inputItem.getItemType())) {
                        input.setInputValue(inputItem.getDefaultValue());
                    } else if (XJConstant.INPUT_ITEM_TEXT.equals(inputItem.getItemType())) {
                        input.setInputValue(inputItem.getDefaultValue());
                    }
                }

                if (!ObjectUtils.isEmpty(requestParam)) {
                    List<CheckInputParam> checkItems = requestParam.getCheckItems();
                    for (CheckInputParam x : checkItems) {
                        if (x.getInputItemId() == action.getInputItemId()) {
                            if (x.getCheckInputImg() != null && x.getCheckInputImg().size() > 0) {
                                input.setPointInputImgUrls(x.getCheckInputImg());
                            } else {
                                input.setPointInputImgUrls(new ArrayList<>());
                            }
                        }
                    }
                }
            }

            input.setInputName(action.getInputName());
            input.setCheckInputId(action.getCheckInputId());
            input.setDefaultValue(action.getDefaultValue());
            input.setDataJson(action.getDataJson());
            input.setIsMultiline(action.getIsMultiline());
            input.setIsMust(action.getIsMust());

            input.setItemType(action.getItemType());
            input.setOrderNo(action.getOrderNo());
            input.setPictureJson(action.getPictureJson());
            input.setClassifyId(action.getClassifyId());
            input.setClassifyName(action.getClassifyName());
            appCheckInputResponeList.add(input);
        });
        appResponeMap.put("items", appCheckInputResponeList);
        return appResponeMap;
    }

    /**
     * 创建检查记录
     *
     * @param planTask
     */
    public void createCheckRecord(PlanTask planTask, String userId) {
        List<PlanTaskPointInputItemBo> planTaskPointInputItems = planTaskMapper.getPlanTaskPointInputItemByPlanTaskId(planTask.getId(), PlanTaskDetailStatusEnum.QUALIFIED.getValue());
        Map<Long, Check> checkMap = new HashMap<>();
        Map<String, String> deptMap = new HashMap<>();
        StringBuffer deptName = new StringBuffer();
        StringBuffer deptId = new StringBuffer();
        StringBuffer userName = new StringBuffer();
        if (planTask.getUserDept().indexOf(",") > 0) {
            List<String> depts = Arrays.asList(planTask.getUserDept().split(","));
            depts.stream().forEach(dept -> {
                deptMap.put(dept.split("@")[0], dept.split("@")[2]);
                deptName.append(dept.split("@")[2]).append(",");
                deptId.append(dept.split("@")[0]).append(",");
            });
            Set<String> departmentOrgCode = new HashSet<>();
            for (String key : deptMap.keySet()) {
                departmentOrgCode.add(deptMap.get(key));
            }
            StringBuffer deptIds = new StringBuffer();
            Iterator it = departmentOrgCode.iterator();
            while (it.hasNext()) {
                deptIds.append(it.next()).append(",");
            }

            String realNames = "";
            FeignClientResult<AgencyUserModel> agencyUserModelsDate = Privilege.agencyUserClient.queryByUserId(userId);
            AgencyUserModel agencyUserModel = agencyUserModelsDate.getResult();

            if (agencyUserModel != null) {
                realNames = agencyUserModel.getRealName().join(",");
                userName.append(realNames);
            }
        }
        for (PlanTaskPointInputItemBo arg : planTaskPointInputItems) {
            Check check = new Check();
            if (checkMap.get(arg.getPointId()) == null) {
                check.setOrgCode(arg.getOrgCode());
                check.setUserId(planTask.getUserId());
                int len = userName.toString().indexOf(",");
                if (len != -1) {
                    check.setUserName(userName.toString());
                } else {
                    check.setUserName(userName.toString());
                }

                check.setDepName(deptName.toString());
                check.setPointId(arg.getPointId());

                check.setPointName(arg.getPointName());
                check.setRouteName(arg.getRouteName());
                check.setPlanName(arg.getPlanName());
                check.setErrorClassify(arg.getClassifyName());

                check.setUploadTime(new Date());
                check.setPlanId(arg.getPlanId());
                check.setPlanTaskId(arg.getPlanTaskId());
                check.setPlanTaskDetailId(arg.getPlanTaskDetailId());
                check.setRouteId(arg.getRouteId());
                check.setCheckTime(arg.getEndTime());
                check.setIsOk(CheckStatusEnum.QUALIFIED.getCode());
                try {
                    check = iCheckDao.save(check);
                } catch (InnerInvokException e) {
                    e.printStackTrace();
                }
                iCheckDao.flush();
                checkMap.put(arg.getPointId(), check);
            } else {
                check = checkMap.get(arg.getPointId());
            }
            if (arg.getInputItemId() != null) {

                InputItem inputItem = inputItemDao.findById(arg.getInputItemId()).get();
                CheckInput checkInput = new CheckInput();

                if (XJConstant.INPUT_ITEM_SELECT.equals(inputItem.getItemType())) {
                    checkInput = paraseSelect(checkInput, inputItem.getDataJson(), inputItem.getIsScore());
                } else if (XJConstant.INPUT_ITEM_NUMBER.equals(inputItem.getItemType())) {
                    checkInput.setInputValue(inputItem.getDefaultValue());
                } else if (XJConstant.INPUT_ITEM_TEXT.equals(inputItem.getItemType())) {
                    checkInput.setInputValue(inputItem.getDefaultValue());
                }

                checkInput.setCheckId(check.getId());
                checkInput.setInputId(arg.getInputItemId());
                checkInput.setIsOk(CheckStatusEnum.QUALIFIED.getCode());
                checkInput.setRoutePointItemId(arg.getRoutePointItemId());
                checkInput.setOrderNo(arg.getOrderNo());
                checkInput.setOrgCode(arg.getOrgCode());
                checkInput.setInputName(arg.getInputName());
                checkInput.setPointClassifyId(arg.getClassifyId());
                checkInput.setPointClassifyName(arg.getClassifyName());
                iCheckInputDao.saveAndFlush(checkInput);
            }

        }


    }

    private CheckInput paraseSelect(CheckInput checkInput, String json, String isScore) {
        JSONArray jsonArray = JSONArray.parseArray(json);
        if (!ObjectUtils.isEmpty(jsonArray)) {
            for (int i = 0; i < jsonArray.size(); i++) {
                JSONObject jsonObject = jsonArray.getJSONObject(i);
                String validateName = jsonObject.getString("name");
                String validateIsOk = jsonObject.getString("isOk");
                if (validateIsOk.equals("是")) {
                    checkInput.setInputValue(validateName);
                }
            }
        }
        return checkInput;
    }

    private void removeJob(String jobName) {
        log.debug("removeJob==jobName==" + jobName);
        QuartzManager.removeJob(jobName);
    }

    private Job getJobInstance(String type) {
        switch (type) {
            case "planTask":
                return new PlanTaskJobService();
            case "task":
                return new TaskJobService();
            case "msg":
                return new MsgJobService();
            default:
                return null;
        }
    }

    @Override
    public void taskAddJob(Task task) {
        // TODO Auto-generated method stub
        long taskId = task.getId();
        if (XJConstant.TASK_WARN.equals(task.getIsWarn())) { // 设置为接受报警执行代码
            Date alarmDate = task.getWarnTime();
            addJob("task", XJConstant.MESSAGE_PUSH, taskId, alarmDate);
        }
        addJob("task", XJConstant.STATUS_MONITOR_END, taskId, task.getFinishTime());

    }

    @Override
    @Transactional
    public void taskJobPerform(long taskId, String jobType, String jobName) {
        // TODO Auto-generated method stub
        log.error("开始执行定时任务========");

        if (iTaskDao.existsById(taskId)) {
            Task task = iTaskDao.findById(taskId).get();
            if (XJConstant.STATUS_MONITOR_END.equals(jobType)) {
                if (TaskStatusEnum.UNDERWAY.getValue() == task.getStatus()) {
                    task.setStatus(TaskStatusEnum.OVERTIME.getValue());
                    iTaskDao.saveAndFlush(task);
                    TaskFeedback taskFeedback = new TaskFeedback();
                    taskFeedback.setUserId(task.getExecutorId());
                    taskFeedback.setMessage("该任务在规定时间内未完成，请核实信息！任务名称： " + task.getTitle() + " 要求完成时间：  " + DateUtil.getDateFormat(task.getFinishTime(), "yyyy-MM-dd HH:mm:ss") + " 发起人：" + task.getPublisherName() + " 执行人：" + task.getExecutor());
                    taskFeedback.setCreateDate(new Date());
                    taskFeedback.setUserName(task.getExecutor());
                    taskFeedback.setFeedbackTime(new Date());
                    taskFeedback.setOrgCode(task.getOrgCode());
                    taskFeedback.setTaskId(task.getId());
                    taskFeedback.setMessageType(TaskStatusEnum.OVERTIME.getName());
                    taskFeedback = taskFeedbackDao.save(taskFeedback);
                    try {
                        asyncTask.pushTaskDetailInfoTo3D(amosRequestContext.getToken(), amosRequestContext.getProduct(), amosRequestContext.getAppKey(), taskId); // 超时任务向3D推送
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        log.error(e.getMessage(), e);
                        e.printStackTrace();
                    }
                }
            } else {
                messageService.pushTaskMessage(amosRequestContext.getToken(), amosRequestContext.getProduct(), amosRequestContext.getAppKey(), task);
            }
        }
        removeJob(jobName);
    }

    @Override
    public void planTaskAddJob(PlanTask planTask) {
        // TODO Auto-generated method stub
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date endTime = sdf.parse(planTask.getEndTime());
            Date beginTime = sdf.parse(planTask.getBeginTime());
            if (PlanTaskFinishStatusEnum.OVERTIME.getValue() != planTask.getFinishStatus()) {

                // 添加状态监控定时

                int status = planTask.getFinishStatus();
                if (PlanTaskFinishStatusEnum.NOTSTARTED.getValue() == status) {
                    addJob("planTask", XJConstant.STATUS_MONITOR_START, planTask.getPlanId(), beginTime);// 添加监控任务开始时间定时任务
                }
                if (PlanTaskFinishStatusEnum.NOTSTARTED.getValue() == status || PlanTaskFinishStatusEnum.UNDERWAY.getValue() == status) {
                    addJob("planTask", XJConstant.STATUS_MONITOR_END, planTask.getPlanId(), endTime);// 添加监控任务开始结束定时任务
                }

//                // 查询需要推送消息提醒
//                List<MsgConfigParam> configParam = msgMapper.getPlanTaskMsgConfigByUserIdAndStatus(planTask.getUserId().split(","), "True");
//                if (!configParam.isEmpty()) {
//                    configParam.forEach(config -> {
//                        String jobType = "";
//                        Date time = new Date();
//                        int minute = Integer.valueOf(config.getValue());
//                        long tempTime = minute * 60 * 1000;
//                        if (MsgSubscribeTypeEnum.PLANWARN.getName().equals(config.getMsgType())) {
//                            time = new Date(beginTime.getTime() - tempTime);
//                            jobType = XJConstant.PLAN_TASK_WARN_MSG_PUSH + "-" + config.getUserId();
//                        } else if (MsgSubscribeTypeEnum.PLANBEGIN.getName().equals(config.getMsgType())) {
//                            time = new Date(beginTime.getTime() + tempTime);
//                            jobType = XJConstant.PLAN_TASK_BEGIN_MSG_PUSH + "-" + config.getUserId();
//                        } else if (MsgSubscribeTypeEnum.PLANEND.getName().equals(config.getMsgType())) {
//                            time = new Date(endTime.getTime() + tempTime);
//                            jobType = XJConstant.PLAN_TASK_END_MSG_PUSH + "-" + config.getUserId();
//                        }
//                        addJob("planTask", jobType, planTask.getId(), time);
//                    });
//                }

            } else {
                updatePlanTaskStatus(planTask, PlanTaskFinishStatusEnum.OVERTIME.getValue());
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            e.printStackTrace();
        }
    }

    @Override
    @Transactional
    public void planTaskJobPerform(long planId, String jobType, String jobName) {

        if (planDao.existsById(planId)) {
            List<Long> notStartPlanTaskList = planTaskMapper.getPlanTaskListByPlanId(planId, PlanTaskFinishStatusEnum.NOTSTARTED.getValue());
            List<Long> StartPlanTaskList = planTaskMapper.getPlanTaskListByPlanId(planId, PlanTaskFinishStatusEnum.UNDERWAY.getValue());
            List<PlanTask> planTaskList = planTaskMapper.getPlanTaskTListByPlanId(planId, PlanTaskFinishStatusEnum.UNDERWAY.getValue());

            List<String> notStartPlanTaskStringList = notStartPlanTaskList.stream()
                    .map(Object::toString)
                    .collect(Collectors.toList());

            List<String> StartPlanTaskStringList = StartPlanTaskList.stream()
                    .map(Object::toString)
                    .collect(Collectors.toList());

            log.error("开始执行定时任务添加的任务==========>>{}", JSON.toJSONString(planTask));
            if (XJConstant.STATUS_MONITOR_START.equals(jobType)) {
                if (!ValidationUtil.isEmpty(notStartPlanTaskList)) {
                    planTaskMapper.updatePlanTaskByPlanId(notStartPlanTaskList, PlanTaskFinishStatusEnum.UNDERWAY.getValue());
                    updateEsPlanTaskList(notStartPlanTaskStringList, PlanTaskFinishStatusEnum.UNDERWAY.getValue(), "notApp", null);
                    patrolDataSyncService.taskStatic(null);
                }
            } else if (XJConstant.STATUS_MONITOR_END.equals(jobType)) {
                if (!ValidationUtil.isEmpty(StartPlanTaskList)) {
                    planTaskMapper.updatePlanTaskByPlanId(StartPlanTaskList, PlanTaskFinishStatusEnum.OVERTIME.getValue());
                    planTaskMapper.updatePlanTaskDetailsByPlanId(StartPlanTaskList);
                    updateEsPlanTaskList(StartPlanTaskStringList, PlanTaskFinishStatusEnum.OVERTIME.getValue(), "notApp", null);
                    patrolDataSyncService.taskStatic(null);
                    for (PlanTask planTask : planTaskList
                    ) {
                        createOmissionCheckRecord(planTask);
                    }
//                    iPlanTaskDao.updatePlanTaskDetailFinishStatus(collect,PlanTaskFinishStatusEnum.UNDERWAY.getValue());
//                    updatePlanTaskStatus(planTask, PlanTaskFinishStatusEnum.OVERTIME.getValue());
                }
            }
        }
        removeJob(jobName);
    }

    public PlanTaskSyncBo buildPlanTaskBo(PlanTask planTask) {
        PlanTaskSyncBo taskSyncBo = new PlanTaskSyncBo();
        BeanUtils.copyProperties(planTask, taskSyncBo);
        return taskSyncBo;
    }

    public String buildSyncMessage(String topic, Object object) {
        Map<String, Object> map = new HashMap<>();
        map.put("topic", topic);
        map.put("data", object);
        return JSON.toJSONString(map, SerializerFeature.WriteMapNullValue);
    }

    @Override
    public void msgAddJob(Msg msg) {
        addJob("msg", XJConstant.MESSAGE_PUSH, msg.getId(), msg.getFixedTime());
    }

    @Override
    public void msgJobPerform(long msgId, String jobType, String jobName) {
        if (iMsgDao.existsById(msgId)) {
            Msg msg = iMsgDao.findById(msgId).get();
            messageService.pushMsgAndSave(amosRequestContext.getToken(), amosRequestContext.getProduct(), amosRequestContext.getAppKey(), msg);
        }
        removeJob(jobName);
    }

}
