package cn.axzo.workflow.server.controller.web.bpmn;

import cn.axzo.workflow.client.feign.bpmn.ProcessModelApi;
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.request.bpmn.task.BpmnTaskDelegateAssigner;
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.axzo.workflow.core.service.BpmnProcessModelService;
import cn.axzo.workflow.core.service.ExtAxReModelService;
import cn.azxo.framework.common.model.CommonResponse;
import com.alibaba.fastjson.JSON;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
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.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;

import static cn.azxo.framework.common.model.CommonResponse.success;

@Tag(name = "运维管理 - 流程模型")
@Slf4j
@RequestMapping({"/web/v1/api/process/model", "/api/process/model"})
@RestController
@Validated
public class BpmnProcessModelController implements ProcessModelApi {

    @Resource
    private BpmnProcessModelService bpmnProcessModelService;
    @Resource
    private ExtAxReModelService reModelService;

    /**
     * 获取流程模型的查询结果
     */
    @Operation(summary = "流程模型列表")
    @GetMapping("/page")
    @Override
    public CommonResponse<BpmPageResult<BpmnModelDetailVO>> page(@Validated @RequestBody BpmnModelSearchDTO dto) {
        log.info("获取流程模型getModelPage===>>>参数：{}", JSON.toJSONString(dto));
        BpmPageResult<BpmnModelDetailVO> result = bpmnProcessModelService.getModelPage(dto);
        return success(result);
    }

    /**
     * 创建流程,
     * return modelId的主键
     */
    @Operation(summary = "创建流程模型")
    @PostMapping("/create")
    @Override
    public CommonResponse<String> create(@Validated @RequestBody BpmnModelCreateDTO dto) {
        log.info("创建流程createBpmModel===>>>参数：{}", JSON.toJSONString(dto));
        String result = bpmnProcessModelService.createBpmModel(dto);
        return success(result);
    }

    @Operation(summary = "通过 Xml 创建模型", hidden = true)
    @PostMapping("/xml/create")
    public CommonResponse<String> createWithXml() {
        // TODO 不完善的接口
        return success(bpmnProcessModelService.createBpmModelWithXml(""));
    }

    /**
     * 获取模型
     */
    @Operation(summary = "通过模型ID查询指定流程模型")
    @GetMapping("/get")
    @Override
    public CommonResponse<BpmnModelDetailVO> getById(@NotBlank(message = "流程模型 ID 不能为空") @RequestParam String processModelId,
                                                     @NotBlank(message = "租户不能为空") @RequestParam String tenantId) {
        log.info("获取模型getModelDetailById===>>>参数：{}", JSON.toJSONString(processModelId));
        BpmnModelDetailVO result = bpmnProcessModelService.getById(processModelId, tenantId);
        return success(result);
    }


    /**
     * 获取模型
     */
    @Operation(summary = "通过模型KEY查询指定流程模型")
    @GetMapping("/getByKey")
    @Override
    public CommonResponse<BpmnModelDetailVO> getByKey(@NotBlank(message = "流程模型 KEY 不能为空") @RequestParam String processModelKey,
                                                      @NotBlank(message = "租户不能为空") @RequestParam String tenantId) {
        log.info("获取模型getModelDetailByKey===>>>参数：{}", JSON.toJSONString(processModelKey));
        BpmnModelDetailVO result = bpmnProcessModelService.getByKey(processModelKey, tenantId);
        return success(result);
    }

    @Operation(summary = "获取指定模型的扩展属性")
    @GetMapping("/ext")
    @Override
    public CommonResponse<BpmnModelExtVO> getModelExt(@NotBlank(message = "模型 ID 不能为空") @RequestParam(required =
            false) String modelId) {
        log.info("获取指定模型的扩展属性getModelExt===>>>参数：{}", JSON.toJSONString(modelId));
        return success(reModelService.getStatusByModelId(modelId));
    }

    /**
     * 修改流程信息
     */
    @Operation(summary = "更新流程模型")
    @PutMapping("/update")
    @Override
    public CommonResponse<String> update(@Validated @RequestBody BpmnModelUpdateDTO dto) {
        log.info("修改流程信息updateBpmModel===>>>参数：{}", JSON.toJSONString(dto));
        bpmnProcessModelService.updateBpmModel(dto);
        return success();
    }


    /**
     * 部署模型
     * return 部署完成的流程定义Id
     */
    @Operation(summary = "通过模型 ID 部署流程模型")
    @PostMapping("/deploy")
    @Override
    public CommonResponse<String> deployById(@NotBlank(message = "流程模型 ID 不能为空") @RequestParam(required = false) String processModelId,
                                             @RequestParam(required = false) String modelTenantId,
                                             @NotNull(message = "操作人不能为空") BpmnTaskDelegateAssigner operator) {
        log.info("部署模型deployBpmModelById===>>>参数：{}, 租户 ID: {}, operator: {}", JSON.toJSONString(processModelId),
                modelTenantId, operator);
        String result = bpmnProcessModelService.deployBpmModelById(processModelId, modelTenantId, operator);
        return success(result);
    }


    /**
     * 部署模型
     * return 部署完成的流程定义Id
     */
    @Operation(summary = "通过模型 KEY 部署流程模型")
    @PostMapping("/deployByKey")
    @Override
    public CommonResponse<String> deployByKey(@NotBlank(message = "流程模型 KEY 不能为空") @RequestParam(required = false) String processModelKey,
                                              @NotBlank(message = "租户不能为空") @RequestParam(required = false) String modelTenantId,
                                              @NotNull(message = "操作人不能为空") BpmnTaskDelegateAssigner operator) {
        log.info("部署模型deployBpmModelByKey===>>>参数：{}", JSON.toJSONString(processModelKey));
        String result = bpmnProcessModelService.deployBpmModelByKey(processModelKey, modelTenantId, operator);
        return success(result);
    }

    @Operation(summary = "通过模块 ID 取消部署流程模型")
    @PostMapping("/undeploy")
    @Override
    public CommonResponse<Void> unDeployById(String processModelId, String tenantId) {
        log.info("部署模型unDeployBpmModelById===>>>参数：{}", JSON.toJSONString(processModelId));
        bpmnProcessModelService.unDeployBpmModelById(processModelId, tenantId);
        return success();
    }

    /**
     * 删除模型
     */
    @Operation(summary = "删除指定模型 ID 的流程模型")
    @DeleteMapping("/delete")
    @Override
    public CommonResponse<Void> deleteById(@NotBlank(message = "流程模型 ID 不能为空") @RequestParam String processModelId,
                                           @NotBlank(message = "租户不能为空") @RequestParam String tenantId) {
        log.info("删除模型deleteBpmModel===>>>参数：{}", JSON.toJSONString(processModelId));
        bpmnProcessModelService.deleteBpmModelById(processModelId, tenantId);
        return success();
    }

    @Operation(summary = "删除指定模型 KEY 的流程模型")
    @DeleteMapping("/deleteByKey")
    @Override
    public CommonResponse<Void> deleteByKey(@NotBlank(message = "流程模型 KEY 不能为空") @RequestParam String processModelKey,
                                            @NotBlank(message = "租户不能为空") @RequestParam String tenantId) {
        log.info("删除模型deleteBpmModel===>>>参数：{}", JSON.toJSONString(processModelKey));
        bpmnProcessModelService.deleteBpmModelByKey(processModelKey, tenantId);
        return success();
    }

    @Operation(summary = "修改模型状态")
    @PostMapping("/changeStatus")
    @Override
    public CommonResponse<Void> changeStatus(@NotBlank(message = "模型 ID 不能为空") @RequestParam String modelId,
                                             @NotNull(message = "状态不能为空") @RequestParam Integer status) {
        log.info("修改模型状态changeStatus===>>>参数：{}", JSON.toJSONString(modelId));
        bpmnProcessModelService.changeStatus(modelId, status);
        return success();
    }
}
