package com.tykj.workflowcore.workflow_editer.listener;

import com.alibaba.fastjson.JSONObject;
import com.tykj.workflowcore.base.result.ApiException;
import com.tykj.workflowcore.workflow_editer.entity.DataHistory;
import com.tykj.workflowcore.workflow_editer.entity.FormPage;
import com.tykj.workflowcore.workflow_editer.entity.enums.JavaTypeEnum;
import com.tykj.workflowcore.workflow_editer.entity.vo.ParameterVo;
import com.tykj.workflowcore.workflow_editer.service.DataHistoryService;
import com.tykj.workflowcore.workflow_editer.service.FormPageService;
import org.flowable.bpmn.model.StartEvent;
import org.flowable.bpmn.model.UserTask;
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.springframework.beans.BeanUtils;
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
    ProcessEngineConfigurationImpl processEngineConfiguration;

    @Autowired
    TaskService taskService;

    @Autowired
    DataHistoryService dataHistoryService;

    @Autowired
    FormPageService formPageService;

    @Override
    protected void processCompleted(FlowableEngineEntityEvent event) {
    }

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

    @Override
    public void onEvent(FlowableEvent flowableEvent) {
        System.out.println(flowableEvent.getType().name());
        super.onEvent(flowableEvent);
    }

    @Override
    protected void activityCompleted(FlowableActivityEvent event) {
        super.activityCompleted(event);
        if (event instanceof FlowableActivityEventImpl){
            DelegateExecution execution = ((FlowableActivityEventImpl) event).getExecution();
            initDataHistory(execution);
//                //开始节点
//            if (execution.getCurrentFlowElement() instanceof StartEvent){
//                DataHistory dataHistory = new DataHistory();
//                StartEvent startEvent = (StartEvent) execution.getCurrentFlowElement();
//                //流程id  实例id  pageId  datas userId
//                String processInstanceBusinessKey = execution.getProcessInstanceBusinessKey();
//                dataHistory.setFlowKey(processInstanceBusinessKey);
//                dataHistory.setProcessInstanceId(execution.getProcessInstanceId());
//                dataHistory.setPageId(startEvent.getFormKey());
////                dataHistory.setUserId();
////                dataHistory.setDatas();
//                System.out.println(processInstanceBusinessKey);
//
//                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 processInstanceBusinessKey = execution.getProcessInstanceBusinessKey();
//
////              dataHistory.setTaskId(taskId);
//                dataHistory.setDatas(datas);
//                dataHistory.setProcessInstanceId(processInstanceId);
//                dataHistoryService.saveData(dataHistory);
//            }
        }
    }

    public void initDataHistory(DelegateExecution execution){
        FormPage page = null;
        if (execution.getCurrentFlowElement() instanceof UserTask){
            UserTask userTask = (UserTask) execution.getCurrentFlowElement();
            String formKey = userTask.getFormKey();
            //查询出这个节点的页面
            page = formPageService.getPage(Integer.valueOf(formKey));
        }else
        if (execution.getCurrentFlowElement() instanceof StartEvent){
            StartEvent startEvent = (StartEvent) execution.getCurrentFlowElement();
            String formKey = startEvent.getFormKey();
            //查询出这个节点的页面
            page = formPageService.getPage(Integer.valueOf(formKey));
        }else {
            return;
        }
        DataHistory dataHistory = new DataHistory();
        //查出这个节点内的临时数据
        Map<String, Object> variables = execution.getVariables();
        //设置processInstanceId
        dataHistory.setProcessInstanceId(execution.getProcessInstanceId());
        //设置节点Id
        dataHistory.setExecutionId(execution.getId());
        dataHistory.setProcessInstanceId(execution.getProcessInstanceId());
        dataHistory.setActivityId(execution.getCurrentFlowElement().getId());
        dataHistory.setUniqueString(DataHistory.initUniqueString(dataHistory.getExecutionId(),dataHistory.getProcessInstanceId(),dataHistory.getActivityId()));
        dataHistory.setJs(page.getJs());
        dataHistory.setCss(page.getCss());
        dataHistory.setTemplate(page.getTemplate());
        dataHistory.setDescFile(page.getDescFile());
        dataHistory.setDatas(JSONObject.toJSONString(variables));
        dataHistory.setIndexKey(initDataHistoryIndexKey(dataHistory));
        //保存下来
        dataHistoryService.save(dataHistory);

    }

    public String initDataHistoryIndexKey(DataHistory dataHistory){
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("activityId",dataHistory.getActivityId());
        jsonObject.put("executionId",dataHistory.getExecutionId());
        jsonObject.put("processInstanceId",dataHistory.getProcessInstanceId());
        return jsonObject.toJSONString();
    }


    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 {
            if (instance.get(parameterVo.getName())==null){
                //判断基础类型 为基础类型
                Class<?> aClass = null;
                try {
                    aClass = Class.forName(parameterVo.getClassName());
                }catch (ClassNotFoundException e){
                    throw new ApiException("填充参数时类型转换失败，className:"+parameterVo.getClassName());
                }
                if (checkIn(parameterVo.getClassName())){
                    instance.put(parameterVo.getName(),null);
                }else
                if (Collection.class.isAssignableFrom(aClass)){
                    if (List.class.isAssignableFrom(aClass)){
                        instance.put(parameterVo.getName(),new ArrayList<>());
                    }else {
                        instance.put(parameterVo.getName(),new HashSet<>());
                    }
                }else {
                    instance.put(parameterVo.getName(),new HashMap<>());
                }
            }
        }
        List<ParameterVo> parameterVoList = parameterVo.getFields();
        if (parameterVoList!=null&&parameterVoList.size()>0){
            for (int i = 0; i < parameterVoList.size() ; i++) {
                if (instance.get(parameterVo.getName()) instanceof Map){
                    FillParameter((Map<String, Object>) instance.get(parameterVo.getName()),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);
    }

    public Boolean checkIn(String className){
        JavaTypeEnum[] values = JavaTypeEnum.values();
        for (int i = 0; i < values.length ; i++) {
            if (className.equals(values[i].getName())){
                return true;
            };
        }
        return false;
    }


}
