package cn.datax.service.workflow.service.impl;

import cn.datax.common.utils.SecurityUtil;
import cn.datax.service.workflow.api.dto.ProcessInstanceCreateRequest;
import cn.datax.service.workflow.api.query.FlowInstanceQuery;
import cn.datax.service.workflow.service.FlowInstanceService;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.flowable.common.engine.impl.identity.Authentication;
import org.flowable.engine.HistoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.engine.runtime.ProcessInstanceBuilder;
import org.flowable.engine.runtime.ProcessInstanceQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.util.List;

@Slf4j
@Service
public class FlowInstanceServiceImpl implements FlowInstanceService {

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private HistoryService historyService;

    @Override
    public void page(FlowInstanceQuery flowInstanceQuery) {
        ProcessInstanceQuery processInstanceQuery = runtimeService.createProcessInstanceQuery();
        if(StrUtil.isNotBlank(flowInstanceQuery.getName())){
            processInstanceQuery.processInstanceNameLike(flowInstanceQuery.getName());
        }
        long count = processInstanceQuery.count();
        List<ProcessInstance> processInstanceList = processInstanceQuery.orderByStartTime().desc().listPage((flowInstanceQuery.getPageNum() - 1) * flowInstanceQuery.getPageSize(), flowInstanceQuery.getPageSize());
        Page<ProcessInstance> page = new Page<>(flowInstanceQuery.getPageNum(), flowInstanceQuery.getPageSize());
        page.setRecords(processInstanceList);
        page.setTotal(count);
    }

    @Override
    public void activateProcessInstanceById(String processInstanceId) {
        log.info("成功激活流程实例ID:{}", processInstanceId);
        runtimeService.activateProcessInstanceById(processInstanceId);
    }

    @Override
    public void suspendProcessInstanceById(String processInstanceId) {
        log.info("成功挂起流程实例ID:{}", processInstanceId);
        runtimeService.suspendProcessInstanceById(processInstanceId);
    }

    @Override
    public void deleteProcessInstance(String processInstanceId, String deleteReason) {
        log.info("成功删除流程实例ID:{}", processInstanceId);
        runtimeService.deleteProcessInstance(processInstanceId, deleteReason);
    }

    @Override
    public void startProcessInstanceById(ProcessInstanceCreateRequest request) {
        Assert.notNull(request.getBusinessKey(), "请输入业务id");
        Assert.notNull(request.getBusinessType(), "请输入业务类型");
        Assert.notNull(request.getProcessDefinitionId(), "请输入流程定义ID");
        ProcessInstanceBuilder processInstanceBuilder = runtimeService.createProcessInstanceBuilder();
        if(StrUtil.isNotBlank(request.getProcessDefinitionId())){
            processInstanceBuilder.processDefinitionId(request.getProcessDefinitionId());
        }
        if(StrUtil.isNotBlank(request.getBusinessKey())){
            processInstanceBuilder.businessKey(request.getBusinessKey());
        }
        processInstanceBuilder.variables(request.getVariables());
        // 流程实例标题(动态拼接)
        if(StrUtil.isNotBlank(request.getBusinessName())){
            processInstanceBuilder.name(request.getBusinessName());
        }
        Authentication.setAuthenticatedUserId(SecurityUtil.getUserId());
        ProcessInstance processInstance = processInstanceBuilder.start();
        Authentication.setAuthenticatedUserId(null);
        log.info("发起流程成功，流程ID:{}", processInstance.getId());
    }

//    // 本人参与的流程实例
//    historyService.createHistoricProcessInstanceQuery().involvedUser(SecurityUtil.getUserId()).orderByProcessInstanceStartTime().desc().list();
//    // 本人发起的流程实例
//    historyService.createHistoricProcessInstanceQuery().startedBy(SecurityUtil.getUserId()).orderByProcessInstanceStartTime().desc().list();
}
