package cn.axzo.workflow.client.feign.bpmn;

import cn.axzo.workflow.common.model.request.bpmn.task.BpmnRobotTaskCompleteDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnRobotTaskCreateDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAttachmentDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAuditDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskCommentDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskCountersignDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskPageSearchDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskRemindDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskTransferDTO;
import cn.axzo.workflow.common.model.response.BpmPageResult;
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnHistoricTaskInstanceGroupVO;
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnHistoricTaskInstanceVO;
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnTaskDonePageItemVO;
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnTaskInstanceVO;
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnTaskTodoPageItemVO;
import cn.azxo.framework.common.model.CommonResponse;
import io.swagger.v3.oas.annotations.Operation;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;

import javax.annotation.Nullable;
import javax.validation.constraints.NotBlank;
import java.util.List;


/**
 * 流程任务 API
 *
 * @author wangli
 * @since 2023/9/21 16:26
 */
@FeignClient(name = "workflow-engine", url = "${axzo.service.workflow-engine:http://workflow-engine:8080}")
public interface ProcessTaskApi {

    /**
     * 待审核列表
     */
    @GetMapping("/api/process/task/page/todo")
    CommonResponse<BpmPageResult<BpmnTaskTodoPageItemVO>> getTodoTaskPage(@Validated @RequestBody BpmnTaskPageSearchDTO dto);

    /**
     * 已完成的审批列表
     */
    @GetMapping("/api/process/task/page/done")
    CommonResponse<BpmPageResult<BpmnTaskDonePageItemVO>> getDoneTaskPage(@Validated @RequestBody BpmnTaskPageSearchDTO dto);

    /**
     * 获取指定流程实例的审批过程信息
     * <p>
     * 同一层级结构
     */
    @GetMapping("/api/process/task/list/flat")
    CommonResponse<List<BpmnHistoricTaskInstanceVO>> getTaskListFlatByProcessInstanceId(@NotBlank(message = "流程实例 ID " +
            "不能为空") @RequestParam String processInstanceId, @Nullable @RequestParam(required = false) String tenantId);

    /**
     * 获取指定流程实例的审批过程信息
     * <p>
     * 分组结构
     */
    @GetMapping("/api/process/task/list/group")
    CommonResponse<List<BpmnHistoricTaskInstanceGroupVO>> getTaskListGroupByProcessInstanceId(@NotBlank(message =
            "流程实例 ID 不能为空") @RequestParam String processInstanceId, @Nullable @RequestParam(required = false) String tenantId);

    /**
     * 获取实例正在审核的人列表
     */
    @GetMapping("/api/process/task/active/list")
    CommonResponse<List<BpmnTaskInstanceVO>> getActiveTasksByProcessInstanceId(@NotBlank(message = "流程实例 ID 不能为空") @RequestParam String processInstanceId, @NotBlank(message = "租户不能为空") @RequestParam String tenantId);

    /**
     * 同意
     *
     * <pre>
     * MQ 触发规则:
     *  1. 当前审批任务会依次触发 process-task-completed 和 process-task-deleted 事件(如果有下一级审批,则会触发第 2.1 点中的事件,
     *  如果当前审核任务最后一级审批,则会触发第 2.2 点中的事件)
     *  2.1. 下一级审批任务会依次触发 process-task-assigned 和 process-task-created 事件
     *  2.2. 流程实例正常结束会触发 process-instance-completed 事件
     * </pre>
     */
    @PostMapping("/api/process/task/approve")
    CommonResponse<Boolean> approveTask(@Validated @RequestBody BpmnTaskAuditDTO dto);

    /**
     * 驳回
     *
     * <pre>
     * MQ 触发规则:
     *   1. 当前审批任务会触发 process-task-deleted 事件
     *   2. 当前流程实例会触发 process-instance-rejected 事件
     * </pre>
     */
    @PostMapping("/api/process/task/reject")
    CommonResponse<Boolean> rejectTask(@Validated @RequestBody BpmnTaskAuditDTO dto);

    /**
     * 转交
     *
     * @param dto
     * @return
     */
    @Operation(summary = "直接修改审批任务的审批人")
    @PostMapping("/api/process/task/transfer")
    CommonResponse<Boolean> transferTask(@Validated @RequestBody BpmnTaskTransferDTO dto);

    /**
     * 评论
     *
     * @param dto 评论请求参数
     * @return
     */
    @Operation(summary = "审批流程评论")
    @PostMapping("/api/process/task/comment")
    CommonResponse<Boolean> commentTask(@Validated @RequestBody BpmnTaskCommentDTO dto);

    /**
     * 添加附件
     *
     * @param dto
     * @return
     */
    @Operation(summary = "添加附件")
    @PostMapping("/api/process/task/attachment")
    CommonResponse<Void> addAttachment(@Validated @RequestBody BpmnTaskAttachmentDTO dto);

    /**
     * 加签
     *
     * @param dto 加签请求参数
     * @return
     */
    @Operation(summary = "审批流程加签")
    @PostMapping("/api/process/task/countersign")
    CommonResponse<Boolean> countersignTask(@Validated @RequestBody BpmnTaskCountersignDTO dto);

    /**
     * 催办
     *
     * @param dto
     * @return
     */
    @Operation(summary = "审批流程催办")
    @PostMapping("/api/process/task/remind")
    CommonResponse<Boolean> remindTask(@Validated @RequestBody BpmnTaskRemindDTO dto);

    /**
     * 暂停流程任务,并创建机器人节点,等待业务推动
     *
     * @param dto
     * @return 返回机器人节点任务 ID
     */
    @Operation(summary = "创建机器人节点, 暂停流程任务")
    @PostMapping("/api/process/task/robot/create")
    CommonResponse<String> createRobotTask(@Validated @RequestBody BpmnRobotTaskCreateDTO dto);

    /**
     * 完成机器人节点
     *
     * @param dto
     * @return
     */
    @Operation(summary = "完成机器人节点, 继续流程任务")
    @PostMapping("/api/process/task/robot/complete")
    CommonResponse<Boolean> completeRobotTask(@Validated @RequestBody BpmnRobotTaskCompleteDTO dto);

    /**
     * 根据实例 ID 和自然人 ID 查询对应待处理的任务 ID
     *
     * @return
     */
    @Operation(summary = "根据实例 ID 和自然人 ID 查询对应待处理的任务 ID")
    @GetMapping("/api/process/task/find")
    CommonResponse<String> findTaskIdByInstanceIdAndPersonId(@RequestParam(required = false) @NotBlank(message = "流程实例 ID 不能为空") String processInstanceId,
                                                             @RequestParam(required = false) @NotBlank(message = "自然人 ID 不能为空") String personId);
}
