package com.zkqy.execution.produce.utils;

import com.alibaba.fastjson2.JSON;
import com.zkqy.common.config.bpm.BpmProperties;
import com.zkqy.common.core.domain.AjaxResult;
import com.zkqy.common.utils.StringUtils;
import com.zkqy.common.utils.http.Sending;
import com.zkqy.execution.produce.dispersed.runbpm.RunImplementationClass;
import com.zkqy.system.entity.BpmNodeHandleUser;
import com.zkqy.system.entity.BpmNodeScriptRelevance;
import com.zkqy.system.entity.BpmProcessConfiguration;
import com.zkqy.system.service.IBpmNodeHandleUserService;
import com.zkqy.system.service.IBpmNodeScriptRelevanceService;
import com.zkqy.system.service.IBpmProcessConfigurationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;

/**
 * 离散型流程发起前校验
 *
 * @author hanzihang
 * @date 2023/11/13 4:44 PM
 */

@Component
public class VerifyExecutionProcess {

    @Autowired
    private IBpmProcessConfigurationService bpmProcessConfigurationService;

    @Autowired
    private IBpmNodeScriptRelevanceService bpmNodeScriptRelevanceService;

    @Autowired
    private IBpmNodeHandleUserService bpmNodeHandleUserService;

    @Autowired
    private RunImplementationClass runImplementationClass;

    @Autowired
    private BpmProperties bpmProperties;

    @Autowired
    private Sending sending;

    /*
      判断开始节点结束节点是否存在、脚本是否存在
      判断是否有其他节点，有，循环判断每一个节点是否包含自动执行脚本，并且脚本是否存在，
      节点是否绑定角色权限，真实角色下是否存在可处理用户，虚拟角色下用户是否都真实存在
      node_form_type类型为拖拽表单类型，查看该表单信息是否存在；为组合表单类型查看该表格组信息是否存在；
      为自定义表单类型时，判断节点脚本关联表查看script_node_name该字段是否存在及该字段是否有“-”,"-"前是否有内容。
    */
    public boolean VerifyProcessData(String processKey) {
        // 根据流程编号（node_process_key）查询流程配置表（bpm_process_configuration）得到该流程所有节点信息
        BpmProcessConfiguration bpmProcessConfiguration = new BpmProcessConfiguration();
        bpmProcessConfiguration.setNodeProcessKey(processKey);
        List<BpmProcessConfiguration> bpmProcessConfigurationList = bpmProcessConfigurationService.selectBpmProcessConfigurationList(bpmProcessConfiguration);
        // 定义变量开始节点（startNode)，结束节点（endNode）
        int startNode = 0;
        int endNode = 0;
        for (BpmProcessConfiguration b : bpmProcessConfigurationList) {

            if (b.getNodeType().equals("startEvent")) {
                startNode++;
                //校验正常节点存不存在
                BpmNodeScriptRelevance bpmNodeScriptRelevance = new BpmNodeScriptRelevance();
                bpmNodeScriptRelevance.setNodeKey(b.getNodeKey());
                bpmNodeScriptRelevance.setScriptTriggerType(1L);
                BpmNodeScriptRelevance bpmNodeScriptRelevance1 = bpmNodeScriptRelevanceService.selectBpmNodeScriptRelevanceInfo(bpmNodeScriptRelevance);
                if (bpmNodeScriptRelevance1 != null) {
                    ResponseEntity<AjaxResult> responseEntity = sending.sendGetNodeScript(bpmNodeScriptRelevance1.getScriptKey());
                    if (responseEntity.getStatusCodeValue() != 200L) {
                        return false;
                    }
                    AjaxResult ajaxResult = responseEntity.getBody();
                    if (Long.valueOf(ajaxResult.get("code").toString()) != 200L) {
                        return false;
                    }
                    if (!ajaxResult.containsKey("data")) {
                        return false;
                    }
                    Map<String, Object> dataMap = (Map<String, Object>) ajaxResult.get("data");
                    if (!runImplementationClass.isVerificationMethod(dataMap.get("scriptKey").toString())) {
                        return false;
                    }
                    ;
                } else {
                    return false;
                }
                continue;
            }
            if (b.getNodeType().equals("endEvent")) {
                endNode++;
                //校验正常节点存不存在
                BpmNodeScriptRelevance bpmNodeScriptRelevance = new BpmNodeScriptRelevance();
                bpmNodeScriptRelevance.setNodeKey(b.getNodeKey());
                bpmNodeScriptRelevance.setScriptTriggerType(1L);
                BpmNodeScriptRelevance bpmNodeScriptRelevance1 = bpmNodeScriptRelevanceService.selectBpmNodeScriptRelevanceInfo(bpmNodeScriptRelevance);
                if (bpmNodeScriptRelevance1 != null) {
                    ResponseEntity<AjaxResult> responseEntity = sending.sendGetNodeScript(bpmNodeScriptRelevance1.getScriptKey());
                    if (responseEntity.getStatusCodeValue() != 200L) {
                        return false;
                    }
                    AjaxResult ajaxResult = responseEntity.getBody();
                    if (Long.valueOf(ajaxResult.get("code").toString()) != 200L) {
                        return false;
                    }
                    if (!ajaxResult.containsKey("data")) {
                        return false;
                    }
                    Map<String, Object> dataMap = (Map<String, Object>) ajaxResult.get("data");
                    if (!runImplementationClass.isVerificationMethod(dataMap.get("scriptKey").toString())) {
                        return false;
                    }

                } else {
                    return false;
                }
                continue;
            }


            //判断节点前后是否执行自动脚本,并且脚本是否存在
            if (b.getNodeBefore().equals("true") || b.getNodeAfter().equals("true")) {

                //判断当前节点名称是否存在&& '-' 前是否有内容
                if (b.getNodeName().isEmpty()) {
                    return false;
                }
                int separatorIndex = b.getNodeName().indexOf('-');
                if (separatorIndex <= -1) {
                    return false;
                }
                String nodeName = b.getNodeName().substring(0, b.getNodeName().indexOf('-'));
                if (nodeName.isEmpty()) {
                    return false;
                }

                // 查询自动执行脚本
                BpmNodeScriptRelevance bpmNodeScriptRelevance = bpmNodeScriptRelevanceService.selectAutoScriptByNodeKey(b.getNodeKey());
                if (bpmNodeScriptRelevance != null) {
                    // 获取执行脚本名称，判断脚本是否存在
                    ResponseEntity<AjaxResult> responseEntity = sending.sendGetNodeScript(bpmNodeScriptRelevance.getScriptKey());
                    if (responseEntity.getStatusCodeValue() != 200L) {
                        return false;
                    }
                    AjaxResult ajaxResult = responseEntity.getBody();
                    if (Long.valueOf(ajaxResult.get("code").toString()) != 200L) {
                        return false;
                    }
                    if (!ajaxResult.containsKey("data")) {
                        return false;
                    }
                    Map<String, Object> dataMap = (Map<String, Object>) ajaxResult.get("data");
                    if (!runImplementationClass.isVerificationMethod(dataMap.get("scriptKey").toString())) {
                        return false;
                    }
                } else {
                    return false;
                }
            } else {
                return false;
            }

            //判断节点是否绑定角色权限,真实角色下是否存在可处理用户，虚拟角色下用户是否都真实存在
            if (StringUtils.isNotEmpty(b.getNodeRolePermission())) {
                BpmNodeHandleUser bpmNodeHandleUser = bpmNodeHandleUserService.selectBpmNodeHandleUserByVirtuallyRole(b.getNodeRolePermission());
                // 真实角色不为空查询真实角色下是否存在可处理用户
                if (StringUtils.isNotEmpty(bpmNodeHandleUser.getRealRole())) {
                    ResponseEntity responseEntity = sending.sendQueryUserExistsByRoleKey(bpmNodeHandleUser.getRealRole());
                    if (responseEntity.getStatusCodeValue() != 200) {
                        return false;
                    }
                    Map<String, Object> map = JSON.parseObject(responseEntity.getBody().toString());
                    if (Long.valueOf(map.get("code").toString()) != 200L) {
                        return false;
                    }
                    if (Long.valueOf(map.get("data").toString()) <= 0L) {
                        return false;
                    }
                }
                // 虚拟角色下用户是否都真实存在
                if (StringUtils.isNotEmpty(bpmNodeHandleUser.getExecuteUserNo())) {
                    ResponseEntity<AjaxResult> responseEntity = sending.sendQueryUserExistsByUserIds(bpmNodeHandleUser.getExecuteUserNo());
                    if (responseEntity.getStatusCodeValue() != 200) {
                        return false;
                    }
                    AjaxResult ajaxResult = responseEntity.getBody();
                    if (Long.valueOf(ajaxResult.get("code").toString()) != 200L) {
                        return false;
                    }
                    if (Long.valueOf(ajaxResult.get("data").toString()) <= 0L) {
                        return false;
                    }
                }
            } else {
                return false;
            }
            //判断当前节点是否是自定义表单类型，是判断该名称是否存在&& '-' 前是否有内容
//            if (b.getNodeFormType().equals("designForm")) {
//                BpmNodeScriptRelevance bpmNodeScriptRelevance = new BpmNodeScriptRelevance();
//                bpmNodeScriptRelevance.setScriptNodeFormType("designForm");
//                bpmNodeScriptRelevance.setNodeKey(b.getNodeKey());
//                List<BpmNodeScriptRelevance> bpmNodeScriptRelevanceList = bpmNodeScriptRelevanceService.selectBpmNodeScriptRelevanceList(bpmNodeScriptRelevance);
//                for (BpmNodeScriptRelevance bpmNodeScriptRelevance1 : bpmNodeScriptRelevanceList) {
//                    if (bpmNodeScriptRelevance1.getScriptNodeName().isEmpty()) {
//                        return false;
//                    }
//                    int separatorIndex = bpmNodeScriptRelevance1.getScriptNodeName().indexOf('-');
//                    if (separatorIndex <= -1) {
//                        return false;
//                    }
//                    String scriptNodeName = bpmNodeScriptRelevance1.getScriptNodeName().substring(0, bpmNodeScriptRelevance1.getScriptNodeName().indexOf('-'));
//                    if (scriptNodeName.isEmpty()) {
//                        return false;
//                    }
//                }
//            }
            //判断当前节点是否是拖拽表单类型，是查询drag_form表查看该表单是否存在
//            if (b.getNodeFormType().equals("dragForm")) {
//                ResponseEntity<AjaxResult> responseEntity = sending.sendGetFormInfo(Long.valueOf(b.getNodeFormKey()));
//                if (responseEntity.getStatusCodeValue() != 200) {
//                    return false;
//                }
//                if (!responseEntity.getBody().containsKey("data")) {
//                    return false;
//                }
//            }
            //判断当前节点是否是组合表单类型，是查询drag_table_group表查看该表单是否存在
//            if (b.getNodeFormType().equals("composeForm")) {
//                ResponseEntity<AjaxResult> responseEntity = sending.sendGetGroupInfo(b.getNodeFormKey());
//                if (responseEntity.getStatusCodeValue() != 200) {
//                    return false;
//                }
//                if (!responseEntity.getBody().containsKey("data")) {
//                    return false;
//                }
//            }
        }
        if (startNode <= 0 || endNode <= 0) {
            return false;
        }
        return true;
    }

}
