package cn.fateverse.workflow.controller;

import cn.hutool.core.util.StrUtil;
import cn.fateverse.common.core.exception.CustomException;
import cn.fateverse.common.core.result.Result;
import cn.fateverse.common.core.result.page.TableDataInfo;
import cn.fateverse.common.log.annotation.Log;
import cn.fateverse.common.log.enums.BusinessType;
import cn.fateverse.workflow.entity.dto.ProcessDto;
import cn.fateverse.workflow.entity.query.ProcessQuery;
import cn.fateverse.workflow.entity.vo.ProcessDefinitionHistoryVo;
import cn.fateverse.workflow.entity.vo.ProcessDefinitionInfoVo;
import cn.fateverse.workflow.entity.vo.ProcessDefinitionVo;
import cn.fateverse.workflow.service.ProcessDefinitionService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 工作流流程部署
 *
 * @author Clay
 * @date 2022/12/22
 */
@Api(value = "工作流流程部署", tags = "工作流流程部署")
@RestController
@RequestMapping("/process/definition")
public class ProcessDefinitionController {

    private final ProcessDefinitionService processDefinitionService;

    public ProcessDefinitionController(ProcessDefinitionService processDefinitionService) {
        this.processDefinitionService = processDefinitionService;
    }

    @ApiOperation("工作流流程查询")
    @GetMapping
    @PreAuthorize("@ss.hasPermission('workflow:definition:list')")
    public Result<TableDataInfo<ProcessDefinitionVo>> list(ProcessQuery query) {
        TableDataInfo<ProcessDefinitionVo> dataTable = processDefinitionService.searchList(query);
        return Result.ok(dataTable);
    }

    @ApiOperation("工作流查询")
    @GetMapping("/{deploymentId}")
    @PreAuthorize("@ss.hasPermission('workflow:definition:info')")
    public Result<ProcessDefinitionInfoVo> info(@PathVariable String deploymentId){
        ProcessDefinitionInfoVo infoVo = processDefinitionService.searchByDeploymentId(deploymentId);
        return Result.ok(infoVo);
    }

    @ApiOperation("工作流查询")
    @GetMapping("/key/{processDefinitionKey}")
    @PreAuthorize("@ss.hasPermission('workflow:definition:info')")
    public Result<ProcessDefinitionInfoVo> initiateInfo(@PathVariable String processDefinitionKey){
        ProcessDefinitionInfoVo infoVo = processDefinitionService.searchInitiateInfoByKey(processDefinitionKey);
        return Result.ok(infoVo);
    }

    @ApiOperation("工作流历史流程查询")
    @GetMapping("/history/{processDefinitionKey}")
    @PreAuthorize("@ss.hasPermission('workflow:definition:history')")
    public Result<List<ProcessDefinitionHistoryVo>> history(@PathVariable String processDefinitionKey) {
        List<ProcessDefinitionHistoryVo> processVos = processDefinitionService.searchHistoryList(processDefinitionKey);
        return Result.ok(processVos);
    }

    @ApiOperation("工作流挂起")
    @PutMapping("/suspend")
    @Log(title = "工作流挂起",businessType = BusinessType.UPDATE)
    @PreAuthorize("@ss.hasPermission('workflow:definition:suspend')")
    public Result<Void> suspend(@RequestBody String processDefinitionId) {
        checkProcessDefinitionId(processDefinitionId);
        processDefinitionService.suspend(processDefinitionId);
        return Result.ok();
    }

    @ApiOperation("工作流激活")
    @PutMapping("/activate")
    @Log(title = "工作流激活",businessType = BusinessType.UPDATE)
    @PreAuthorize("@ss.hasPermission('workflow:definition:activate')")
    public Result<Void> activate(@RequestBody String processDefinitionId) {
        checkProcessDefinitionId(processDefinitionId);
        processDefinitionService.activate(processDefinitionId);
        return Result.ok();
    }

    @ApiOperation("删除工作流")
    @DeleteMapping("/{deploymentId}")
    @Log(title = "删除工作流",businessType = BusinessType.UPDATE)
    @PreAuthorize("@ss.hasPermission('workflow:definition:activate')")
    public Result<Void> delete(@PathVariable String deploymentId) {
        checkProcessDefinitionId(deploymentId);
        processDefinitionService.delete(deploymentId);
        return Result.ok();
    }

    @ApiOperation("工作流流程部署")
    @PostMapping
    @Log(title = "工作流流程部署",businessType = BusinessType.UPDATE)
    @PreAuthorize("@ss.hasPermission('workflow:definition:add')")
    public Result<Void> add(@RequestBody ProcessDto processDto) {
        processDefinitionService.add(processDto);
        return Result.ok("工作流程部署成功!");
    }

    private void checkProcessDefinitionId(String processDefinitionId) {
        if (StrUtil.isEmpty(processDefinitionId)) {
            throw new CustomException("流程id不能为空");
        }
    }

}
