package com.tykj.workflowcore.workflow_editer.listener;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;
import com.tykj.workflowcore.api.controller.ApiController;
import com.tykj.workflowcore.api.entity.InvokeRequest;
import com.tykj.workflowcore.api.entity.Parameter;
import com.tykj.workflowcore.workflow_editer.entity.CommandGetValue;
import com.tykj.workflowcore.workflow_editer.entity.DataHistory;
import com.tykj.workflowcore.workflow_editer.entity.VariableStorage;
import com.tykj.workflowcore.workflow_editer.entity.vo.InvokeRequestVo;
import com.tykj.workflowcore.workflow_editer.entity.vo.ParameterVo;
import com.tykj.workflowcore.workflow_editer.entity.vo.SearchVariableStorageVo;
import com.tykj.workflowcore.workflow_editer.service.DataHistoryService;
import com.tykj.workflowcore.workflow_editer.service.VariableStorageService;
import org.flowable.bpmn.model.*;
import liquibase.pro.packaged.I;
import org.flowable.bpmn.model.EndEvent;
import org.flowable.common.engine.api.delegate.Expression;
import org.flowable.common.engine.api.delegate.event.FlowableEngineEntityEvent;
import org.flowable.common.engine.api.delegate.event.FlowableEvent;
import org.flowable.engine.*;
import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.delegate.event.AbstractFlowableEngineEventListener;
import org.flowable.engine.delegate.event.FlowableActivityEvent;
import org.flowable.engine.delegate.event.impl.FlowableActivityEventImpl;
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.flowable.engine.impl.persistence.entity.ExecutionEntity;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.impl.persistence.entity.ExecutionEntityImpl;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;


import java.util.*;

/**
 * @author HuangXiahao
 * @version V1.0
 * @class ProcessEndListener
 * @packageName com.tykj.workflowcore.workflow_editer.listener
 **/
@Component
public class ProcessEndListener extends AbstractFlowableEngineEventListener {

    @Autowired
    RuntimeService runtimeService;

    @Autowired
    RepositoryService repositoryService;

    @Autowired
    FormService formService;

    @Autowired
    VariableStorageService variableStorageService;

    @Autowired
    ProcessEngineConfigurationImpl processEngineConfiguration;

    @Autowired
    ApiController apiController;

    @Autowired
    TaskService taskService;

    @Autowired
    DataHistoryService dataHistoryService;

    @Override
    protected void processCompleted(FlowableEngineEntityEvent event) {
        //流程结束了
//        if (event.getEntity() instanceof ProcessInstance){
//            ProcessInstance processInstance = (ProcessInstance) event.getEntity();
//            String processDefinitionId = processInstance.getProcessDefinitionId();
//            String flowKey = processDefinitionId;
//            if (processDefinitionId.indexOf(":")>=0){
//                flowKey = processDefinitionId.substring(0,processDefinitionId.indexOf(":"));
//            }
//            List<VariableStorage> variableStorageList = variableStorageService.searchVariableStorageList(new SearchVariableStorageVo(flowKey));
//            for (VariableStorage variableStorage : variableStorageList) {
//                InvokeRequestVo variableInfo = variableStorage.getInvokeRequest();
//                variableInfo.setProcessInstance(processInstance);
//                //调用服务接口
//
//                //1. 获取调用的具体数值
//                apiController.invoke(getApiInvokeParam(variableInfo));
//            }
//        }
//        throw new ApiException("强行报错");
    }

    @Override
    protected void taskCompleted(FlowableEngineEntityEvent event) {
        super.taskCompleted(event);
    }

    @Override
    public void onEvent(FlowableEvent flowableEvent) {
        super.onEvent(flowableEvent);
    }

    @Override
    protected void activityCompleted(FlowableActivityEvent event) {
        super.activityCompleted(event);
        if (event instanceof FlowableActivityEventImpl){
            DelegateExecution execution = ((FlowableActivityEventImpl) event).getExecution();
            if (execution.getCurrentFlowElement() instanceof EndEvent){
                System.out.println("流程结束了");
                String processDefinitionId = ((ExecutionEntityImpl) execution).getProcessDefinitionKey();
                String flowKey = processDefinitionId;
                if (processDefinitionId.indexOf(":")>=0){
                    flowKey = processDefinitionId.substring(0,processDefinitionId.indexOf(":"));
                }
                List<VariableStorage> variableStorageList = variableStorageService.searchVariableStorageList(new SearchVariableStorageVo(flowKey,execution.getCurrentActivityId()));
                for (VariableStorage variableStorage : variableStorageList) {
                    List<ParameterVo> parameterVoList = variableStorage.getParameterInfo();
                    InvokeRequest invokeRequest = new InvokeRequest();
                    invokeRequest.setClassName(variableStorage.getClassName());
                    invokeRequest.setName(variableStorage.getMethod());
                    invokeRequest.setParams(getApiInvokeParam(parameterVoList,execution));
                    //调用服务接口
                    apiController.invoke(invokeRequest);
                }
            }

            if (execution.getCurrentFlowElement() instanceof StartEvent){
                DataHistory dataHistory = new DataHistory();
                StartEvent startEvent = (StartEvent) execution.getCurrentFlowElement();
                //实例id
                String processInstanceId = execution.getProcessInstanceId();
                String processInstanceBusinessKey = execution.getProcessInstanceBusinessKey();
                System.out.println(processInstanceBusinessKey);
                String nodeId = execution.getCurrentActivityId();
                String formKey = startEvent.getFormKey();
                //通过formKey查询出页面

            }
            if (execution.getCurrentFlowElement() instanceof UserTask){
                //查询任务
                Task task = taskService.createTaskQuery().singleResult();
                Map<String, Object> variables = taskService.getVariables(task.getId());
                DataHistory dataHistory = new DataHistory();
                String datas = JSON.toJSONString(variables);
                //流程实例id
                String processInstanceId = task.getProcessInstanceId();
                //当前节点id
                String nodeId = task.getTaskDefinitionKey();


//                dataHistory.setTaskId(taskId);
                dataHistory.setDatas(datas);
                dataHistory.setNodeId(nodeId);
                dataHistory.setProcessInstanceId(processInstanceId);
                dataHistoryService.saveData(dataHistory);
            }
        }
    }

    /**
     * 获取调用Api用的参数
     *
     * @param parameterVoList 调用服务接口vo
     * @return 调用服务接口实体
     */
    public List<Parameter> getApiInvokeParam(List<ParameterVo> parameterVoList,DelegateExecution execution) {
        //拿出taskId
        List<Parameter> parameterList = new ArrayList<>();
        for (int i = 0; i < parameterVoList.size(); i++) {
            ParameterVo parameterVo = parameterVoList.get(i);
            Parameter parameter = new Parameter();
            parameter.setClassName(parameterVo.getClassName());
            Map<String, Object> instance = new HashMap<>();
            FillParameter(instance,parameterVoList.get(i),execution);
            parameter.setInstance((Map<String, Object>) instance.get(parameterVo.getName()));
            parameterList.add(parameter);
        }
        return parameterList;
    }

    public Map<String, Object> FillParameter(Map<String, Object> instance,ParameterVo parameterVo,DelegateExecution execution){
        if (!StringUtils.isEmpty(parameterVo.getExp())) {
            //如果是表示式  如：${people}
            instance.put(parameterVo.getName(),getProcessValue(execution, parameterVo.getExp()));
        }else {
            instance.put(parameterVo.getName(),"");
        }
        List<ParameterVo> parameterVoList = parameterVo.getParameterVoList();
        if (parameterVoList!=null&&parameterVoList.size()>0){
            for (int i = 0; i < parameterVoList.size() ; i++) {
                FillParameter(instance,parameterVoList.get(i),execution);
            }
        }
        return instance;
    }

    public Object getProcessValue(DelegateExecution execution, String exp) {
        // processInstance -> ExecutionEntity
        Expression expression = processEngineConfiguration.getExpressionManager().createExpression(exp);
        return expression.getValue(execution);
    }

}
