package com.mvc.service.taizhang;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.mvc.dao.TaskBatchRemoteMapper;
import com.mvc.entity.TaskBatchRemote;
import com.mvc.entity.TaskBatchRemoteExample;
import com.mvc.entity.TaskRemoteCfg;
import com.mvc.model.*;
import com.mvc.service.copy.TCheckService;
import com.mvc.utils.StringUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Transactional
public class TaskBatchRemoteService {

    @Resource
    private TaskBatchRemoteMapper taskBatchRemoteMapper;

    @Resource
    private TaskBatchRemoteDetailService taskBatchRemoteDetailService;

    @Resource
    private TaskRemoteCfgService taskRemoteCfgService;

    @Resource
    private TCheckService tCheckService;

    @Resource
    private TStkinService tStkinService;

    @Resource
    private TStkoutService tStkoutService;

    @Resource
    private TTaskDownService tTaskDownService;

    @Resource
    private DeviceAccService deviceAccService;

    public Map<String, Object> findAllTaskBatchRemote(TaskBatchRemoteModel queryModel) {
        TaskBatchRemoteExample example = new TaskBatchRemoteExample();
        TaskBatchRemoteExample.Criteria criteria = example.createCriteria();

        if (StringUtils.isNotEmpty(queryModel.getTaskDescribe())) {//任务描述模糊查询
            criteria.andTaskDescribeLike("%" + queryModel.getTaskDescribe() + "%");
        }

        if (StringUtils.isNotEmpty(queryModel.getFinishedFlag())) {//完成状态
            criteria.andFinishedFlagEqualTo(queryModel.getFinishedFlag());
        }

        if (StringUtils.isNotEmpty(queryModel.getCreateMan())) {//创建人
            criteria.andCreateManEqualTo(queryModel.getCreateMan());
        }

        example.setOrderByClause("CREATE_TIME desc");
        Map<String, Object> resMap = new HashMap<>();
        Page<Object> pageObject = PageHelper.startPage(queryModel.getPage(), queryModel.getRows());
        List<TaskBatchRemote> TaskBatchRemotes = taskBatchRemoteMapper.selectByExample(example);
        List<TaskBatchRemoteModel> resList = new ArrayList<>();
        for (TaskBatchRemote TaskBatchRemote : TaskBatchRemotes) {
            TaskBatchRemoteModel model = new TaskBatchRemoteModel();
            BeanUtils.copyProperties(TaskBatchRemote, model);

            List<TaskBatchRemoteDetailModel> details = taskBatchRemoteDetailService.findTaskBatchRemoteDetailByTaskBatchId(model.getTaskBatchId());
            model.setDetailModels(details);

            TaskRemoteCfgModel cfgModel = taskRemoteCfgService.findTaskRemoteCfg_Batch(model.getTaskBatchId());
            model.setTaskRemoteCfgModel(cfgModel);
            resList.add(model);
        }
        resMap.put("total", pageObject.getTotal());
        resMap.put("list", resList);
        return resMap;
    }

    public TaskBatchRemoteModel saveTaskBatchRemote(TaskBatchRemoteModel model) {
        model.setTaskBatchId(StringUtil.getUuid());
        model.setFinishedFlag("0");
        Date nowTime = new Date();
        model.setCreateTime(nowTime);
//        if(model.getMinutesAhead()==null){//默认3分钟
//            model.setMinutesAhead(3);
//        }
        TaskBatchRemote taskBatchRemote = new TaskBatchRemote();
        BeanUtils.copyProperties(model, taskBatchRemote);
        if (taskBatchRemoteMapper.insert(taskBatchRemote) > 0) {
            model.setId(taskBatchRemote.getId());

            //保存配置项到配置任务表
            model.getTaskRemoteCfgModel().setTaskId(taskBatchRemote.getTaskBatchId());
            taskRemoteCfgService.saveTaskRemoteCfg_Batch(model.getTaskRemoteCfgModel());

            //保存明细
            for (TaskBatchRemoteDetailModel detailModel : model.getDetailModels()) {
                if (StringUtils.isNotEmpty(detailModel.getDeviceSn())) {
                    detailModel.setTaskBatchId(taskBatchRemote.getTaskBatchId());
                    taskBatchRemoteDetailService.saveTaskBatchRemoteDetail(detailModel);
                }
            }

            updateSourceRecord(taskBatchRemote, 0);

            //配置是当前日期,马上执行启动检测任务 2022-11-13 guozhao
            if (nowTime.compareTo(model.getExecutionTime()) > -1) {
                executeTaskBatchRemote();
            }
        }

        return model;
    }

    public TaskBatchRemoteModel updateTaskBatchRemote(TaskBatchRemoteModel model) {
        TaskBatchRemote TaskBatchRemote = taskBatchRemoteMapper.selectByPrimaryKey(model.getId());
        BeanUtils.copyProperties(model, TaskBatchRemote);
        int i = taskBatchRemoteMapper.updateByPrimaryKey(TaskBatchRemote);

        if (model.getTaskRemoteCfgModel() != null) {
            taskRemoteCfgService.updateTaskRemoteCfg(model.getTaskRemoteCfgModel());
        }
        return model;
    }

    public int deleteTaskBatchRemote(int id) {
        TaskBatchRemote taskBatchRemote = taskBatchRemoteMapper.selectByPrimaryKey(id);
        if (taskBatchRemote != null) {
            updateSourceRecord(taskBatchRemote, 1);

            List<TaskBatchRemoteDetailModel> detailModels = taskBatchRemoteDetailService.findTaskBatchRemoteDetailByTaskBatchId(taskBatchRemote.getTaskBatchId());
            if (detailModels != null && detailModels.size() > 0) {
                for (TaskBatchRemoteDetailModel detail : detailModels) {
                    if (StringUtils.isNotEmpty(detail.getTaskDownId())) {
                        //删除远程配置表和下行任务表中的记录
                        tTaskDownService.deleteTTaskDownByTaskid_Batch(detail.getTaskDownId());
                    }
                }
            }
            taskBatchRemoteDetailService.deleteTaskBatchRemoteDetailByTaskBatchId(taskBatchRemote.getTaskBatchId());
        }
        int i = taskBatchRemoteMapper.deleteByPrimaryKey(id);
        return i;
    }

    /**
     * 检测符合条件的批量任务开始执行(创建下行任务计划)
     */
    public void executeTaskBatchRemote() {
        synchronized (this.getClass()) {//预防人工保存和定时任务同时调用此方法,导致数据重复
            TaskBatchRemoteExample example = new TaskBatchRemoteExample();
            TaskBatchRemoteExample.Criteria criteria = example.createCriteria();
            criteria.andFinishedFlagEqualTo("0");
            List<TaskBatchRemote> taskBatchRemotes = taskBatchRemoteMapper.selectByExample(example);

            Date now = new Date();
            if (taskBatchRemotes != null) {
                for (TaskBatchRemote taskBatchRemote : taskBatchRemotes) {
                    Date execuTime = taskBatchRemote.getExecutionTime();
                    //Date checkTime = DateUtil.getOtherDateByMinute(execuTime,-1*taskBatchRemote.getMinutesAhead());
                    if (now.compareTo(execuTime) > 0) {
                        generateTaskDown(taskBatchRemote);
                        taskBatchRemote.setFinishedFlag("1");//任务已创建
                        taskBatchRemote.setFinishedTime(now);
                        taskBatchRemoteMapper.updateByPrimaryKey(taskBatchRemote);
                    }
                }
            }
        }
    }

    private void generateTaskDown(TaskBatchRemote taskBatchRemote) {
        List<TaskBatchRemoteDetailModel> details = taskBatchRemoteDetailService.findTaskBatchRemoteDetailByTaskBatchId(taskBatchRemote.getTaskBatchId());
        TaskRemoteCfgModel model = taskRemoteCfgService.findTaskRemoteCfg_Batch(taskBatchRemote.getTaskBatchId());
        String createMan = "批量任务";
        Date createTime = new Date();
        for (TaskBatchRemoteDetailModel detail : details) {
            model.setDeviceSn(detail.getDeviceSn());
            model.setCreateMan(createMan);
            model.setCreateTime(createTime);
            TTaskDownModel downModel = taskRemoteCfgService.addTaskRemoteCfg(model);
            detail.setTaskDownId(downModel.getTaskDownId());
            detail.setTaskRemoteCfgId(downModel.getTaskId());
            taskBatchRemoteDetailService.updateTaskBatchRemoteDetail(detail);
        }
    }

    /**
     * 保存数据时,更新对应的任务表记录
     *
     * @param remote
     * @param type   0新增,1删除
     */
    private void updateSourceRecord(TaskBatchRemote remote, int type) {
        String taskType = remote.getTaskType();
        if (StringUtils.isEmpty(taskType) || taskType.equals("9") || StringUtils.isEmpty(remote.getSourceTaskId()))
            return;//自定义或无ID的不处理
        if (taskType.equals("0") || taskType.equals("1") || taskType.equals("2")) {//拷机
            TCheckModel tCheckModel = tCheckService.findBycheckByIdWithOutMx(remote.getSourceTaskId());
            if (tCheckModel != null) {
                tCheckModel.setTaskBatchId(type == 0 ? remote.getTaskBatchId() : "");
                tCheckService.updateTCheck(tCheckModel);
            }
        } else if (taskType.equals("3")) {//入库
            TStkinModel tStkinModel = tStkinService.findTStkinByBillCode(remote.getSourceTaskId());
            if (tStkinModel != null) {
                tStkinModel.setTaskBatchId(type == 0 ? remote.getTaskBatchId() : "");
                tStkinService.updateTStkin(tStkinModel);
            }
        } else if (taskType.equals("4")) {//出库
            TStkoutModel tStkoutModel = tStkoutService.findTStkoutByBillCode(remote.getSourceTaskId());
            if (tStkoutModel != null) {
                tStkoutModel.setTaskBatchId(type == 0 ? remote.getTaskBatchId() : "");
                tStkoutService.updateTStkout(tStkoutModel);
            }
        } else if (taskType.equals("5")) {//更新拷机表,拷机结束后自动生成的批量任务ID
            TCheckModel tCheckModel = tCheckService.findBycheckByIdWithOutMx(remote.getSourceTaskId());
            if (tCheckModel != null) {
                tCheckModel.setAutoBatchId(remote.getTaskBatchId());
                tCheckService.updateTCheck(tCheckModel);
            }
        }
//        else if (taskType.equals("6")) {//更新拷机表,自动切换天线的批量任务ID(在CheckService中已经记录)
//            TCheckModel tCheckModel = tCheckService.findBycheckByIdWithOutMx(remote.getSourceTaskId());
//            if (tCheckModel != null) {
//                tCheckModel.setDelaySwitchBatchId(remote.getTaskBatchId());
//                tCheckService.updateTCheck(tCheckModel);
//            }
//        }
    }

    /**
     * 根据taskBatchId获取对象
     *
     * @param taskBatchId
     * @return
     */
    public TaskBatchRemoteModel findTaskBatchRemoteByTaskBatchId(String taskBatchId) {
        if (StringUtils.isEmpty(taskBatchId)) return null;
        TaskBatchRemoteExample example = new TaskBatchRemoteExample();
        TaskBatchRemoteExample.Criteria criteria = example.createCriteria();
        criteria.andTaskBatchIdEqualTo(taskBatchId);

        List<TaskBatchRemote> taskBatchRemotes = taskBatchRemoteMapper.selectByExample(example);
        if (taskBatchRemotes != null && taskBatchRemotes.size() > 0) {
            TaskBatchRemoteModel model = new TaskBatchRemoteModel();
            BeanUtils.copyProperties(taskBatchRemotes.get(0), model);
            return model;
        }
        return null;
    }

    /**
     * 验证数据完整性
     *
     * @param model
     * @return
     */
    public String checkValid(TaskBatchRemoteModel model, boolean isAdd) {
        if (model.getTaskRemoteCfgModel() == null) {
            return "配置无效";
        }

        if (StringUtils.isEmpty(model.getTaskDescribe()) || model.getTaskDescribe().length() < 3) {
            return "任务描述不能少于3个字";
        }
        if (model.getExecutionTime() == null) {
            return "执行时间不能为空";
        }

        String msg = taskRemoteCfgService.checkDataLegitimacy(model.getTaskRemoteCfgModel(), false);
        if (StringUtils.isNotEmpty(msg)) {
            return msg;
        }
        List<String> snList = new ArrayList<>();
        if (model.getDetailModels() != null && model.getDetailModels().size() > 0) {
            for (TaskBatchRemoteDetailModel detail : model.getDetailModels()) {
                if (StringUtils.isNotEmpty(detail.getDeviceSn())) {
                    snList.add(detail.getDeviceSn());
                    if (deviceAccService.findDeviceAccBysn(detail.getDeviceSn()) == null) {
                        return "[" + detail.getDeviceSn() + "]不在设备台账中";
                    }
                }
            }
            if (snList.size() == 0) {
                return "请先添加设备";
            }
        } else {
            return "请先添加设备";
        }

        if (isAdd) {
            List<TaskRemoteCfg> tmpTasks = taskRemoteCfgService.getUnexecutedTasksForDevices(snList);
            if (tmpTasks.size() > 0) {
                List<String> taskIdList = tmpTasks.stream()
                        .map(TaskRemoteCfg::getDeviceSn)
                        .collect(Collectors.toList());

                return "以下设备存在未执行的远程任务:" + String.join(",", taskIdList);
            }
        }

        return null;
    }

    /**
     * 更新完成状态
     *
     * @param taskBatchId
     * @param detailId
     */
    public void updateFinishedStatus(String taskBatchId, int detailId) {
        TaskBatchRemoteModel remoteModel = findTaskBatchRemoteByTaskBatchId(taskBatchId);
        if (remoteModel.getFinishedFlag().equals("2")) return;//已经完成了
        List<TaskBatchRemoteDetailModel> details = taskBatchRemoteDetailService.findTaskBatchRemoteDetailByTaskBatchId(taskBatchId);
        if (details != null) {
            boolean isFinished = true;
            for (TaskBatchRemoteDetailModel detail : details) {
                if (!detail.getFinishedFlag().equals("1")) {//明细表状态是未完成并且不是当前更新的子表记录
                    if (StringUtils.isEmpty(detail.getAicqbCfgId()) || detail.getId() != detailId) {//比较detailId是还未验证,一个事务内是不是上次更新会未生效
                        isFinished = false;
                        break;
                    }
                }
            }
            if (isFinished) {
                remoteModel.setFinishedFlag("2");
                remoteModel.setFinishedTime(new Date());
                updateTaskBatchRemote(remoteModel);
            }
        }
    }

    /**
     * 根据sourceTaskId获取其未完成的任务
     *
     * @param sourceTaskId
     * @return
     */
    public TaskBatchRemoteModel getUnfinishedTaskBatchRemoteBySourceTask(String sourceTaskId) {
        if (StringUtils.isNotEmpty(sourceTaskId)) {
            TaskBatchRemoteExample example = new TaskBatchRemoteExample();
            TaskBatchRemoteExample.Criteria criteria = example.createCriteria();
            criteria.andSourceTaskIdEqualTo(sourceTaskId);
            criteria.andFinishedFlagNotEqualTo("2");
            List<TaskBatchRemote> taskBatchRemotes = taskBatchRemoteMapper.selectByExample(example);
            if (taskBatchRemotes != null && taskBatchRemotes.size() > 0) {
                TaskBatchRemoteModel model = new TaskBatchRemoteModel();
                BeanUtils.copyProperties(taskBatchRemotes.get(0), model);
                return model;
            }
        }

        return null;
    }
}
