package tech.easyflow.admin.controller.system;

import cn.dev33.satoken.annotation.SaCheckPermission;
import com.mybatisflex.core.paginate.Page;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import tech.easyflow.common.domain.Result;
import tech.easyflow.common.satoken.util.SaTokenUtil;
import tech.easyflow.common.web.exceptions.BusinessException;
import tech.easyflow.common.web.jsonbody.JsonBody;
import tech.easyflow.approval.entity.vo.ApprovalAssigneeOptionVo;
import tech.easyflow.approval.entity.vo.ApprovalFlowDetailVo;
import tech.easyflow.approval.entity.vo.ApprovalFlowPageVo;
import tech.easyflow.approval.service.ApprovalAssigneeService;
import tech.easyflow.approval.service.ApprovalFlowService;
import tech.easyflow.system.service.CategoryPermissionService;

import javax.annotation.Resource;
import java.math.BigInteger;
import java.util.List;

/**
 * 审批流程管理控制器。
 */
@RestController
@RequestMapping("/api/v1/approvalFlow")
public class ApprovalFlowController {

    @Resource
    private ApprovalFlowService approvalFlowService;

    @Resource
    private CategoryPermissionService categoryPermissionService;

    @Resource
    private ApprovalAssigneeService approvalAssigneeService;

    /**
     * 分页查询审批流程。
     *
     * @param name 流程名称
     * @param resourceType 资源类型
     * @param actionType 动作类型
     * @param status 流程状态
     * @param pageNumber 页码
     * @param pageSize 每页数量
     * @return 分页结果
     */
    @GetMapping("/page")
    @SaCheckPermission("/api/v1/approvalFlow/query")
    public Result<Page<ApprovalFlowPageVo>> page(String name, String resourceType, String actionType, String status,
                                                 Long pageNumber, Long pageSize) {
        return Result.ok(approvalFlowService.pageFlows(name, resourceType, actionType, status, pageNumber, pageSize));
    }

    /**
     * 查询审批流程详情。
     *
     * @param id 流程ID
     * @return 流程详情
     */
    @GetMapping("/detail")
    @SaCheckPermission("/api/v1/approvalFlow/query")
    public Result<ApprovalFlowDetailVo> detail(BigInteger id) {
        return Result.ok(approvalFlowService.getFlowDetail(id));
    }

    /**
     * 查询审批角色选项。
     *
     * @return 角色选项
     */
    @GetMapping("/assigneeRoleOptions")
    @SaCheckPermission("/api/v1/approvalFlow/query")
    public Result<List<ApprovalAssigneeOptionVo>> assigneeRoleOptions() {
        return Result.ok(approvalAssigneeService.listRoleOptions());
    }

    /**
     * 分页查询审批用户选项。
     *
     * @param keyword 关键词
     * @param pageNumber 页码
     * @param pageSize 每页数量
     * @return 用户选项分页
     */
    @GetMapping("/assigneeAccountPage")
    @SaCheckPermission("/api/v1/approvalFlow/query")
    public Result<Page<ApprovalAssigneeOptionVo>> assigneeAccountPage(String keyword, Long pageNumber, Long pageSize) {
        return Result.ok(approvalAssigneeService.pageAccountOptions(keyword, pageNumber, pageSize));
    }

    /**
     * 新增审批流程。
     *
     * @param request 流程请求体
     * @return 新增流程ID
     */
    @PostMapping("/save")
    @SaCheckPermission("/api/v1/approvalFlow/save")
    public Result<BigInteger> save(@JsonBody ApprovalFlowDetailVo request) {
        assertSuperAdmin();
        BigInteger operatorId = SaTokenUtil.getLoginAccount().getId();
        return Result.ok(approvalFlowService.saveFlow(request, operatorId));
    }

    /**
     * 更新审批流程。
     *
     * @param request 流程请求体
     * @return 处理结果
     */
    @PostMapping("/update")
    @SaCheckPermission("/api/v1/approvalFlow/save")
    public Result<Void> update(@JsonBody ApprovalFlowDetailVo request) {
        assertSuperAdmin();
        BigInteger operatorId = SaTokenUtil.getLoginAccount().getId();
        approvalFlowService.updateFlow(request, operatorId);
        return Result.ok();
    }

    /**
     * 启用审批流程。
     *
     * @param id 流程ID
     * @return 处理结果
     */
    @PostMapping("/enable")
    @SaCheckPermission("/api/v1/approvalFlow/enable")
    public Result<Void> enable(@JsonBody(value = "id", required = true) BigInteger id) {
        assertSuperAdmin();
        approvalFlowService.enableFlow(id, SaTokenUtil.getLoginAccount().getId());
        return Result.ok();
    }

    /**
     * 停用审批流程。
     *
     * @param id 流程ID
     * @return 处理结果
     */
    @PostMapping("/disable")
    @SaCheckPermission("/api/v1/approvalFlow/disable")
    public Result<Void> disable(@JsonBody(value = "id", required = true) BigInteger id) {
        assertSuperAdmin();
        approvalFlowService.disableFlow(id, SaTokenUtil.getLoginAccount().getId());
        return Result.ok();
    }

    /**
     * 删除审批流程。
     *
     * @param id 流程ID
     * @return 处理结果
     */
    @PostMapping("/remove")
    @SaCheckPermission("/api/v1/approvalFlow/remove")
    public Result<Void> remove(@JsonBody(value = "id", required = true) BigInteger id) {
        assertSuperAdmin();
        approvalFlowService.removeFlow(id);
        return Result.ok();
    }

    private void assertSuperAdmin() {
        if (!categoryPermissionService.isCurrentSuperAdmin()) {
            throw new BusinessException("仅超级管理员可管理审批流程");
        }
    }
}
