package cn.estsh.i3plus.ext.mes.pcn.apiservice.controller.busi;


import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesNingDeShippingCheckService;
import cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.busi.log.MesServiceBusiScanLogService;
import cn.estsh.i3plus.ext.mes.pcn.apiservice.util.MesPcnException;
import cn.estsh.i3plus.ext.mes.pcn.apiservice.util.MesRedisLockUtil;
import cn.estsh.i3plus.ext.mes.pcn.pojo.constant.MesCommonConstant;
import cn.estsh.i3plus.ext.mes.pcn.pojo.model.MesSortShippingCheckModel;
import cn.estsh.i3plus.ext.mes.pcn.pojo.model.MesSortShippingPasswordModel;
import cn.estsh.i3plus.platform.common.convert.ConvertBean;
import cn.estsh.i3plus.pojo.mes.bean.shipping.MesShippingOrderManagement;
import cn.estsh.i3plus.pojo.mes.repository.MesServiceBusiScanLogRepository;
import cn.estsh.impp.framework.boot.auth.AuthUtil;
import cn.estsh.impp.framework.boot.exception.ImppBusiException;
import cn.estsh.impp.framework.boot.exception.ImppExceptionBuilder;
import cn.estsh.impp.framework.boot.util.ResultBean;
import cn.estsh.impp.framework.boot.util.ValidatorBean;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

@RestController
@Api(tags = "宁德二次发运校验")
@RequestMapping(MesCommonConstant.MES_YANFEN + "/ning-de-second-shipping")
@Slf4j
public class MesNingDeSecondShippingController {

    @Autowired
    private IMesNingDeShippingCheckService sortShippingCheckService;

    @Autowired
    private MesRedisLockUtil redisLockUtil;

    @Autowired
    private MesServiceBusiScanLogRepository mesServiceBusiScanLogRepository;

    private static final String KEY = ":BUSI_LOCK:SORT_SHIPPING_CHECK:";

    @PostMapping("/query-shipping-order")
    @ApiOperation(value = "查询发运单")
    public ResultBean queryLoadingOrderNo(@RequestBody MesShippingOrderManagement shippingOrderManagement) {
        if (StringUtils.isEmpty(shippingOrderManagement.getShippingGroupCode())) {
            return ResultBean.fail("未选择零件发运组");
        }
        MesServiceBusiScanLogService scanLogUtil = new MesServiceBusiScanLogService(MesNingDeSecondShippingController.class);
        scanLogUtil.setMesServiceBusiScanLogRepository(mesServiceBusiScanLogRepository);

        Boolean lockFlg = false;
        String moduleKey = null;
        String organizeCode = null;
        String userInfo = null;
        try {
            if (StringUtils.isEmpty(shippingOrderManagement.getShippingCode())) {
                MesPcnException.throwBusiException("请扫描发运单!");
            }

            organizeCode = !StringUtils.isEmpty(shippingOrderManagement.getOrganizeCode()) ? shippingOrderManagement.getOrganizeCode() : AuthUtil.getOrganize().getOrganizeCode();

            userInfo = !StringUtils.isEmpty(shippingOrderManagement.getUserInfo()) ? shippingOrderManagement.getUserInfo() : AuthUtil.getSessionUser().getUserName();
            scanLogUtil.setOrderNo(shippingOrderManagement.getShippingCode());
            scanLogUtil.setOrganizeCode(organizeCode);
            scanLogUtil.setUserName(userInfo);
            moduleKey = organizeCode + KEY + "SHIPPING_CODE:" + shippingOrderManagement.getShippingCode();

            scanLogUtil.info(String.format("工厂:%s 排序发运扫描发运单 --- %s --- START --- 操作人:%s --- THREAD:%s", organizeCode, moduleKey, userInfo, Thread.currentThread().getName()));

            //加锁
            lockFlg = redisLockUtil.redisLock(moduleKey);

            scanLogUtil.info(String.format("工厂:%s 排序发运扫描发运单 --- %s --- LOCKED --- 操作人:%s --- THREAD:%s", organizeCode, moduleKey, userInfo, Thread.currentThread().getName()));

            // 数据校验
            ValidatorBean.checkNotNull(shippingOrderManagement.getShippingCode(), "发运单不能为空");
            shippingOrderManagement.setOrganizeCode(organizeCode);
            ConvertBean.serviceModelUpdate(shippingOrderManagement, userInfo);
            long start = System.currentTimeMillis();
            MesSortShippingCheckModel model = sortShippingCheckService.doShippingOrderNoQuery(shippingOrderManagement);
            long end = System.currentTimeMillis();
            scanLogUtil.info("扫描发运单执行结束", end - start);
            return ResultBean.success(model != null ? model.getMsg() : "").setResultObject(model);
        } catch (ImppBusiException imppException) {
            scanLogUtil.error(imppException.getErrorMsg());
            return ResultBean.fail(imppException);
        } catch (Exception e) {
            scanLogUtil.error(ExceptionUtils.getStackTrace(e));
            return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
        } finally {
            //解锁
            if (lockFlg) {
                redisLockUtil.redisUnLock(lockFlg, moduleKey);
                log.info("工厂:{} 排序发运扫描发运单 --- {} --- UNLOCK --- 操作人:{} --- THREAD:{}", organizeCode, moduleKey, userInfo, Thread.currentThread().getName());
            }
            scanLogUtil.flush();
        }
    }

    @PostMapping("/scan-sn")
    @ApiOperation(value = "扫描条码")
    public ResultBean saveSn(@RequestBody MesSortShippingCheckModel model) {
        MesServiceBusiScanLogService scanLogUtil = new MesServiceBusiScanLogService(MesNingDeSecondShippingController.class);
        scanLogUtil.setMesServiceBusiScanLogRepository(mesServiceBusiScanLogRepository);

        Boolean lockFlg = false;
        String moduleKey = null;
        String organizeCode = null;
        String userInfo = null;
        try {
            if (StringUtils.isEmpty(model.getSn())) {
                MesPcnException.throwBusiException("请扫描条码!");
            }

            organizeCode = !StringUtils.isEmpty(model.getOrganizeCode()) ? model.getOrganizeCode() : AuthUtil.getOrganize().getOrganizeCode();

            userInfo = !StringUtils.isEmpty(model.getUserInfo()) ? model.getUserInfo() : AuthUtil.getSessionUser().getUserName();
            scanLogUtil.setOrderNo(model.getShippingCode());
            scanLogUtil.setOrganizeCode(organizeCode);
            scanLogUtil.setUserName(userInfo);
            scanLogUtil.setSn(model.getSn());
            //增加单据锁
            moduleKey = organizeCode + KEY + "SHIPPING_CODE:" + model.getShippingCode();

            scanLogUtil.info(String.format("工厂:%s 排序发运扫描条码 --- %s --- START --- 操作人:%s --- THREAD:%s", organizeCode, model.getSn(), userInfo, Thread.currentThread().getName()));

            //加锁
            lockFlg = redisLockUtil.redisLock(moduleKey);

            scanLogUtil.info(String.format("工厂:%s 排序发运扫描条码 --- %s --- LOCKED --- 操作人:%s --- THREAD:%s", organizeCode, model.getSn(), userInfo, Thread.currentThread().getName()));

            // 数据校验
            ValidatorBean.checkNotNull(model.getShippingCode(), "发运单不能为空");
            ValidatorBean.checkNotNull(model.getDetailList(), "发运明细不能为空");
            ValidatorBean.checkNotNull(model.getSn(), "条码不能为空");
            model.setOrganizeCode(organizeCode);
            model.setUserInfo(userInfo);
            model.setSecondShipping(true);
            long start = System.currentTimeMillis();
            sortShippingCheckService.saveSn(model);
            long end = System.currentTimeMillis();
            scanLogUtil.info("扫描发运条码执行结束", end - start);
            return ResultBean.success(model.getMsg()).setResultObject(model);
        } catch (ImppBusiException imppException) {
            scanLogUtil.error(imppException.getErrorMsg());
            return ResultBean.fail(imppException);
        } catch (Exception e) {
            scanLogUtil.error(ExceptionUtils.getStackTrace(e));
            return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
        } finally {
            //解锁
            if (lockFlg) {
                redisLockUtil.redisUnLock(lockFlg, moduleKey);
                log.info("工厂:{} 排序发运扫描条码 --- {} --- UNLOCK --- 操作人:{} --- THREAD:{}", organizeCode, model.getSn(), userInfo, Thread.currentThread().getName());
            }
            scanLogUtil.flush();
        }
    }

    @GetMapping("/query-auto-push-order")
    @ApiOperation(value = "自动推单")
    public ResultBean queryAutoPushOrder(String shippingGroupNo, String organizeCode) {

        try {
            organizeCode = !StringUtils.isEmpty(organizeCode) ? organizeCode : AuthUtil.getOrganize().getOrganizeCode();
            MesShippingOrderManagement order = sortShippingCheckService.queryShippingOrderNoByAutoPushOrder(shippingGroupNo, organizeCode);
            return ResultBean.success("查询成功").setResultObject(order);
        } catch (ImppBusiException imppException) {
            return ResultBean.fail(imppException);
        } catch (Exception e) {
            return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
        }
    }

    @PostMapping("/check-password")
    @ApiOperation(value = "校验二次发运操作密码")
    public ResultBean checkPassword(@RequestBody MesSortShippingPasswordModel model) {
        if (StringUtils.isEmpty(model.getPassword())) {
            return ResultBean.fail("密码不能为空！");
        }
        try {
            String organizeCode = !StringUtils.isEmpty(model.getOrganizeCode()) ? model.getOrganizeCode() : AuthUtil.getOrganize().getOrganizeCode();
            sortShippingCheckService.checkPassword(model.getPassword(), organizeCode);
            return ResultBean.success("校验成功");
        } catch (ImppBusiException imppException) {
            return ResultBean.fail(imppException);
        } catch (Exception e) {
            return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
        }
    }
}
