package com.casic.missiles.controller;

import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.casic.missiles.GeneralApprovalDTO;
import com.casic.missiles.core.base.controller.ExportController;
import com.casic.missiles.core.page.PageFactory;
import com.casic.missiles.core.page.PageInfoBT;
import com.casic.missiles.dto.*;
import com.casic.missiles.dto.flowable.ApprovalDeleteRequest;
import com.casic.missiles.enums.BusinessExceptionEnum;
import com.casic.missiles.exception.BusinessException;
import com.casic.missiles.model.exception.enums.CoreExceptionEnum;
import com.casic.missiles.service.IGeneralApprovalService;
import io.swagger.annotations.ApiOperation;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;

import javax.validation.Valid;
import java.util.Objects;

/**
 * @Description: 通用审批Controller
 *          O：列表响应实体类
 *          T：编辑请求实体类
 *          R：列表请求实体类
 *          S：提交请求实体类
 * @Author: wangpeng
 * @Date: 2023/8/14 15:26
 */
public class GeneralApprovalController<O extends GeneralApprovalDTO, T extends GeneralApprovalDTO, R extends BaseApprovalListRequest, S extends BaseApprovalSubmitRequest> extends ExportController {

    private IGeneralApprovalService<O, T, R, S> baseApprovalService;

    public GeneralApprovalController(IGeneralApprovalService<O, T, R, S> baseApprovalService) {
        this.baseApprovalService = baseApprovalService;
    }

    @ApiOperation("审批列表（分页）")
    @PostMapping("/approval/listPage")
    public ReturnDTO<PageInfoBT<T>> approvalListPage(@RequestBody R request) throws Exception {
        Page<O> page = PageFactory.defaultPage();
        page = baseApprovalService.listPage(page, request);
        return ReturnUtil.success(super.packForBT(page));
    }

    @ApiOperation("草稿箱-编辑")
    @PostMapping("/draftUpdate")
    public ReturnDTO draftUpdate(@RequestBody @Valid T request, BindingResult bindingResult) {
        if(bindingResult.hasErrors()){
            throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage());
        }
        return baseApprovalService.draftUpdate(request);
    }

    @ApiOperation("草稿箱-删除")
    @PostMapping("/draftDelete")
    public ReturnDTO draftDelete(@RequestBody @Valid IdDTO idDTO) {
        Assert.isFalse(Objects.isNull(idDTO.getId()), () -> {
            throw new BusinessException(BusinessExceptionEnum.ID_NULL);
        });
        return baseApprovalService.draftDelete(idDTO.getId());
    }

    @ApiOperation("草稿箱-批量删除")
    @PostMapping("/draftBatchDelete")
    public ReturnDTO draftBatchDelete(@RequestBody @Valid IdsDTO idsDTO) {
        Assert.isFalse(CollectionUtils.isEmpty(idsDTO.getIds()), () -> {
            throw new BusinessException(BusinessExceptionEnum.ID_NULL);
        });
        return baseApprovalService.draftBatchDelete(idsDTO.getIds());
    }

    @ApiOperation("提交（未调用过保存接口保存至草稿箱需先调用保存接口，再调用该接口；无基本信息变更时changeFlag传1）")
    @PostMapping("/submit")
    public ReturnDTO submit(@RequestBody @Valid S request, BindingResult bindingResult) {
        if(bindingResult.hasErrors()){
            throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage());
        }
        return baseApprovalService.submit(request);
    }

    @ApiOperation("审批-拒绝")
    @PostMapping("/approval/refuse")
    public ReturnDTO approvalRefuse(@RequestBody @Valid BaseApprovalRefuseRequest request, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage());
        }
        return baseApprovalService.approvalRefuse(request);
    }

    @ApiOperation("审批-取消（发起者撤回，表单状态更改为已取消，仅审批中状态可撤回）")
    @PostMapping("/approval/revoke")
    public ReturnDTO approvalRevoke(@RequestBody @Valid BaseApprovalRevokeRequest request, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage());
        }
        return baseApprovalService.approvalRevoke(request);
    }

    @ApiOperation("审批-删除（已取消删除，发起者或具有删除权限的用户可以删除，已通过/未通过状态不可删除，前端控制按钮权限）")
    @PostMapping("/approval/delete")
    public ReturnDTO delete(@RequestBody @Valid ApprovalDeleteRequest request, BindingResult bindingResult) {
        if(bindingResult.hasErrors()){
            throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage());
        }
        return baseApprovalService.approvalDelete(request);
    }

    @ApiOperation("未通过/已取消-编辑（驳回后的重新编辑）")
    @PostMapping("/failUpdate")
    public ReturnDTO failUpdate(@RequestBody @Valid T request, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage());
        }
        return baseApprovalService.failUpdate(request);
    }
}
