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

import cn.axzo.workflow.common.model.request.bpmn.model.BpmnModelCreateDTO;
import cn.axzo.workflow.common.model.request.bpmn.model.BpmnModelSearchDTO;
import cn.axzo.workflow.common.model.request.bpmn.model.BpmnModelUpdateDTO;
import cn.axzo.workflow.common.model.response.BpmPageResult;
import cn.axzo.workflow.common.model.response.bpmn.model.BpmnModelDetailVO;
import cn.axzo.workflow.common.model.response.bpmn.model.BpmnModelExtVO;
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.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.List;

/**
 * 流程模型 API
 *
 * @author wangli
 * @since 2023/9/21 15:47
 */
@FeignClient(name = "workflow-engine", url = "${axzo.service.workflow-engine:http://workflow-engine:8080}")
public interface ProcessModelApi {

    /**
     * 流程模型列表
     *
     * @param dto
     * @return
     */
    @Operation(summary = "流程模型列表")
    @GetMapping("/api/process/model/page")
    CommonResponse<BpmPageResult<BpmnModelDetailVO>> page(@Validated @RequestBody BpmnModelSearchDTO dto);

    /**
     * 创建流程,
     * return modelId的主键
     */
    @Operation(summary = "创建流程模型")
    @PostMapping("/api/process/model/create")
    CommonResponse<String> create(@Validated @RequestBody BpmnModelCreateDTO dto);

    /**
     * 通过模型 ID 获取模型
     */
    @Operation(summary = "通过模型ID查询指定流程模型")
    @GetMapping("/api/process/model/get")
    CommonResponse<BpmnModelDetailVO> getById(@NotBlank(message = "流程模型 ID 不能为空") @RequestParam(required = false) String processModelId,
                                              @RequestParam(required = false) String tenantId);

    /**
     * 通过模型 KEY 获取模型
     */
    @Operation(summary = "通过模型KEY查询指定流程模型")
    @GetMapping("/api/process/model/getByKey")
    CommonResponse<BpmnModelDetailVO> getByKey(@NotBlank(message = "流程模型 KEY 不能为空") @RequestParam(required = false) String processModelKey,
                                               @NotBlank(message = "租户不能为空") @RequestParam(required = false) String tenantId);

    /**
     * 校验是否能更新模型即其关联的流程定义内容
     * <p>
     * 偏向业务的接口,flowable 引擎是站在流程定义维度进行激活和挂起
     *
     * @return true 能更新,表明该模型关联的所有定义版本都是挂起状态
     */
    @Operation(summary = "获取指定模型的扩展属性")
    @GetMapping("/api/process/model/ext")
    CommonResponse<BpmnModelExtVO> getModelExt(@NotBlank(message = "模型 ID 不能为空") @RequestParam(required = false) String modelId);

    /**
     * 修改流程信息
     */
    @Operation(summary = "更新流程模型")
    @PutMapping("/api/process/model/update")
    CommonResponse<String> update(@RequestBody BpmnModelUpdateDTO dto);


    /**
     * 通过模型 ID 部署模型
     *
     * @return 部署完成的流程定义Id
     */
    @Operation(summary = "通过模型 ID 部署流程模型")
    @PostMapping("/api/process/model/deploy")
    CommonResponse<String> deployById(@NotBlank(message = "流程模型 ID 不能为空") @RequestParam(required = false) String processModelId,
                                      @RequestParam(required = false, defaultValue = "") String modelTenantId,
                                      @RequestParam(required = false) String operator);

    /**
     * 通过模型 KEY 部署模型
     *
     * @return 部署完成的流程定义Id
     */
    @Operation(summary = "通过模型 KEY 部署流程模型")
    @PostMapping("/api/process/model/deployByKey")
    CommonResponse<String> deployByKey(@NotBlank(message = "流程模型 KEY 不能为空") @RequestParam(required = false) String processModelKey,
                                       @NotBlank(message = "租户不能为空") @RequestParam(required = false) String modelTenantId,
                                       @RequestParam(required = false) String operator);

    /**
     * 通过模型 ID 取消部署流程模型
     *
     * @param processModelId
     * @param tenantId
     * @param operator
     * @return
     */
    @Operation(summary = "通过模型 ID 取消部署流程模型")
    @PostMapping("/api/process/model/undeploy")
    CommonResponse<Void> unDeployById(@NotBlank(message = "流程模型 ID 不能为空") @RequestParam(required = false) String processModelId,
                                      @RequestParam(required = false, defaultValue = "") String tenantId,
                                      @RequestParam(required = false) String operator);

    /**
     * 通过模型 ID 删除模型
     */
    @Operation(summary = "删除指定模型 ID 的流程模型")
    @DeleteMapping("/api/process/model/delete")
    CommonResponse<Void> deleteById(@NotBlank(message = "流程模型 ID 不能为空") @RequestParam String processModelId,
                                    @RequestParam(required = false, defaultValue = "") String tenantId);

    /**
     * 通过模型 KEY 删除模型
     *
     * @param processModelKey
     * @param tenantId
     * @return
     */
    @Operation(summary = "删除指定模型 KEY 的流程模型")
    @DeleteMapping("/api/process/model/deleteByKey")
    CommonResponse<Void> deleteByKey(@NotBlank(message = "流程模型 KEY 不能为空") @RequestParam String processModelKey,
                                     @RequestParam(required = false, defaultValue = "") String tenantId);

    /**
     * 通过模型 ID 修改模型状态
     *
     * @param modelId
     * @param status
     * @param operator
     * @return
     */
    @Operation(summary = "修改模型状态")
    @PostMapping("/api/process/model/changeStatus")
    CommonResponse<Void> changeStatus(@NotBlank(message = "模型 ID 不能为空") @RequestParam String modelId,
                                      @NotNull(message = "状态不能为空") @RequestParam Integer status,
                                      @RequestParam(required = false) String operator);

    /**
     * 查询流程模型使用的分类列表
     *
     * @return
     */
    @Operation(summary = "查询流程模型使用的分类列表")
    @GetMapping("/api/process/model/category/ids")
    CommonResponse<List<String>> getModelCategoryList();

    /**
     * 查询模型的租户集合
     *
     * @return
     */
    @Operation(summary = "查询模型的租户集合")
    @GetMapping("/api/process/model/tenant/ids")
    CommonResponse<List<String>> getTenantIds();
}
