package com.qmth.sop.server.api;


import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qmth.boot.api.constant.ApiConstant;
import com.qmth.sop.business.activiti.service.ActivitiService;
import com.qmth.sop.business.bean.params.FlowApproveParam;
import com.qmth.sop.business.bean.result.FlowViewResult;
import com.qmth.sop.business.bean.result.WorkTaskResult;
import com.qmth.sop.business.entity.TFCustomFlow;
import com.qmth.sop.business.service.TFCustomFlowService;
import com.qmth.sop.common.annotation.OperationLog;
import com.qmth.sop.common.contant.SystemConstant;
import com.qmth.sop.common.enums.ExceptionResultEnum;
import com.qmth.sop.common.enums.FlowTaskTypeEnum;
import com.qmth.sop.common.enums.LogTypeEnum;
import com.qmth.sop.common.enums.TFCustomTypeEnum;
import com.qmth.sop.common.util.Result;
import com.qmth.sop.common.util.ResultUtil;
import io.swagger.annotations.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.validation.Valid;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 自定义流程表 前端控制器
 * </p>
 *
 * @author wangliang
 * @since 2023-07-17
 */
@Api(tags = "流程表单Controller")
@RestController
@RequestMapping(ApiConstant.DEFAULT_URI_PREFIX + SystemConstant.PREFIX_FLOW)
public class TFCustomFlowController {
    private final static Logger log = LoggerFactory.getLogger(TFCustomFlowController.class);

    @Resource
    ActivitiService activitiService;

    @Resource
    TFCustomFlowService tfCustomFlowService;

    @ApiOperation(value = "创建流程接口")
    @RequestMapping(value = "/createDeployment", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "返回信息", response = Object.class)})
    @OperationLog(logType = LogTypeEnum.ADD)
    public Result createDeployment() throws Exception {
        return ResultUtil.ok(activitiService.createDeployment(Arrays.asList(TFCustomTypeEnum.OFFICE_SOP_FLOW, TFCustomTypeEnum.CLOUD_MARK_SOP_FLOW, TFCustomTypeEnum.DING_EXCEPTION_FLOW, TFCustomTypeEnum.PROJECT_EXCHANGE_FLOW, TFCustomTypeEnum.QUALITY_PROBLEM_FLOW)));
    }

    @ApiOperation(value = "上传流程接口")
    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "返回信息", response = Object.class)})
    @OperationLog(logType = LogTypeEnum.UN_KNOW)
    public Result upload(@ApiParam(required = true, value = "上传文件") @RequestParam MultipartFile file) throws Exception {
        return ResultUtil.ok(activitiService.upload(file));
    }

    @ApiOperation(value = "获取流程部署信息")
    @RequestMapping(value = "/deployment/data", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "返回信息", response = TFCustomFlow.class)})
    public Result getDeploymentData() {
        return ResultUtil.ok(tfCustomFlowService.findFlowDeploymentList());
    }

    @ApiOperation(value = "获取流程版本信息")
    @RequestMapping(value = "/version/list", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "返回信息", response = TFCustomFlow.class)})
    public Result getVersionList(@ApiParam(value = "sop流程类型", required = true) @RequestParam TFCustomTypeEnum type) {
        return ResultUtil.ok(tfCustomFlowService.findFlowVersion(type));
    }

    @ApiOperation(value = "获取流程表单属性接口")
    @RequestMapping(value = "/form_properties/get", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "返回信息", response = Object.class)})
    public Result formPropertiesGet(@ApiParam(value = "流程部署id") @RequestParam(required = false) String flowDeploymentId,
                                    @ApiParam(value = "流程id") @RequestParam(required = false) Long flowId,
                                    @ApiParam(value = "流程任务id") @RequestParam(required = false) Long taskId,
                                    @ApiParam(value = "crm单号") @RequestParam(required = false) String crmNo) throws Exception {
        return ResultUtil.ok(activitiService.formPropertiesGet(flowDeploymentId, flowId, taskId, false, crmNo));
    }

    @ApiOperation(value = "流程审批接口")
    @RequestMapping(value = "/approve", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "返回信息", response = Object.class)})
    @OperationLog(logType = LogTypeEnum.UN_KNOW)
    public Result approve(@Valid @ApiParam(value = "流程审批信息", required = true) @RequestBody FlowApproveParam flowApproveParam, BindingResult bindingResult) throws InterruptedException {
        if (bindingResult.hasErrors()) {
            return ResultUtil.error(bindingResult.getAllErrors().get(0).getDefaultMessage());
        }
        activitiService.taskApprove(flowApproveParam);
        return ResultUtil.ok(true);
    }

    @ApiOperation(value = "获取流程待办接口")
    @RequestMapping(value = "/task/list", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "返回信息", response = WorkTaskResult.class)})
    public Result getFlowTaskList(@ApiParam(value = "用户id") @RequestParam(required = false) Long userId,
                                  @ApiParam(value = "流程类型") @RequestParam(required = false) TFCustomTypeEnum type,
                                  @ApiParam(value = "服务单元id") @RequestParam(required = false) Long serviceId,
                                  @ApiParam(value = "客户名称") @RequestParam(required = false) String customName,
                                  @ApiParam(value = "待办任务类型", required = true) @RequestParam FlowTaskTypeEnum flowTaskTypeEnum,
                                  @ApiParam(value = "crm单号") @RequestParam(required = false) String crmNo,
                                  @ApiParam(value = "页码", required = true) @RequestParam @Min(SystemConstant.PAGE_NUMBER_MIN) Integer pageNumber,
                                  @ApiParam(value = "页数", required = true) @RequestParam @Min(SystemConstant.PAGE_SIZE_MIN) @Max(SystemConstant.PAGE_SIZE_MAX) Integer pageSize) {
        return ResultUtil.ok(activitiService.getFlowTaskList(new Page<>(pageNumber, pageSize), userId, type, serviceId, customName, flowTaskTypeEnum, crmNo));
    }

    @ApiOperation(value = "获取流程待办计数接口")
    @RequestMapping(value = "/task/list/count", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "返回信息", response = Integer.class)})
    public Result getFlowTaskListCount(@ApiParam(value = "用户id") @RequestParam(required = false) Long userId,
                                       @ApiParam(value = "流程类型") @RequestParam(required = false) TFCustomTypeEnum type,
                                       @ApiParam(value = "服务单元id") @RequestParam(required = false) Long serviceId,
                                       @ApiParam(value = "客户名称") @RequestParam(required = false) String customName,
                                       @ApiParam(value = "待办任务类型", required = true) @RequestParam FlowTaskTypeEnum flowTaskTypeEnum,
                                       @ApiParam(value = "crm单号") @RequestParam(required = false) String crmNo) {
        return ResultUtil.ok(activitiService.getFlowTaskListCount(userId, type, serviceId, customName, flowTaskTypeEnum, crmNo));
    }

    @ApiOperation(value = "结束流程接口")
    @RequestMapping(value = "/delete", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "返回信息", response = Object.class)})
    @OperationLog(logType = LogTypeEnum.UN_KNOW)
    public Result delete(@ApiParam(value = "流程id", required = true) Long flowId) {
        return ResultUtil.ok(activitiService.flowEnd(flowId));
    }

    @ApiOperation(value = "批量结束流程接口")
    @RequestMapping(value = "/batch/delete", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "返回信息", response = Object.class)})
    @OperationLog(logType = LogTypeEnum.UN_KNOW)
    public Result batchDelete(@ApiParam(value = "流程id数组", required = true) @RequestBody List<Long> flowIds) {
        if (CollectionUtils.isEmpty(flowIds)) {
            throw ExceptionResultEnum.PARAMS_ERROR.exception("流程id数组不能为空");
        }
        return ResultUtil.ok(activitiService.flowEnd(flowIds));
    }

    @ApiOperation(value = "流程转办接口")
    @RequestMapping(value = "/task/approver/exchange", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "返回信息", response = Object.class)})
    @OperationLog(logType = LogTypeEnum.UN_KNOW)
    public Result taskApproverExchange(@ApiParam(value = "用户id", required = true) @RequestParam Long userId,
                                       @ApiParam(value = "流程任务id", required = true) @RequestParam Long taskId) {
        return ResultUtil.ok(activitiService.taskApproverExchange(userId, taskId));
    }

    @ApiOperation(value = "获取流程详细信息接口")
    @RequestMapping(value = "/view", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "返回信息", response = FlowViewResult.class)})
    public Result flowView(@ApiParam(value = "流程id") @RequestParam(required = false) Long flowId,
                           @ApiParam(value = "流程编号") @RequestParam(required = false) String code) {
        if (Objects.isNull(flowId) && Objects.isNull(code)) {
            throw ExceptionResultEnum.PARAMS_ERROR.exception();
        }
        return ResultUtil.ok(activitiService.flowView(flowId, code));
    }
}
