package com.yunzhupaas.flowable.controller;

import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.util.ObjectUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import com.yunzhupaas.base.ActionResult;
import com.yunzhupaas.base.vo.PageListVO;
import com.yunzhupaas.base.vo.PaginationVO;
import com.yunzhupaas.constant.MsgCode;
import com.yunzhupaas.exception.WorkFlowException;
import com.yunzhupaas.flowable.entity.TaskEntity;
import com.yunzhupaas.flowable.model.monitor.MonitorModel;
import com.yunzhupaas.flowable.model.monitor.MonitorVo;
import com.yunzhupaas.flowable.model.task.FlowModel;
import com.yunzhupaas.flowable.model.task.TaskPagination;
import com.yunzhupaas.flowable.service.TaskService;
import com.yunzhupaas.flowable.util.ServiceUtil;
import com.yunzhupaas.permission.entity.UserEntity;
import com.yunzhupaas.util.JsonUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 流程监控
 *
 * @author YUNZHUPAASYUNZHUPAAS开发组
 * @version 5.0.x
 * @since 2024/5/15 10:15
 */
@Tag(name = "流程监控", description = "Monitor")
@RestController
@RequestMapping("/api/workflow/monitor")
@RequiredArgsConstructor
public class WorkflowMonitorController {
    @Autowired
    private TaskService taskService;
    @Autowired
    private ServiceUtil serviceUtil;

    /**
     * 监控列表
     *
     * @param pagination 分页参数
     */
    @Operation(summary = "流程监控列表")
    @GetMapping
    public ActionResult<PageListVO<MonitorVo>> list(TaskPagination pagination) {
        List<TaskEntity> list = taskService.getMonitorList(pagination);
        List<UserEntity> userList = serviceUtil
                .getUserName(list.stream().map(TaskEntity::getCreatorUserId).collect(Collectors.toList()));
        List<MonitorVo> voList = new LinkedList<>();
        for (TaskEntity taskEntity : list) {
            MonitorVo vo = JsonUtil.getJsonToBean(taskEntity, MonitorVo.class);
            UserEntity user = userList.stream().filter(t -> t.getId().equals(taskEntity.getCreatorUserId())).findFirst()
                    .orElse(null);
            vo.setCreatorUser(user != null ? user.getRealName() + "/" + user.getAccount() : "");
            vo.setFlowUrgent(taskEntity.getUrgent());
            if (ObjectUtil.equals(taskEntity.getIsFile(), 0)) {
                vo.setIsFile("否");
            } else if (ObjectUtil.equals(taskEntity.getIsFile(), 1)) {
                vo.setIsFile("是");
            } else {
                vo.setIsFile("");
            }
            voList.add(vo);
        }
        PaginationVO paginationVO = JsonUtil.getJsonToBean(pagination, PaginationVO.class);
        return ActionResult.page(voList, paginationVO);
    }

    /**
     * 批量删除流程监控
     *
     * @param model 参数
     */
    @Operation(summary = "批量删除流程监控")
    @DeleteMapping
    @SaCheckPermission(value = { "workFlow.flowMonitor" })
    public ActionResult delete(@RequestBody MonitorModel model) throws Exception {
        taskService.deleteBatch(model.getIds());
        return ActionResult.success(MsgCode.SU003.get());
    }

    /**
     * 判断是否存在异步子流程
     *
     * @param id 任务主键
     */
    @Operation(summary = "判断是否存在异步子流程")
    @GetMapping("/AnySubFlow/{id}")
    public ActionResult pause(@PathVariable("id") String id) {
        return ActionResult.success(taskService.checkAsync(id));
    }

    /**
     * 暂停
     *
     * @param id        主键
     * @param flowModel 参数
     */
    @Operation(summary = "暂停")
    @PostMapping("/Pause/{id}")
    @SaCheckPermission(value = { "workFlow.flowMonitor" })
    public ActionResult<String> pause(@PathVariable("id") String id, @RequestBody FlowModel flowModel)
            throws WorkFlowException {
        taskService.pause(id, flowModel, true);
        return ActionResult.success(MsgCode.WF074.get());
    }

    /**
     * 恢复
     *
     * @param id        主键
     * @param flowModel 参数
     */
    @Operation(summary = "恢复")
    @PostMapping("/Reboot/{id}")
    @SaCheckPermission(value = { "workFlow.flowMonitor" })
    public ActionResult<String> reboot(@PathVariable("id") String id, @RequestBody FlowModel flowModel)
            throws WorkFlowException {
        taskService.pause(id, flowModel, false);
        return ActionResult.success(MsgCode.WF016.get());
    }

    /**
     * 终止
     *
     * @param id        任务主键
     * @param flowModel 参数
     */
    @Operation(summary = "终止")
    @PostMapping("/Cancel/{id}")
    @SaCheckPermission(value = { "workFlow.flowMonitor" })
    public ActionResult<String> cancel(@PathVariable("id") String id, @RequestBody FlowModel flowModel)
            throws WorkFlowException {
        taskService.cancel(id, flowModel, true);
        return ActionResult.success(MsgCode.SU009.get());
    }

    /**
     * 复活
     *
     * @param id        任务主键
     * @param flowModel 参数
     */
    @Operation(summary = "复活")
    @PostMapping("/Activate/{id}")
    @SaCheckPermission(value = { "workFlow.flowMonitor" })
    public ActionResult<String> activate(@PathVariable("id") String id, @RequestBody FlowModel flowModel)
            throws WorkFlowException {
        taskService.cancel(id, flowModel, false);
        return ActionResult.success(MsgCode.WF013.get());
    }

    /**
     * 指派
     *
     * @param id        主键
     * @param flowModel 参数
     */
    @Operation(summary = "指派")
    @PostMapping("/Assign/{id}")
    @SaCheckPermission(value = { "workFlow.flowMonitor" })
    public ActionResult<String> assign(@PathVariable("id") String id, @RequestBody FlowModel flowModel)
            throws WorkFlowException {
        taskService.assign(id, flowModel);
        return ActionResult.success(MsgCode.WF010.get());
    }
}
