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

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yeejoin.amos.boot.biz.common.utils.RedisUtils;
import com.yeejoin.amos.boot.module.jg.api.dto.WorkFlowPublicInfo;
import com.yeejoin.amos.boot.module.jg.flc.api.fegin.WorkFlowFeignService;
import com.yeejoin.amos.component.feign.model.FeignClientResult;
import com.yeejoin.amos.feign.workflow.Workflow;
import com.yeejoin.amos.feign.workflow.model.ActWorkflowBatchDTO;
import com.yeejoin.amos.feign.workflow.model.ActWorkflowStartDTO;
import com.yeejoin.amos.feign.workflow.model.AjaxResult;
import com.yeejoin.amos.feign.workflow.model.TaskResultDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.*;

/**
 * 工作流公共方法类
 */
@Slf4j
@Service
public class PublicWorkFlowService {

    @Autowired
    WorkFlowFeignService workFlowFeignService;

    @Autowired
    RedisUtils redisUtils;

    /**
     * 批量启动工作流 并执行一步
     *
     * @param processDefinitionKey 流程key
     * @param size                 启动数量
     * @param isTaskNameOrCode     是否需要下一步执行的任务code和name
     */
    public List<WorkFlowPublicInfo> batchStartWorkFlowPublic(String processDefinitionKey, int size, Boolean isTaskNameOrCode) {
        ActWorkflowBatchDTO actWorkflowBatchDTO = new ActWorkflowBatchDTO();
        List<ActWorkflowStartDTO> list = new ArrayList<>();
        for (int i = 0; i < size; i++) {
            ActWorkflowStartDTO dto = new ActWorkflowStartDTO();
            dto.setProcessDefinitionKey(processDefinitionKey);
            dto.setBusinessKey(String.valueOf(i));
            list.add(dto);
        }
        actWorkflowBatchDTO.setProcess(list);
        try {
            FeignClientResult result = Workflow.taskV2Client.startByVariableBatch(actWorkflowBatchDTO);
            List<Object> returnList = (List<Object>) result.getResult();
            List<WorkFlowPublicInfo> resultList = new ArrayList<>();
            for (Object obj : returnList) {
                WorkFlowPublicInfo resultMap = new WorkFlowPublicInfo();
                JSONObject jsonObject = JSON.parseObject(JSONObject.toJSONString(obj));
                String instanceId = jsonObject.getString("id");

                //填充流程实例ID
                resultMap.setInstanceId(instanceId);

                //发起节点相关信息  ----- 【第一节点信息/启动节点信息】
                WorkFlowPublicInfo firstInfo = getNextInfoPublic(instanceId, isTaskNameOrCode);

                // 推动下一个节点
                AjaxResult ajaxResult = Workflow.taskClient.getTask(instanceId);
                JSONObject dataObject = JSON.parseObject(JSON.toJSONString(ajaxResult.get("data")));
                String taskId = dataObject.getString("id");
                //组装信息
                TaskResultDTO dto = new TaskResultDTO();
                dto.setResultCode("approvalStatus");
                dto.setTaskId(taskId);
                dto.setComment("提交流程");
                HashMap<String, Object> map = new HashMap<>();
                map.put("approvalStatus", "0");
                dto.setVariable(map);
                //执行流程
                AjaxResult ajaxResult1 = null;
                try {
                    ajaxResult1 = Workflow.taskClient.completeByTask(taskId, dto);
                    if (ajaxResult1.get("code").equals(200)) {

                        //第二节点相关信息  ----- 【第二节点信息】
                        WorkFlowPublicInfo nextInfo = getNextInfoPublic(instanceId, isTaskNameOrCode);

                        resultMap.setNextTaskName(nextInfo.getNextTaskName());
                        resultMap.setNextTaskCode(nextInfo.getNextTaskCode());
                        resultMap.setNextRoleList(nextInfo.getNextRoleList());

                        List<String> firstRoleList = firstInfo.getNextRoleList();
                        firstRoleList.addAll(nextInfo.getNextRoleList());
                        resultMap.setAllRoleList(firstRoleList);
                        resultList.add(resultMap);
                    } else {
                        log.error("提交失败");
                    }
                } catch (Exception e) {
                    log.error("提交失败：{}", e);
                }
            }
            return resultList;
        } catch (Exception e) {
            log.error("提交失败：{}", e);
        }
        return Collections.emptyList();
    }


    /**
     * 工作流执行操作 【包括通过和驳回】
     *
     * @param instanceId 流程实例ID
     * @param operate    提交、0、1     0-通过、1-驳回、提交-驳回、撤回后提交
     * @param comment    内容
     */
    public WorkFlowPublicInfo flowExecutePublic(String instanceId, String operate, String comment) {
        try {
            AjaxResult task = Workflow.taskClient.getTaskNoAuth(instanceId);

            JSONObject nextTask = JSON.parseObject(JSON.toJSONString(task.get("data")));
            String taskId = nextTask.getString("id");
            //组装信息
            TaskResultDTO dto = new TaskResultDTO();
            dto.setResultCode("approvalStatus");
            dto.setTaskId(taskId);
            dto.setComment(comment);
            HashMap<String, Object> map = new HashMap<>();
            map.put("approvalStatus", operate);
            dto.setVariable(map);
            //执行流程
            Workflow.taskClient.completeByTask(taskId, dto);
            return getNextInfoPublic(instanceId, Boolean.TRUE);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new WorkFlowPublicInfo();
    }

    /**
     * 撤回
     *
     * @param instanceId 流程实例ID
     */
    public WorkFlowPublicInfo revocationPublic(String instanceId) {
        try {
            workFlowFeignService.rollBack(instanceId);
            return getNextInfoPublic(instanceId, true);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new WorkFlowPublicInfo();
    }

    /**
     * 根据instanceId查询下一步执行节点需要的信息
     *
     * @param instanceId       流程实例ID
     * @param isTaskNameOrCode 是否需要code和name
     * @return 具体信息
     */
    public WorkFlowPublicInfo getNextInfoPublic(String instanceId, Boolean isTaskNameOrCode) {
        WorkFlowPublicInfo workFlowPublicInfo = new WorkFlowPublicInfo();
        // 查询下节点信息
        AjaxResult aj = Workflow.taskClient.getTaskNoAuth(instanceId);
        JSONObject nextTask = JSON.parseObject(JSON.toJSONString(aj.get("data")));
        if (!ObjectUtils.isEmpty(nextTask)) {
            String nextTaskId = nextTask.getString("id");

            FeignClientResult<JSONObject> nodeInfo = workFlowFeignService.getNodeInfo(nextTaskId);
            JSONObject result = nodeInfo.getResult();
            Map<String, Object> taskInfo = (Map<String, Object>) result.get("taskInfo");
            workFlowPublicInfo.setNextTaskCode(String.valueOf(taskInfo.get("taskDefinitionKey")));

            AjaxResult taskGroupName = Workflow.taskClient.getTaskGroupName(nextTaskId);
            //填充下一步任务名称
            workFlowPublicInfo.setNextTaskName(nextTask.getString("name"));

            JSONArray data = JSON.parseArray(JSON.toJSONString(taskGroupName.get("data")));
            List<String> roleListFirst = new ArrayList<>();
            for (Object datum : data) {
                if (((Map) datum).containsKey("groupId")) {
                    roleListFirst.add(((Map) datum).get("groupId").toString());
                }
            }
            //填充下一步执行权限角色ID集合
            workFlowPublicInfo.setNextRoleList(roleListFirst);
        }
        return workFlowPublicInfo;
    }
}
