package com.qmth.sop.server.api;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qmth.boot.api.constant.ApiConstant;
import com.qmth.boot.api.exception.ApiException;
import com.qmth.sop.business.bean.params.CrmDetailSopParam;
import com.qmth.sop.business.bean.result.EditResult;
import com.qmth.sop.business.entity.TBCrmDetail;
import com.qmth.sop.business.service.TBCrmDetailService;
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.LogTypeEnum;
import com.qmth.sop.common.lock.MemoryLock;
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.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.Map;
import java.util.Objects;

/**
 * @Description: 派单明细表
 * @Param:
 * @return:
 * @Author: wangliang
 * @Date: 2024/5/14
 */
@Api(tags = "派单明细表Controller")
@RestController
@RequestMapping(ApiConstant.DEFAULT_URI_PREFIX + SystemConstant.PREFIX_URL_CRM_DETAIL)
public class TBCrmDetailController {

    private final static Logger log = LoggerFactory.getLogger(TBCrmDetailController.class);

    @Resource
    MemoryLock memoryLock;

    @Resource
    TBCrmDetailService tbCrmDetailService;

    @ApiOperation(value = "获取派单信息")
    @RequestMapping(value = "/sop/var/info", method = RequestMethod.POST)
    @OperationLog(logType = LogTypeEnum.SEARCH)
    @ApiResponses({ @ApiResponse(code = 200, message = "派单信息", response = EditResult.class) })
    public Result sopVarInfo(@ApiParam(value = "派单号", required = true) @RequestParam String crmNo) {
        return ResultUtil.ok(tbCrmDetailService.sopVarInfo(crmNo));
    }

    @ApiOperation(value = "派单明细sop变量保存")
    @RequestMapping(value = "/sop/var/save", method = RequestMethod.POST)
    @OperationLog(logType = LogTypeEnum.UPDATE)
    @ApiResponses({ @ApiResponse(code = 200, message = "派单明细sop变量信息", response = EditResult.class) })
    public Result sopVarSave(
            @Valid @ApiParam(value = "派单明细sop信息", required = true) @RequestBody CrmDetailSopParam crmDetailSopParam,
            BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResultUtil.error(bindingResult.getAllErrors().get(0).getDefaultMessage());
        }
        boolean lock = memoryLock.lock(SystemConstant.LOCK_CRM_DETAIL_SOP_VAR_PREFIX + crmDetailSopParam.getCrmNo(),
                crmDetailSopParam.getCrmNo(), SystemConstant.LOCK_CRM_DETAIL_SOP_TIME_OUT);
        if (!lock) {
            throw ExceptionResultEnum.ERROR.exception("正在保存数据，请稍候再试！");
        }
        boolean result = false;
        try {
            result = tbCrmDetailService.sopVarSave(crmDetailSopParam);
        } catch (Exception e) {
            log.error(SystemConstant.LOG_ERROR, e);
            if (e instanceof ApiException) {
                ResultUtil.error((ApiException) e, ((ApiException) e).getCode(), e.getMessage());
            } else {
                ResultUtil.error(e.getMessage());
            }
        } finally {
            memoryLock.unlock(SystemConstant.LOCK_CRM_DETAIL_SOP_VAR_PREFIX + crmDetailSopParam.getCrmNo());
        }
        return ResultUtil.ok(result);
    }

    @ApiOperation(value = "获取派单明细sop列表")
    @RequestMapping(value = "/sop/info", method = RequestMethod.POST)
    @OperationLog(logType = LogTypeEnum.SEARCH)
    @ApiResponses({ @ApiResponse(code = 200, message = "派单明细sop信息", response = EditResult.class) })
    public Result sopInfo(@ApiParam(value = "派单号", required = true) @RequestParam 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(tbCrmDetailService.list(new Page<>(pageNumber, pageSize), crmNo));
    }

    @ApiOperation(value = "创建/编辑派单明细sop")
    @RequestMapping(value = "/sop/save", method = RequestMethod.POST)
    @OperationLog(logType = LogTypeEnum.ADD)
    @ApiResponses({ @ApiResponse(code = 200, message = "派单明细sop信息", response = EditResult.class) })
    public Result sopSave(@Valid @ApiParam(value = "派单明细sop信息", required = true) @RequestBody TBCrmDetail tbCrmDetail,
            BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResultUtil.error(bindingResult.getAllErrors().get(0).getDefaultMessage());
        }
        boolean lock = memoryLock.lock(SystemConstant.LOCK_CRM_DETAIL_SOP_CREATE_PREFIX + tbCrmDetail.getCrmNo() + "_"
                        + tbCrmDetail.getCourseName(), tbCrmDetail.getCrmNo() + "_" + tbCrmDetail.getCourseName(),
                SystemConstant.LOCK_CRM_DETAIL_SOP_TIME_OUT);
        if (!lock) {
            throw ExceptionResultEnum.ERROR.exception("正在保存数据，请稍候再试！");
        }
        boolean result = false;
        try {
            result = tbCrmDetailService.sopSave(tbCrmDetail);
        } catch (Exception e) {
            log.error(SystemConstant.LOG_ERROR, e);
            if (e instanceof ApiException) {
                ResultUtil.error((ApiException) e, ((ApiException) e).getCode(), e.getMessage());
            } else {
                ResultUtil.error(e.getMessage());
            }
        } finally {
            memoryLock.unlock(SystemConstant.LOCK_CRM_DETAIL_SOP_CREATE_PREFIX + tbCrmDetail.getCrmNo() + "_"
                    + tbCrmDetail.getCourseName());
        }
        return ResultUtil.ok(result);
    }

    @ApiOperation(value = "获取派单明细sop")
    @RequestMapping(value = "/sop/edit", method = RequestMethod.POST)
    @OperationLog(logType = LogTypeEnum.ADD)
    @ApiResponses({ @ApiResponse(code = 200, message = "派单明细sop信息", response = EditResult.class) })
    public Result sopEdit(@ApiParam(value = "派单明细sopId", required = true) @RequestParam Long id) {
        TBCrmDetail tbCrmDetail = tbCrmDetailService.getById(id);
        Objects.requireNonNull(tbCrmDetail, "未找到派单sop信息");
        return ResultUtil.ok(tbCrmDetail);
    }

    @ApiOperation(value = "派单明细sop发布")
    @RequestMapping(value = "/sop/publish", method = RequestMethod.POST)
    @OperationLog(logType = LogTypeEnum.EDIT)
    @ApiResponses({ @ApiResponse(code = 200, message = "派单明细sop发布", response = EditResult.class) })
    public Result sopPublish(@ApiParam(value = "派单明细sopId", required = true) @RequestParam Long id) {
        boolean lock = memoryLock.lock(SystemConstant.LOCK_CRM_DETAIL_SOP_PUBLISH_PREFIX + id, id,
                SystemConstant.LOCK_CRM_DETAIL_SOP_TIME_OUT);
        if (!lock) {
            throw ExceptionResultEnum.ERROR.exception("正在发布数据，请稍候再试！");
        }
        boolean result = false;
        try {
            result = tbCrmDetailService.sopPublish(id);
        } catch (Exception e) {
            log.error(SystemConstant.LOG_ERROR, e);
            if (e instanceof ApiException) {
                ResultUtil.error((ApiException) e, ((ApiException) e).getCode(), e.getMessage());
            } else {
                ResultUtil.error(e.getMessage());
            }
        } finally {
            memoryLock.unlock(SystemConstant.LOCK_CRM_DETAIL_SOP_PUBLISH_PREFIX + id);
        }
        return ResultUtil.ok(result);
    }

    @ApiOperation(value = "派单明细sop删除")
    @RequestMapping(value = "/sop/delete", method = RequestMethod.POST)
    @OperationLog(logType = LogTypeEnum.DELETE)
    @ApiResponses({ @ApiResponse(code = 200, message = "派单明细sop删除", response = EditResult.class) })
    public Result sopDelete(@ApiParam(value = "派单明细sopId", required = true) @RequestParam Long id) {
        boolean lock = memoryLock.lock(SystemConstant.LOCK_CRM_DETAIL_SOP_DELETE_PREFIX + id, id,
                SystemConstant.LOCK_CRM_DETAIL_SOP_TIME_OUT);
        if (!lock) {
            throw ExceptionResultEnum.ERROR.exception("正在删除数据，请稍候再试！");
        }
        boolean result = false;
        try {
            result = tbCrmDetailService.sopDelete(id);
        } catch (Exception e) {
            log.error(SystemConstant.LOG_ERROR, e);
            if (e instanceof ApiException) {
                ResultUtil.error((ApiException) e, ((ApiException) e).getCode(), e.getMessage());
            } else {
                ResultUtil.error(e.getMessage());
            }
        } finally {
            memoryLock.unlock(SystemConstant.LOCK_CRM_DETAIL_SOP_DELETE_PREFIX + id);
        }
        return ResultUtil.ok(result);
    }

    @ApiOperation(value = "导入派单明细")
    @RequestMapping(value = "/sop/import", method = RequestMethod.POST)
    @OperationLog(logType = LogTypeEnum.IMPORT)
    @ApiResponses({ @ApiResponse(code = 200, message = "导入成功", response = EditResult.class) })
    public Result sopImport(@ApiParam(value = "上传文件", required = true) @RequestParam MultipartFile file,
            @ApiParam(value = "派单号", required = true) @RequestParam String crmNo) {
        boolean lock = memoryLock.lock(SystemConstant.LOCK_CRM_DETAIL_SOP_IMPORT_PREFIX + crmNo, crmNo,
                SystemConstant.LOCK_CRM_DETAIL_SOP_TIME_OUT);
        if (!lock) {
            throw ExceptionResultEnum.ERROR.exception("正在导入数据，请稍候再试！");
        }
        Map<String, String> map = null;
        try {
            map = tbCrmDetailService.sopExcelImport(file, crmNo);
        } catch (Exception e) {
            log.error(SystemConstant.LOG_ERROR, e);
            if (e instanceof ApiException) {
                ResultUtil.error((ApiException) e, ((ApiException) e).getCode(), e.getMessage());
            } else {
                ResultUtil.error(e.getMessage());
            }
        } finally {
            memoryLock.unlock(SystemConstant.LOCK_CRM_DETAIL_SOP_IMPORT_PREFIX + crmNo);
        }
        return ResultUtil.ok(map);
    }
}
