package com.yeejoin.amos.boot.module.jg.biz.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yeejoin.amos.boot.biz.common.bo.ReginParams;
import com.yeejoin.amos.boot.biz.common.utils.RedisKey;
import com.yeejoin.amos.boot.biz.common.utils.RedisUtils;
import com.yeejoin.amos.boot.module.jg.api.dto.JgScrapCancelDto;
import com.yeejoin.amos.boot.module.jg.api.dto.TaskMessageDto;
import com.yeejoin.amos.boot.module.jg.api.dto.TaskModelDto;
import com.yeejoin.amos.boot.module.jg.api.dto.WorkflowResultDto;
import com.yeejoin.amos.boot.module.jg.api.entity.JgScrapCancel;
import com.yeejoin.amos.boot.module.jg.api.entity.JgScrapCancelEq;
import com.yeejoin.amos.boot.module.jg.api.enums.BusinessTypeEnum;
import com.yeejoin.amos.boot.module.jg.api.enums.CancelTypeEnum;
import com.yeejoin.amos.boot.module.jg.api.enums.WorkFlowStatusEnum;
import com.yeejoin.amos.boot.module.jg.api.mapper.JgScrapCancelEqMapper;
import com.yeejoin.amos.boot.module.jg.api.mapper.JgScrapCancelMapper;
import com.yeejoin.amos.boot.module.jg.api.service.IJgScrapCancelService;
import com.yeejoin.amos.boot.module.jg.biz.feign.TzsServiceFeignClient;
import com.yeejoin.amos.boot.module.jg.biz.service.IIdxBizJgRegisterInfoService;
import com.yeejoin.amos.boot.module.jg.flc.api.fegin.WorkFlowFeignService;
import com.yeejoin.amos.boot.module.ymt.api.entity.IdxBizJgRegisterInfo;
import com.yeejoin.amos.boot.module.ymt.api.entity.IdxBizJgUseInfo;
import com.yeejoin.amos.boot.module.ymt.api.entity.OtherInfo;
import com.yeejoin.amos.boot.module.ymt.api.entity.SuperviseInfo;
import com.yeejoin.amos.boot.module.ymt.api.enums.ApplicationFormTypeEnum;
import com.yeejoin.amos.boot.module.ymt.api.enums.EquimentEnum;
import com.yeejoin.amos.boot.module.ymt.api.enums.FlowStatusEnum;
import com.yeejoin.amos.boot.module.ymt.api.mapper.*;
import com.yeejoin.amos.feign.systemctl.model.TaskV2Model;
import com.yeejoin.amos.feign.workflow.model.ActWorkflowBatchDTO;
import com.yeejoin.amos.feign.workflow.model.ActWorkflowStartDTO;
import com.yeejoin.amos.feign.workflow.model.ProcessTaskDTO;
import com.yeejoin.amos.feign.workflow.model.TaskResultDTO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
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.rdbms.service.BaseService;
import org.typroject.tyboot.core.restful.utils.ResponseModel;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 设备注销报废服务实现类
 *
 * @author system_generator
 * @date 2023-12-20
 */
@Service
public class JgScrapCancelServiceImpl extends BaseService<JgScrapCancelDto, JgScrapCancel, JgScrapCancelMapper> implements IJgScrapCancelService {


    private static final String SUBMIT_TYPE_FLOW = "1";
    private static final String PAGE_KEY = "jgScrapCancelAdd";
    private static final String template = "来自电梯【%s】【%s】的业务办理，【申请单号：%s】";
    @Autowired
    WorkFlowFeignService workFlowFeginService;
    @Autowired
    TzsServiceFeignClient tzsServiceFeignClient;
    @Autowired
    IdxBizJgOtherInfoMapper idxBizJgOtherInfoMapper;
    @Autowired
    SuperviseInfoMapper superviseInfoMapper;
    @Autowired
    CommonServiceImpl commonService;
    @Autowired
    CmWorkflowServiceImpl cmWorkflowService;
    @Autowired
    RedisUtils redisUtils;
    @Autowired
    IdxBizJgRegisterInfoMapper idxBizJgRegisterInfoMapper;
    @Autowired
    IIdxBizJgRegisterInfoService idxBizJgRegisterInfoService;
    @Autowired
    private OtherInfoMapper otherInfoMapper;
    @Autowired
    private JgScrapCancelEqServiceImpl jgScrapCancelEqService;
    @Autowired
    private JgScrapCancelEqMapper jgScrapCancelEqMapper;
    @Autowired
    private IdxBizJgUseInfoMapper idxBizJgUseInfoMapper;

    /**
     * 移装移装报废/注销报废判断
     *
     * @return BusinessTypeEnum 业务对应枚举
     */
    public static BusinessTypeEnum businessTypeJudgment(String type) {
        return "1".equals(type) ? BusinessTypeEnum.JG_EQUIPMENT_CANCEL : BusinessTypeEnum.JG_EQUIPMENT_MOVE;
    }

    public Page<Map<String, Object>> getList(JgScrapCancelDto dto, Page<Map<String, Object>> page, List<String> roleIds) {
        ReginParams reginParams = this.getSelectedOrgInfo();
        String orgCode = reginParams.getCompany().getCompanyCode();
        dto.setCreateUserId(reginParams.getUserModel().getUserId());
        Page<Map<String, Object>> listPage = this.baseMapper.getListPage(page, dto, roleIds, orgCode);
        listPage.getRecords().forEach(item -> {
            if (item.containsKey("auditStatus") && Objects.nonNull(item.get("auditStatus"))) {
                item.put("auditStatusDesc", item.get("auditStatus").toString());
            }
            if (item.containsKey("cancelType") && Objects.nonNull(item.get("cancelType"))) {
                item.put("cancelTypeDesc", CancelTypeEnum.getNameByType(item.get("cancelType").toString()));
            }
        });
        return listPage;
    }

    private void convertField(JgScrapCancelDto model) {
        // 处理图片
        if (!ValidationUtil.isEmpty(model.getCancelCertificateList())) {
            model.setCancelCertificate(JSON.toJSONString(model.getCancelCertificateList()));
        }
        String receiveOrgId = model.getReceiveOrgCode();
        if (!ObjectUtils.isEmpty(receiveOrgId)) {
            String[] receiveOrgIdList = receiveOrgId.split("_");
            if (receiveOrgIdList.length > 1) {
                model.setReceiveOrgCode(receiveOrgIdList[0]);
                model.setReceiveOrgName(receiveOrgIdList[1]);
            }
        }
    }

    /**
     * 获取登录用户信息
     *
     * @return
     */
    protected ReginParams getSelectedOrgInfo() {
        return JSONObject.parseObject(redisUtils.get(RedisKey.buildReginKey(RequestContext.getExeUserId(), RequestContext.getToken())).toString(), ReginParams.class);
    }

    @SuppressWarnings({"Duplicates", "rawtypes"})
    @Transactional(rollbackFor = Exception.class)
    public void save(String submitType, Map<String, Object> mapParams) {
        ReginParams reginParams = this.getSelectedOrgInfo();
        Map<?, ?> noticeParams = (Map) mapParams.get(PAGE_KEY);
        String equipId = noticeParams.get("record").toString();
        String[] receiveOrg = String.valueOf(noticeParams.get("receiveOrgCreditCode")).split("_");
        noticeParams.remove("record");
        String[] taskName = new String[]{"流程结束"};
        JgScrapCancelDto model = JSON.parseObject(JSON.toJSONString(noticeParams), JgScrapCancelDto.class);
        model.setSEQUENCE_NBR(equipId);
        model.setReceiveOrgCode(receiveOrg[0]);
        model.setReceiveOrgName(receiveOrg[1]);
        // 字段转换
        convertField(model);
        // 获取告知设备信息
        // 设备信息转换
        if (StrUtil.isEmpty(model.getSEQUENCE_NBR())) {
            return;
        }
        List<Map<String, Object>> deviceList = new ArrayList<>();
        HashMap<String, Object> map1 = new HashMap<>();
        map1.put("SEQUENCE_NBR", model.getSEQUENCE_NBR());
        deviceList.add(map1);
        // 获取告知单号
        ResponseModel<List<String>> listResponseModel =
                tzsServiceFeignClient.applicationFormCode(ApplicationFormTypeEnum.getCode.get(String.valueOf(noticeParams.get("businessCode"))), deviceList.size());
        if (!ObjectUtils.isEmpty(listResponseModel) && listResponseModel.getStatus() != HttpStatus.OK.value()) {
            log.error(" 获取告知单号失败");
            throw new RuntimeException();
        }
        String instanceId = "";
        String nextTaskId = "";
        String nextUserIds = "";
        List<ProcessTaskDTO> processTaskDTOS;
        List<String> roleListNext = new ArrayList<>();
        List<String> roleListAll = new ArrayList<>();
        List<String> applyNoList = listResponseModel.getResult();
        if (CollectionUtils.isEmpty(applyNoList)) {
            return;
        }
        // 判断当前是否为提交
        List<WorkflowResultDto> workflowResultDtos = null;
        if (SUBMIT_TYPE_FLOW.equals(submitType)) {
            // 发起流程
            ActWorkflowBatchDTO actWorkflowBatchDTO = new ActWorkflowBatchDTO();
            List<ActWorkflowStartDTO> list = new ArrayList<>();
            for (int i = 0; i < deviceList.size(); i++) {
                ActWorkflowStartDTO dto = new ActWorkflowStartDTO();
                dto.setProcessDefinitionKey("scrapCancelNew");
                dto.setBusinessKey(applyNoList.get(i));
                dto.setCompleteFirstTask(Boolean.TRUE);
                //下一节点执行人单位（下节点接收机构code）
                dto.setNextExecuteUserCompanyCode(model.getReceiveOrgCode());
                list.add(dto);
            }
            actWorkflowBatchDTO.setProcess(list);
            processTaskDTOS = cmWorkflowService.startBatch(actWorkflowBatchDTO);
            this.buildRoleList(processTaskDTOS, roleListNext, roleListAll);
            instanceId = processTaskDTOS.get(0).getProcessInstance().getId();
            nextTaskId = processTaskDTOS.get(0).getNextTask().get(0).getId();
            taskName[0] = processTaskDTOS.get(0).getNextTask().get(0).getName();
            workflowResultDtos = commonService.buildWorkFlowInfo(processTaskDTOS);
            nextUserIds = workflowResultDtos.get(0).getNextExecutorUserIds();
            this.buildRoleList(processTaskDTOS, roleListNext, roleListAll);
        }

        List<JgScrapCancel> list = new ArrayList<>();
        List<JgScrapCancelEq> equipList = new ArrayList<>();

        for (int i = 0; i < deviceList.size(); i++) {
            JgScrapCancelEq jgRelationEquip = new JgScrapCancelEq();
            JgScrapCancel dto = new JgScrapCancel();
            BeanUtils.copyProperties(model, dto);
            String applyNo = applyNoList.get(i);
            LambdaQueryWrapper<OtherInfo> otherLambda = new QueryWrapper<OtherInfo>().lambda();
            otherLambda.eq(OtherInfo::getRecord, deviceList.get(i).get("SEQUENCE_NBR"));
            OtherInfo otherInfo = otherInfoMapper.selectOne(otherLambda);
            String supervisoryCode = otherInfo.getSupervisoryCode();
            dto.setSupervisoryCode(supervisoryCode);
            dto.setApplyNo(applyNo);
            dto.setCreateDate(new Date());
            dto.setNextExecuteIds(String.join(",", roleListNext));
            dto.setInstanceStatus(String.join(",", roleListAll));
            dto.setPromoter(reginParams.getUserModel().getUserId());
            dto.setNextTaskId(Objects.isNull(workflowResultDtos) ? null : workflowResultDtos.get(i).getNextTaskId());
            jgRelationEquip.setEquId(String.valueOf(deviceList.get(i).get("SEQUENCE_NBR")));
            jgRelationEquip.setEquipTransferId(applyNo);
            if (!StringUtils.isEmpty(instanceId)) {
                dto.setInstanceId(instanceId);
                dto.setNextTaskId(nextTaskId);
                dto.setNextExecuteUserIds(nextUserIds);
                dto.setAuditStatus(String.valueOf(WorkFlowStatusEnum.CANCEL_RECEIVE.getPass()));
            } else {
                dto.setAuditStatus(String.valueOf(WorkFlowStatusEnum.CANCEL_SUBMIT.getPass()));
            }
            dto.setUseUnitCode(reginParams.getCompany().getCompanyCode());
            dto.setUseUnitName(reginParams.getCompany().getCompanyName());
            dto.setCreateUserId(RequestContext.getExeUserId());
            list.add(dto);
            equipList.add(jgRelationEquip);
        }
        this.saveBatch(list);
        // 新增代办
        for (JgScrapCancel jgScrapCancel : list) {
            this.createTaskModel(jgScrapCancel, taskName[0], submitType, nextUserIds);
        }
        List<JgScrapCancelEq> jgScrapCancelEqList = equipList.stream().map(t -> {
            List<JgScrapCancel> collect = list.stream().filter(item -> t.getEquipTransferId().equals(item.getApplyNo())).collect(Collectors.toList());
            Long sequenceNbr = collect.get(0).getSequenceNbr();
            return t.setEquipTransferId(String.valueOf(sequenceNbr));
        }).collect(Collectors.toList());
        jgScrapCancelEqService.saveBatch(jgScrapCancelEqList);
    }

    private void createTaskModel(JgScrapCancel scrapCancel, String taskName, String submitType, String nextUserIds) {
        ReginParams reginParams = JSON.parseObject(redisUtils.get(RedisKey.buildReginKey(RequestContext.getExeUserId(), RequestContext.getToken())).toString(), ReginParams.class);
        TaskModelDto taskModelDto = new TaskModelDto();
        if ("1".equals(submitType)) {
            taskModelDto.setFlowCreateDate(scrapCancel.getCreateDate());
            taskModelDto.setTaskName(taskName);
            taskModelDto.setTaskCode(scrapCancel.getApplyNo());
            taskModelDto.setTaskContent(this.buildTaskContent(scrapCancel.getSupervisoryCode(),
                    scrapCancel.getCancelType(), scrapCancel.getApplyNo()));
            taskModelDto.setTaskDesc("");
            taskModelDto.setTaskType(businessTypeJudgment(scrapCancel.getCancelType()).getCode());
            taskModelDto.setTaskTypeLabel(businessTypeJudgment(scrapCancel.getCancelType()).getName());
            taskModelDto.setRelationId(scrapCancel.getInstanceId());
            taskModelDto.setExecuteUserIds(nextUserIds);
            FlowStatusEnum flowStatusEnum = this.getTaskStatus(submitType);
            taskModelDto.setTaskStatus(flowStatusEnum.getCode());
            taskModelDto.setTaskStatusLabel(flowStatusEnum.getName());
            taskModelDto.setFlowStatus(this.getTaskStatusByName(scrapCancel.getAuditStatus()));
            taskModelDto.setFlowStatusLabel(scrapCancel.getAuditStatus());
            taskModelDto.setStartUserId(scrapCancel.getCreateUserId());
            taskModelDto.setFlowCode(scrapCancel.getNextTaskId());
            taskModelDto.setStartUser(reginParams.getUserModel().getRealName());
            taskModelDto.setStartUserCompanyName(scrapCancel.getUseUnitName());
            taskModelDto.setNextExecuteUser(scrapCancel.getNextExecuteIds());
            taskModelDto.setStartDate(scrapCancel.getCreateDate() == null ? new Date() : scrapCancel.getCreateDate());
            TaskMessageDto taskMessageDto = new TaskMessageDto();
            BeanUtils.copyProperties(scrapCancel, taskMessageDto);
            taskModelDto.setModel(taskMessageDto);
        } else {
            TaskMessageDto taskMessageDto = new TaskMessageDto();
            BeanUtils.copyProperties(scrapCancel, taskMessageDto);
            taskModelDto.setModel(taskMessageDto);
            taskModelDto.setTaskContent(this.buildTaskContent(scrapCancel.getSupervisoryCode(),
                    scrapCancel.getCancelType(), scrapCancel.getApplyNo()));
            taskModelDto.setTaskCode(scrapCancel.getApplyNo());
            taskModelDto.setTaskType(businessTypeJudgment(scrapCancel.getCancelType()).getCode());
            taskModelDto.setNextExecuteUser(scrapCancel.getNextExecuteIds());
            taskModelDto.setRelationId(taskMessageDto.getSequenceNbr() + "");
        }
        commonService.buildTaskModel(Collections.singletonList(taskModelDto));
    }

    private void buildRoleList(List<ProcessTaskDTO> processTasks, List<String> roleListNext, List<String> roleListAll) {
        processTasks.forEach(p -> {
            p.getNextCandidateGroups().values().forEach(e -> {
                roleListNext.addAll(e);
                roleListAll.addAll(e);
            });
            roleListAll.addAll(p.getCandidateGroups());
        });
    }

    /**
     * 摘要构建
     *
     * @return 摘要
     */
    private String buildTaskContent(String supervisoryCode, String cancelType, String applyNo) {
        //    来自电梯【X3100-123456】【移装注销】的业务办理【申请单号：ABCD0000001】
        String type = "1".equals(cancelType) ? "报废注销" : "移装注销";
        return String.format(template, Objects.isNull(supervisoryCode) ? "无" : supervisoryCode, type, applyNo);
    }

    public void deleteBatch(List<Long> ids) {
        if (!ids.isEmpty()) {
            for (Long id : ids) {
                LambdaQueryWrapper<JgScrapCancel> lambda = new QueryWrapper<JgScrapCancel>().lambda();
                lambda.eq(JgScrapCancel::getSequenceNbr, id);
                JgScrapCancel jgScrapCancel = this.baseMapper.selectOne(lambda);
                //删除代办消息
                commonService.deleteTaskModel(jgScrapCancel.getInstanceId());
                //更新jgScrapCancel数据
                jgScrapCancel.setIsDelete(true);
                this.updateById(jgScrapCancel);
            }
        }
    }

    public JgScrapCancelDto updateInfo(String submitType, JgScrapCancelDto jgScrapCancelDto, String op) {
        if (Objects.isNull(jgScrapCancelDto) || StringUtils.isEmpty(submitType)) {
            throw new IllegalArgumentException("参数不能为空");
        }
        // 字段转换
        this.convertField(jgScrapCancelDto);
        List<String> roleListNext = new ArrayList<>();
        List<String> roleListAll = new ArrayList<>();
        if (SUBMIT_TYPE_FLOW.equals(submitType)) {
            // 更新并提交
            // 发起流程
            if (!StringUtils.hasText(jgScrapCancelDto.getInstanceId())) {
                //未进流程直接发起并执行

                List<ProcessTaskDTO> processTasks;
                ActWorkflowBatchDTO actWorkflowBatchDTO = new ActWorkflowBatchDTO();
                List<ActWorkflowStartDTO> list = new ArrayList<>();
                ActWorkflowStartDTO dto = new ActWorkflowStartDTO();
                dto.setProcessDefinitionKey("scrapCancelNew");
                dto.setBusinessKey(jgScrapCancelDto.getApplyNo());
                dto.setCompleteFirstTask(true);
                dto.setNextExecuteUserCompanyCode(jgScrapCancelDto.getReceiveOrgCode());
                list.add(dto);
                actWorkflowBatchDTO.setProcess(list);
                processTasks = cmWorkflowService.startBatch(actWorkflowBatchDTO);
                String instanceId = processTasks.get(0).getProcessInstance().getId();
                String nextTaskId = processTasks.get(0).getNextTask().get(0).getId();
                String taskName = processTasks.get(0).getNextTask().get(0).getName();
                this.buildRoleList(processTasks, roleListNext, roleListAll);
                List<WorkflowResultDto> workflowResultDtos = commonService.buildWorkFlowInfo(processTasks);
                String nextUserIds = workflowResultDtos.get(0).getNextExecutorUserIds();
                jgScrapCancelDto.setInstanceStatus(String.join(",", roleListAll));
                jgScrapCancelDto.setInstanceId(instanceId);
                jgScrapCancelDto.setNextExecuteIds(String.join(",", roleListNext));
                jgScrapCancelDto.setNextTaskId(nextTaskId);
                jgScrapCancelDto.setNextExecuteUserIds(nextUserIds);
                jgScrapCancelDto.setAuditStatus(WorkFlowStatusEnum.CANCEL_RECEIVE.getPass());
                // 创建待办
                JgScrapCancel bean = new JgScrapCancel();
                BeanUtil.copyProperties(jgScrapCancelDto, bean);
                commonService.deleteTaskModel(String.valueOf(jgScrapCancelDto.getSequenceNbr()));
                createTaskModel(bean, taskName, "1", nextUserIds);
            } else {
                // 已经在流程中，执行一步
                ProcessTaskDTO processTaskDTO = submit(op, jgScrapCancelDto.getNextTaskId());
                String nextTaskId = processTaskDTO.getNextTask().get(0).getId();
                String taskName = processTaskDTO.getNextTask().get(0).getName();
                this.buildRoleList(Collections.singletonList(processTaskDTO), roleListNext, roleListAll);
                List<WorkflowResultDto> workflowResultDtos = commonService.buildWorkFlowInfo(Collections.singletonList(processTaskDTO));
                String nextUserIds = workflowResultDtos.get(0).getNextExecutorUserIds();
                // 查询下节点任务
                if (!ObjectUtils.isEmpty(jgScrapCancelDto.getInstanceStatus())) {
                    jgScrapCancelDto.setInstanceStatus(jgScrapCancelDto.getInstanceStatus() + "," + String.join("", roleListNext));
                } else {
                    jgScrapCancelDto.setInstanceStatus(String.join(",", roleListAll));
                }
                jgScrapCancelDto.setPromoter(RequestContext.getExeUserId());
                jgScrapCancelDto.setNextExecuteIds(String.join(",", roleListNext));
                jgScrapCancelDto.setAuditStatus(String.valueOf(WorkFlowStatusEnum.CANCEL_RECEIVE.getPass()));
                jgScrapCancelDto.setNextTaskId(nextTaskId);
                // 更新下一步可执行人
                jgScrapCancelDto.setNextExecuteUserIds(nextUserIds);
                JgScrapCancel jgScrapCancel = new JgScrapCancel();
                BeanUtils.copyProperties(jgScrapCancelDto, jgScrapCancel);
                updateTaskModel(jgScrapCancelDto, "0");
                createTaskModel(jgScrapCancel, taskName, "1", nextUserIds);
            }
            JgScrapCancel cancel = new JgScrapCancel();
            BeanUtils.copyProperties(jgScrapCancelDto, cancel);
            this.updateById(cancel);
            JgScrapCancel jgScrapCancel = new JgScrapCancel();
            BeanUtils.copyProperties(jgScrapCancelDto, jgScrapCancel, "useUnitName", "useUnitName");
            LambdaUpdateWrapper<JgScrapCancelEq> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(JgScrapCancelEq::getEquipTransferId, jgScrapCancel.getSequenceNbr());
            JgScrapCancelEq jgScrapCancelEq = new JgScrapCancelEq();
            jgScrapCancelEq.setEquId(jgScrapCancelDto.getRecord());
            jgScrapCancelEqMapper.update(jgScrapCancelEq, updateWrapper);
        } else {
            LambdaQueryWrapper<OtherInfo> otherLambda = new QueryWrapper<OtherInfo>().lambda();
            otherLambda.eq(OtherInfo::getRecord, jgScrapCancelDto.getSEQUENCE_NBR());
            OtherInfo otherInfo = otherInfoMapper.selectOne(otherLambda);
            String supervisoryCode = otherInfo.getSupervisoryCode();
            jgScrapCancelDto.setSupervisoryCode(supervisoryCode);
            //更新操作
            JgScrapCancel bean = new JgScrapCancel();
            BeanUtils.copyProperties(jgScrapCancelDto, bean);
            this.updateById(bean);
            LambdaUpdateWrapper<JgScrapCancelEq> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(JgScrapCancelEq::getEquipTransferId, bean.getSequenceNbr());
            JgScrapCancelEq jgScrapCancelEq = new JgScrapCancelEq();
            jgScrapCancelEq.setEquId(jgScrapCancelDto.getRecord());
            jgScrapCancelEqMapper.update(jgScrapCancelEq, updateWrapper);
        }
        return jgScrapCancelDto;
    }

    private void executeOneStep(JgScrapCancelDto jgScrapCancelDto, String taskName, String nextUserIds, String operate) {
        // 先更新之前的待办
        TaskV2Model taskV2Model = updateTaskModel(jgScrapCancelDto, operate);
        taskV2Model.setTaskDesc("");
        taskV2Model.setTaskContent(this.buildTaskContent(jgScrapCancelDto.getSupervisoryCode(), jgScrapCancelDto.getCancelType(), jgScrapCancelDto.getApplyNo()));
        taskV2Model.setTaskName(taskName);
        taskV2Model.setTaskDesc("");
        taskV2Model.setTaskCode(jgScrapCancelDto.getApplyNo());
        taskV2Model.setExecuteUserIds(nextUserIds);
        taskV2Model.setRelationId(jgScrapCancelDto.getInstanceId());
        FlowStatusEnum flowStatusEnum = this.getTaskStatus(operate);
        taskV2Model.setTaskStatus(flowStatusEnum.getCode());
        taskV2Model.setTaskStatusLabel(flowStatusEnum.getName());
        taskV2Model.setFlowStatus(this.getTaskStatusByName(jgScrapCancelDto.getAuditStatus()));
        taskV2Model.setFlowStatusLabel(jgScrapCancelDto.getAuditStatus());
        taskV2Model.setTaskType(businessTypeJudgment(jgScrapCancelDto.getCancelType()).getCode());
        taskV2Model.setStartUser(jgScrapCancelDto.getRecUserName());
        taskV2Model.setTaskTypeLabel(businessTypeJudgment(jgScrapCancelDto.getCancelType()).getName());
        taskV2Model.setStartDate(jgScrapCancelDto.getCreateDate());
        taskV2Model.setStartUserId(jgScrapCancelDto.getCreateUserId());
        taskV2Model.setStartUserCompanyName(jgScrapCancelDto.getUseUnitName());
        taskV2Model.setExecuteUserIds(nextUserIds);
        TaskModelDto modelDto = new TaskModelDto();
        BeanUtil.copyProperties(taskV2Model, modelDto);
        modelDto.setNextExecuteUser(jgScrapCancelDto.getNextExecuteIds());
        TaskMessageDto taskMessageDto = new TaskMessageDto();
        BeanUtils.copyProperties(jgScrapCancelDto, taskMessageDto);
        modelDto.setModel(taskMessageDto);
        modelDto.setPageType(this.getPageTypeForReject(operate, jgScrapCancelDto.getAuditStatus()));
        commonService.buildTaskModel(Collections.singletonList(modelDto));
    }

    private Integer getTaskStatusByName(String auditStatus) {
        return commonService.getDictionaryCodeByName(auditStatus);
    }

    private String getPageTypeForReject(String operate, String auditStatus) {
        // 驳回
        if ("1".equals(operate)) {
            // 且驳回到的节点为使用单位提交 则可编辑
            if (WorkFlowStatusEnum.CANCEL_SUBMIT.getPass().equals(auditStatus) ||
                    WorkFlowStatusEnum.CANCEL_SUBMIT.getReject().equals(auditStatus) ||
                    WorkFlowStatusEnum.CANCEL_SUBMIT.getRollBack().equals(auditStatus)
            ) {
                return "edit";
            }
            return "look";
        }
        return "look";
    }

    private TaskV2Model updateTaskModel(JgScrapCancelDto jgScrapCancelDto, String operate) {
        Map<String, Object> params = new HashMap<>();
        FlowStatusEnum flowStatusEnum = this.getTaskStatus(operate);
        params.put("relationId", jgScrapCancelDto.getInstanceId());
        params.put("taskStatus", flowStatusEnum.getCode());
        params.put("taskStatusLabel", flowStatusEnum.getName());
        params.put("flowStatus", this.getTaskStatusByName(jgScrapCancelDto.getAuditStatus()));
        params.put("flowStatusLabel", jgScrapCancelDto.getAuditStatus());
        params.put("model", jgScrapCancelDto);
        return commonService.updateTaskModel(params);
    }

    private FlowStatusEnum getTaskStatus(String operate) {
        if ("0".equals(operate)) {
            return FlowStatusEnum.TO_BE_FINISHED;
        } else {
            return FlowStatusEnum.REJECTED;
        }
    }

    public ProcessTaskDTO submit(String op, String taskId) {
        //组装信息
        TaskResultDTO dto = new TaskResultDTO();
        dto.setResultCode("approvalStatus");
        dto.setTaskId(taskId);
        dto.setComment("提交流程");
        HashMap<String, Object> map = new HashMap<>();
        map.put("approvalStatus", op);
        dto.setVariable(map);
        return cmWorkflowService.complete(taskId, dto);
    }

    public Map<String, Object> queryBySequenceNbr(Long sequenceNbr) {
        // 安装告知信息
        JgScrapCancel notice = this.baseMapper.selectById(sequenceNbr);
        if (Objects.isNull(notice)) {
            return null;
        }
        Map<String, Object> installationInfo = BeanUtil.beanToMap(notice);
        installationInfo.put("receiveOrgCode", notice.getReceiveOrgCode() + "_" + notice.getReceiveOrgName());
        installationInfo.put("cancelCertificateList", JSON.parseArray(String.valueOf(installationInfo.get("cancelCertificate"))));
        LambdaQueryWrapper<JgScrapCancelEq> lambdaEq = new QueryWrapper<JgScrapCancelEq>().lambda();
        lambdaEq.eq(JgScrapCancelEq::getEquipTransferId, sequenceNbr);
        JgScrapCancelEq jgScrapCancelEq = jgScrapCancelEqMapper.selectOne(lambdaEq);
        // 设备信息
        installationInfo.put("record", jgScrapCancelEq.getEquId());

        LambdaQueryWrapper<IdxBizJgRegisterInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(IdxBizJgRegisterInfo::getRecord, jgScrapCancelEq.getEquId());
        queryWrapper.last("limit 1");
        IdxBizJgRegisterInfo one = idxBizJgRegisterInfoMapper.selectOne(queryWrapper);
        installationInfo.put("equCode", one.getEquCode());
        Map<String, Object> detailFieldCamelCaseByRecord = idxBizJgRegisterInfoService.getDetailFieldCamelCaseByRecord(jgScrapCancelEq.getEquId());
        BeanUtil.copyProperties(installationInfo, detailFieldCamelCaseByRecord);
        return new HashMap<String, Object>() {{
            this.put(PAGE_KEY, detailFieldCamelCaseByRecord);
        }};
    }


    @Transactional
    public void revocation(String instanceId) {
        ReginParams reginParams = this.getSelectedOrgInfo();
        LambdaQueryWrapper<JgScrapCancel> lambda = new QueryWrapper<JgScrapCancel>().lambda();
        lambda.eq(JgScrapCancel::getInstanceId, instanceId);
        JgScrapCancel jgScrapCancel = this.baseMapper.selectOne(lambda);
        ProcessTaskDTO processTaskDTO = cmWorkflowService.rollBack(instanceId);
        WorkflowResultDto workflowResultDto = commonService.buildWorkFlowInfo(Collections.singletonList(processTaskDTO)).get(0);
        if (!FlowStatusEnum.TO_BE_FINISHED.getName().equals(workflowResultDto.getNextTaskName())) {
            jgScrapCancel.setAuditStatus(Objects.requireNonNull(WorkFlowStatusEnum.getMessage(workflowResultDto.getNextTaskCode())).getRollBack());
        }
        jgScrapCancel.setNextTaskId(workflowResultDto.getNextTaskId());
        List<WorkflowResultDto> workflowResultDtos = commonService.buildWorkFlowInfo(Collections.singletonList(processTaskDTO));
        // 更新下一步可执行人
        String nextUserIds = workflowResultDtos.get(0).getNextExecutorUserIds();
        jgScrapCancel.setNextExecuteUserIds(nextUserIds);
        jgScrapCancel.setPromoter(reginParams.getUserModel().getUserId());
        jgScrapCancel.setNextExecuteIds(workflowResultDto.getNextExecutorRoleIds());
        this.updateById(jgScrapCancel);

        // 删除待办
        JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(jgScrapCancel));
        jsonObject.put("nextTaskId", jgScrapCancel.getNextTaskId());
        jsonObject.put("nextExecuteUser", jgScrapCancel.getNextExecuteIds());
        jsonObject.put("taskType", businessTypeJudgment(jgScrapCancel.getCancelType()).getCode());
        jsonObject.put("flowStatus", this.getTaskCodeByName(jgScrapCancel.getAuditStatus()));
        jsonObject.put("flowStatusLabel", jgScrapCancel.getAuditStatus());
        // 判断撤回后当前的节点，如果当前节点为提交节点则页面可编辑
        jsonObject.put("pageType", this.getPageTypeByCurrentNode(jgScrapCancel.getAuditStatus()));
        commonService.rollbackTask(instanceId, jsonObject);
    }

    private Integer getTaskCodeByName(String auditStatus) {
        return commonService.getDictionaryCodeByName(auditStatus);
    }

    private String getPageTypeByCurrentNode(String auditStatus) {
        if (WorkFlowStatusEnum.CANCEL_SUBMIT.getPass().equals(auditStatus)
                || WorkFlowStatusEnum.CANCEL_SUBMIT.getReject().equals(auditStatus)
                || WorkFlowStatusEnum.CANCEL_SUBMIT.getRollBack().equals(auditStatus)
        ) {
            return "edit";
        } else {
            return "look";
        }
    }

    @Transactional
    public void flowExecute(Long id, String instanceId, String operate, String comment) {
        JgScrapCancel jgScrapCancel = this.getBaseMapper().selectById(id);
        String taskId = jgScrapCancel.getNextTaskId();
        //组装信息
        TaskResultDTO dto = new TaskResultDTO();
        dto.setResultCode("approvalStatus");
        dto.setTaskId(taskId);
        dto.setComment(comment);
        HashMap<String, Object> map = new HashMap<>();
        map.put("approvalStatus", operate);
        if (!ObjectUtils.isEmpty(jgScrapCancel.getInstanceStatus()) && (jgScrapCancel.getInstanceStatus().equals(WorkFlowStatusEnum.CANCEL_SUBMIT.getReject()) || jgScrapCancel.getInstanceStatus().equals(WorkFlowStatusEnum.CANCEL_SUBMIT.getRollBack()))) {
            map.put("approvalStatus", "提交");
        }
        dto.setVariable(map);
        //下一节点执行人单位（下节点接收机构code）
        dto.setNextExecuteUserCompanyCode(this.getNextUserOrgCode(operate, jgScrapCancel));
        //执行流程
        ProcessTaskDTO processTaskDTO = cmWorkflowService.complete(taskId, dto);
        // 更新下一步执行人、创建待办
        updateExecuteIds(instanceId, id, operate, processTaskDTO);
    }


    public void updateExecuteIds(String instanceId, Long sequenceNbr, String operate, ProcessTaskDTO processTaskDTO) {
        List<String> roleListNext = new ArrayList<>();
        List<String> roleListAll = new ArrayList<>();
        String taskCode = FlowStatusEnum.TO_BE_FINISHED.getName();
        String taskName = "";
        String nextTaskId = "";
        JgScrapCancel jgScrapCancel = this.getBaseMapper().selectById(sequenceNbr);
        if (processTaskDTO != null && processTaskDTO.getNextTask() != null && !processTaskDTO.getNextTask().isEmpty()) {
            taskCode = processTaskDTO.getNextTask().get(0).getKey();
            taskName = processTaskDTO.getNextTask().get(0).getName();
            nextTaskId = processTaskDTO.getNextTask().get(0).getId();
        }
        if (!FlowStatusEnum.TO_BE_FINISHED.getName().equals(taskCode)) {
            this.buildRoleList(Collections.singletonList(processTaskDTO), roleListNext, roleListAll);
            List<WorkflowResultDto> workflowResultDtos = commonService.buildWorkFlowInfo(Collections.singletonList(processTaskDTO));
            String nextUserIds = workflowResultDtos.get(0).getNextExecutorUserIds();
            jgScrapCancel.setNextExecuteIds(String.join(",", roleListNext));
            jgScrapCancel.setPromoter(RequestContext.getExeUserId());
            jgScrapCancel.setInstanceId(instanceId);
            jgScrapCancel.setNextTaskId(nextTaskId);
            // 更新下一步可执行人
            jgScrapCancel.setNextExecuteUserIds(nextUserIds);
            if (!ObjectUtils.isEmpty(jgScrapCancel.getInstanceStatus())) {
                jgScrapCancel.setInstanceStatus(jgScrapCancel.getInstanceStatus() + "," + String.join(",", roleListNext));
            } else {
                jgScrapCancel.setInstanceStatus(String.join(",", roleListNext));
            }
            if ("0".equals(operate)) {
                // 通过操作
                jgScrapCancel.setAuditStatus(Objects.requireNonNull(WorkFlowStatusEnum.getMessage(taskCode)).getPass());
            } else {
                // 驳回操作
                jgScrapCancel.setAuditStatus(Objects.requireNonNull(WorkFlowStatusEnum.getMessage(taskCode)).getReject());
                jgScrapCancel.setPromoter(null);
            }
            JgScrapCancelDto scrapCancelDto = new JgScrapCancelDto();
            BeanUtils.copyProperties(jgScrapCancel, scrapCancelDto);
            // 更新上一步待办、创建待办
            executeOneStep(scrapCancelDto, taskName, nextUserIds, operate);
        } else {
            // 完成时 下一步骤可执行人清空
            jgScrapCancel.setNextExecuteUserIds("");
            // 修改业务信息
            updateInfoOther(jgScrapCancel);
            JgScrapCancelDto scrapCancelDto = new JgScrapCancelDto();
            BeanUtils.copyProperties(jgScrapCancel, scrapCancelDto);
            // 更新代办
            updateTaskModel(scrapCancelDto, operate);
        }
        this.getBaseMapper().updateById(jgScrapCancel);
    }

    public void updateInfoOther(JgScrapCancel jgScrapCancel) {
        LambdaQueryWrapper<JgScrapCancelEq> lambdaEq = new QueryWrapper<JgScrapCancelEq>().lambda();
        lambdaEq.eq(JgScrapCancelEq::getEquipTransferId, jgScrapCancel.getSequenceNbr());
        JgScrapCancelEq jgScrapCancelEq = jgScrapCancelEqMapper.selectOne(lambdaEq);

        ResponseModel<String> responseModel = tzsServiceFeignClient.useRegistrationCode(idxBizJgOtherInfoMapper.getSupervisoryCodeByEquipmentCode(jgScrapCancelEq.getEquId()));
        String newUseRegistrationCertificateNumber = responseModel.getResult().split("-")[0];

        Map<String, Map<String, Object>> resultMap = new HashMap<>();
        Map<String, Object> map1 = new HashMap<>();
        map1.put("USE_ORG_CODE", newUseRegistrationCertificateNumber);
        if (CancelTypeEnum.SCRAPPED.getCode().equals(jgScrapCancel.getCancelType())) {
            IdxBizJgUseInfo idxBizJgUseInfo = new IdxBizJgUseInfo();
            idxBizJgUseInfo.setEquState(String.valueOf(EquimentEnum.BAOFEI.getCode()));
            LambdaQueryWrapper<IdxBizJgUseInfo> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(IdxBizJgUseInfo::getRecord, jgScrapCancelEq.getEquId());
            idxBizJgUseInfoMapper.update(idxBizJgUseInfo, wrapper);
            map1.put("EQU_STATE", String.valueOf(EquimentEnum.BAOFEI.getCode()));
        } else {
            SuperviseInfo superviseInfo = new SuperviseInfo();
            superviseInfo.setOrgBranchCode("");
            superviseInfo.setOrgBranchName("");
            LambdaQueryWrapper<SuperviseInfo> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(SuperviseInfo::getRecord, jgScrapCancelEq.getEquId());
            superviseInfoMapper.update(superviseInfo, wrapper);
            map1.put("ORG_BRANCH_CODE", "");
            map1.put("ORG_BRANCH_NAME", "");
        }
        resultMap.put(jgScrapCancelEq.getEquId(), map1);
        try {
            tzsServiceFeignClient.commonUpdateEsDataByIds(resultMap);
        } catch (Exception e) {
            e.printStackTrace();
        }
        jgScrapCancel.setAuditStatus(FlowStatusEnum.TO_BE_FINISHED.getName());
        jgScrapCancel.setAuditPassDate(new Date());
    }

    public String getNextUserOrgCode(String operate, JgScrapCancel jgScrapCancel) {
        String code = null;
        if ("0".equals(operate)) {
            code = jgScrapCancel.getReceiveOrgCode();
        } else {
            //驳回
            if (WorkFlowStatusEnum.CANCEL_RECEIVE.getPass().equals(jgScrapCancel.getAuditStatus()) ||
                    WorkFlowStatusEnum.CANCEL_RECEIVE.getReject().equals(jgScrapCancel.getAuditStatus()) ||
                    WorkFlowStatusEnum.CANCEL_RECEIVE.getRollBack().equals(jgScrapCancel.getAuditStatus())) {
                code = jgScrapCancel.getUseUnitCode();
            }
        }
        return code == null ? jgScrapCancel.getReceiveOrgCode() : code;
    }

}