package cn.axzo.workflow.core.service;

import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceAbortDTO;
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceAdminPageReqVO;
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCancelDTO;
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCarbonCopyDTO;
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCreateDTO;
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCreateWithFormDTO;
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceMyPageReqVO;
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceQueryDTO;
import cn.axzo.workflow.common.model.request.bpmn.process.HistoricProcessInstanceSearchDTO;
import cn.axzo.workflow.common.model.response.BpmPageResult;
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstanceAdminPageItemVO;
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstancePageItemVO;
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstanceVO;
import cn.axzo.workflow.common.model.response.bpmn.process.HistoricProcessInstanceVO;
import cn.axzo.workflow.common.model.response.bpmn.process.ProcessNodeDetailVO;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.form.api.FormInfo;

import javax.annotation.Nullable;
import javax.validation.Valid;
import java.util.List;

public interface BpmnProcessInstanceService {

    /**
     * 发起审核
     */
    String createProcessInstance(BpmnProcessInstanceCreateDTO processInstanceCreateDTO);

    String createProcessInstanceWithForm(BpmnProcessInstanceCreateWithFormDTO createWithFormDTO);

    FormInfo getStartFormModel(String processDefinitionId, String processInstanceId);

    /**
     * 取消流程实例
     *
     * @return true or false, true mean's cancelled
     */
    Boolean cancelProcessInstance(BpmnProcessInstanceCancelDTO processInstanceCancelDTO);

    /**
     * 中止流程实例
     *
     * @param dto
     * @return
     */
    Boolean abortProcessInstance(BpmnProcessInstanceAbortDTO dto);

    /**
     * 抄送流程实例
     *
     * @param dto
     * @return
     */
    Boolean carbonCopyProcessInstance(BpmnProcessInstanceCarbonCopyDTO dto);

    /**
     * 超管查询所有流程实例数据
     *
     * @param dto
     * @return
     */
    BpmPageResult<BpmnProcessInstanceAdminPageItemVO> getAdminProcessInstancePage(BpmnProcessInstanceAdminPageReqVO dto);

    /**
     * 获得流程实例的分页 / 我发起的审批列表
     *
     * @param pageReqVO 分页请求
     * @return 流程实例的分页
     */
    BpmPageResult<BpmnProcessInstancePageItemVO> getMyProcessInstancePage(@Valid BpmnProcessInstanceMyPageReqVO pageReqVO);

    /**
     * 获得流程实例
     *
     * @param businessKey 创建工作流实例时,业务传入的 businessKey
     * @param tenantId    租户 ID,非必传
     * @return 流程实例
     */
    HistoricProcessInstance getProcessInstanceByBusinessKey(String businessKey, @Nullable String tenantId,
                                                            @Nullable Boolean hasVariables);

    /**
     * 获得流程实例
     *
     * @param id          流程实例的编号
     * @param tenantId    租户Id
     * @param hasVariable 查询结果是否包含流程参数，
     * @return 流程实例, 租户Id不必传
     */
    HistoricProcessInstance getProcessInstance(String id, @Nullable String tenantId, @Nullable Boolean hasVariable);

    /**
     * 获得流程实例
     *
     * @param processInstanceId 流程实例的编号
     * @param status            状态
     * @link SuspensionState.ACTIVE.getStateCode()
     */
    Boolean updateProcessStatus(String processDefinitionId, Integer status);

    /**
     * 获得历史的流程实例
     *
     * @param id 流程实例的编号
     * @return 历史的流程实例
     */
    HistoricProcessInstance getHistoricProcessInstance(String id, String tenantId);

    /**
     * 获得流程实例 VO 信息
     *
     * @param processInstanceId 流程实例的编号
     * @param businessKey       业务key
     * @param tenantId          租户 ID
     * @return 流程实例
     */
    BpmnProcessInstanceVO getProcessInstanceVO(BpmnProcessInstanceQueryDTO dto);

    ObjectNode getProcessInstanceGraphical(String processInstanceId, @Nullable String tenantId);

    BpmPageResult<HistoricProcessInstanceVO> historicProcessInstancePage(HistoricProcessInstanceSearchDTO dto);

    /**
     * 流程实例全节点推测
     *
     * @param processInstanceId
     * @param tenantId
     * @return
     */
    List<ProcessNodeDetailVO> getProcessInstanceNodeForecast(String processInstanceId, String tenantId);

    List<ProcessNodeDetailVO> getProcessInstanceNodeFilterForecast(String processInstanceId, String tenantId, List<String> nodeDefinitionKeys);

    List<String> getTenantIds();

}
