package com.njcn.bpm.service.task;

import com.njcn.bpm.pojo.dto.BpmProcessInstanceCreateReqDTO;
import com.njcn.bpm.pojo.dto.PageResult;
import com.njcn.bpm.pojo.param.instance.BpmProcessInstanceCancelParam;
import com.njcn.bpm.pojo.param.instance.BpmProcessInstancePageParam;
import com.njcn.bpm.pojo.param.task.BpmTaskRejectParam;
import org.flowable.engine.TaskService;
import org.flowable.engine.delegate.event.FlowableCancelledEvent;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.runtime.ProcessInstance;

import javax.validation.Valid;
import java.util.List;
import java.util.Map;
import java.util.Set;

import static com.njcn.bpm.utils.CollectionUtils.convertMap;


/**
 * 流程实例 Service 接口
 *
 * @author hongawen
 */
public interface IBpmProcessInstanceService {

    /**
     * 获得流程实例
     *
     * @param id 流程实例的编号
     * @return 流程实例
     */
    ProcessInstance getProcessInstance(String id);


    /**
     * 创建流程实例（提供给内部）
     *
     * @param userId       用户编号
     * @param createReqDTO 创建信息
     * @return 实例的编号
     */
    String createProcessInstance(String userId, BpmProcessInstanceCreateReqDTO createReqDTO);



    /**
     * 获得流程实例列表
     *
     * @param ids 流程实例的编号集合
     * @return 流程实例列表
     */
    List<ProcessInstance> getProcessInstances(Set<String> ids);

    /**
     * 获得流程实例 Map
     *
     * @param ids 流程实例的编号集合
     * @return 流程实例列表 Map
     */
    default Map<String, ProcessInstance> getProcessInstanceMap(Set<String> ids) {
        return convertMap(getProcessInstances(ids), ProcessInstance::getProcessInstanceId);
    }

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

    /**
     * 获得历史的流程实例列表
     *
     * @param ids 流程实例的编号集合
     * @return 历史的流程实例列表
     */
    List<HistoricProcessInstance> getHistoricProcessInstances(Set<String> ids);

    /**
     * 获得历史的流程实例 Map
     *
     * @param ids 流程实例的编号集合
     * @return 历史的流程实例列表 Map
     */
    default Map<String, HistoricProcessInstance> getHistoricProcessInstanceMap(Set<String> ids) {
        return convertMap(getHistoricProcessInstances(ids), HistoricProcessInstance::getId);
    }

    /**
     * 获得流程实例的分页
     *
     * @param userId    用户编号
     * @param bpmProcessInstancePageParam 分页请求
     * @return 流程实例的分页
     */
    PageResult<HistoricProcessInstance> getProcessInstancePage(String userId, BpmProcessInstancePageParam bpmProcessInstancePageParam);

    List<HistoricProcessInstance> getRejectProcessInstanceList(String userIndex, Set<String> instanceIdSet);


//
//    /**
//     * 创建流程实例（提供给前端）
//     *
//     * @param userId      用户编号
//     * @param createReqVO 创建信息
//     * @return 实例的编号
//     */
//    String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqVO createReqVO);
//


    /**
     * 发起人取消流程实例
     *
     * @param userId      用户编号
     * @param cancelReqVO 取消信息
     */
    void cancelProcessInstanceByStartUser(String userId,  BpmProcessInstanceCancelParam cancelReqVO);


    /**
     * 管理员取消流程实例
     *
     * @param userId           用户编号
     * @param cancelReqVO 取消信息
     */
    void cancelProcessInstanceByAdmin(String userId, BpmProcessInstanceCancelParam cancelReqVO);

    /**
     * 更新 ProcessInstance 拓展记录为取消
     *
     * @param event 流程取消事件
     */
    void updateProcessInstanceWhenCancel(FlowableCancelledEvent event);

    /**
     * 更新 ProcessInstance 拓展记录为完成
     *
     * @param instance 流程任务
     */
    void updateProcessInstanceWhenApprove(ProcessInstance instance);

    /**
     * 更新 ProcessInstance 拓展记录为不通过
     *
     * @param id     流程编号
     * @param reason 理由。例如说，审批不通过时，需要传递该值
     */
    void updateProcessInstanceReject(String id, String reason);

    /**
     * 更新 ProcessInstance 拓展记录为不通过
     *
     * @param id     流程编号
     * @param reason 理由。例如说，审批不通过时，需要传递该值
     */
    void updateProcessInstanceFromReject(String id, String reason, TaskService taskService, BpmTaskRejectParam bpmTaskRejectParam);
    /**
     * 用于测试过程删除流程,正式环境慎用
     * @author cdf
     * @date 2024/5/20
     */
    void delete(String id, String reason);


}
