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

import cn.axzo.workflow.client.feign.bpmn.ProcessDefinitionApi;
import cn.axzo.workflow.common.model.request.bpmn.definition.BpmnProcessDefinitionUpdateDTO;
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessDefinitionPageDTO;
import cn.axzo.workflow.common.model.response.BpmPageResult;
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessDefinitionVO;
import cn.axzo.workflow.core.service.BpmnProcessDefinitionService;
import cn.axzo.workflow.core.service.converter.BpmnProcessDefinitionConverter;
import cn.azxo.framework.common.model.CommonResponse;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.flowable.common.engine.impl.db.SuspensionState;
import org.flowable.engine.repository.ProcessDefinition;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

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

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

@Slf4j
@RequestMapping({"/web/v1/api/process/definition", "/api/process/definition"})
@RestController
@Validated
public class BpmnProcessDefinitionController implements ProcessDefinitionApi {
    @Resource
    private BpmnProcessDefinitionService bpmnProcessDefinitionService;
    @Resource
    private BpmnProcessDefinitionConverter processDefinitionConverter;

    /**
     * 获取活跃的流程定义分页
     */
    @GetMapping("/page")
    @Override
    public CommonResponse<BpmPageResult<BpmnProcessDefinitionVO>> getProcessDefinitionPage(@Validated @RequestBody BpmnProcessDefinitionPageDTO dto) {
        log.info("获取活跃的流程定义分页getProcessDefinitionPage===>>>参数：{}", JSON.toJSONString(dto));
        return success(bpmnProcessDefinitionService.getProcessDefinitionPage(dto));
    }

    @PutMapping("/update")
    @Override
    public CommonResponse<Boolean> updateProcessDefinition(@Validated @RequestBody BpmnProcessDefinitionUpdateDTO dto) {
        bpmnProcessDefinitionService.updateProcessDefinition(dto);
        return success(true);
    }

    /**
     * 获得编号对应的 ProcessDefinition
     *
     * @param processDefinitionId 定义编号
     * @return 流程定义
     */
    @GetMapping("/get")
    @Override
    public CommonResponse<BpmnProcessDefinitionVO> getProcessDefinition(@NotBlank(message = "流程定义 ID 不能为空") @RequestParam String processDefinitionId) {
        log.info("获取活跃的流程定义分页getProcessDefinition===>>>参数：{}", JSON.toJSONString(processDefinitionId));
        return success(bpmnProcessDefinitionService.getProcessDefinition(processDefinitionId));
    }


    /**
     * 获得 deploymentId 对应的 ProcessDefinition
     *
     * @param deploymentId 部署编号
     * @return 流程定义
     */
    @GetMapping("/getByDeploymentId")
    @Override
    public CommonResponse<BpmnProcessDefinitionVO> getProcessDefinitionByDeploymentId(
            @NotBlank(message = "流程部署 ID 不能为空") @RequestParam String deploymentId) {
        log.info(" 获得 deploymentId 对应的 getProcessDefinitionByDeploymentId===>>>参数：{}", JSON.toJSONString(deploymentId));
        ProcessDefinition result = bpmnProcessDefinitionService.getProcessDefinitionByDeploymentId(deploymentId);
        return success(processDefinitionConverter.toVo(result));
    }


    /**
     * 获得流程定义标识对应的激活的流程定义
     *
     * @param key 流程定义的标识
     * @return 流程定义
     */
    @GetMapping("/active/getByKey")
    @Override
    public CommonResponse<BpmnProcessDefinitionVO> getActiveProcessDefinitionByKey(@NotBlank(message =
            "模型定义KEY" +
                    "不能为空") @RequestParam String key) {
        log.info("获得流程定义标识对应的激活的流程定义 getActiveProcessDefinitionByKey===>>>参数：{}", JSON.toJSONString(key));
        return success(bpmnProcessDefinitionService.getActiveProcessDefinitionByKey(key, key));
    }

    /**
     * 获取指定
     *
     * @param deploymentId
     * @return
     */
    public CommonResponse<Boolean> hasActiveProcessDefinition(String deploymentId) {
        log.info("获得流程定义标识对应的激活的流程定义 getActiveProcessDefinitionByKey===>>>参数：{}", JSON.toJSONString(deploymentId));
        return success(bpmnProcessDefinitionService.hasActiveProcessDefinition(deploymentId));
    }

    /**
     * 挂起/激活流程，
     * 激活：SuspensionState.ACTIVE.getStateCode()
     * 挂起：SuspensionState.SUSPENDED.getStateCode()
     * {@link SuspensionState}
     */
    @PutMapping("/state/update")
    @Override
    public CommonResponse<Boolean> getActiveProcessDefinitionByKey(@NotBlank(message = "流程定义ID不能为空") @RequestParam String processDefinitionId,
                                                                   @NotNull(message = "状态不能为空") @RequestParam Integer state) {
        log.info("挂起/激活流程 updateProcessDefinitionSuspendedState===>>>参数：{},{}", processDefinitionId, state);
        bpmnProcessDefinitionService.updateProcessDefinitionSuspendedState(processDefinitionId, state);
        return success(true);
    }


    /**
     * 获取指定模型的 Category 激活
     *
     * @return 流程定义ID
     */
    @GetMapping("/active/getByCategory")
    @Override
    public CommonResponse<String> getActiveProcessDefinitionId(@NotBlank(message = "租户不能为空") @RequestParam String tenantId,
                                                               @NotBlank(message = "分类不能为空") @RequestParam String category) {
        log.info("挂起/激活流程 getActiveProcessDefinitionId===>>>参数：{},{}", tenantId, category);
        String result = bpmnProcessDefinitionService.getActiveProcessDefinitionId(tenantId, category);
        return success(result);
    }
}
