package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.busi.step.bu;

import cn.estsh.i3plus.ext.mes.pcn.api.base.ISxWorkOrderExtService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IPackageExtService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IProduceSnExtService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.bu.IOuterPackageSnService;
import cn.estsh.i3plus.ext.mes.pcn.pojo.bean.MesOuterPackage;
import cn.estsh.i3plus.ext.mes.pcn.pojo.bean.MesOuterPackageDetail;
import cn.estsh.i3plus.ext.mes.pcn.pojo.bean.MesProduceSnExt;
import cn.estsh.i3plus.ext.mes.pcn.pojo.bean.MesWorkOrderExt;
import cn.estsh.i3plus.ext.mes.pcn.pojo.model.bu.InnerPackageRecordModel;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtEnumUtil;
import cn.estsh.i3plus.mes.pcn.serviceimpl.base.BaseStepService;
import cn.estsh.i3plus.mes.pcn.util.LocaleUtil;
import cn.estsh.i3plus.platform.common.tool.MathOperation;
import cn.estsh.i3plus.pojo.base.enumutil.MesPcnEnumUtil;
import cn.estsh.i3plus.pojo.mes.bean.MesPackage;
import cn.estsh.i3plus.pojo.mes.bean.MesPackageDetail;
import cn.estsh.i3plus.pojo.mes.model.StationRequestBean;
import cn.estsh.i3plus.pojo.mes.model.StationResultBean;
import cn.estsh.i3plus.pojo.mes.model.StepResult;
import cn.estsh.impp.framework.boot.util.ImppRedis;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 工步业务----净水器线新工位-扫描条码，选择工单类型，校验完成后根据不同工单类型走不同流程
 * @USER: steven.peng
 * @DATE: 2023-01-11 10:20
 * */
@Slf4j
@Service("sxOuterPrintCheckSnStepService")
public class SxOuterPrintCheckSnStepService extends BaseStepService {
    @Autowired
    private IProduceSnExtService produceSnExtService;

    @Autowired
    private ISxWorkOrderExtService workOrderExtService;

    @Autowired
    private IPackageExtService packageExtService;

    @Autowired
    IOuterPackageSnService iOuterPackageSnService;

    @Resource(name = MesPcnExtConstWords.REDIS_RES_PCN)
    private ImppRedis redisMesPcn;

    @Override
    public StepResult guide(StationRequestBean reqBean) {
        StationResultBean resultBean = new StationResultBean();
        String guide = LocaleUtil.transferLanguage(reqBean.getUserInfo(), "请扫描条码");
        this.sendMessage(reqBean, resultBean, guide, MesPcnEnumUtil.STATION_BUSI_TYPE.GUIDE, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT);
        return super.guide(reqBean);
    }

    @Override
    public StepResult init(StationRequestBean reqBean) {
        //清除工步内容
        StationResultBean resultBean = new StationResultBean();
        resultBean.setBusiType(MesPcnEnumUtil.STATION_BUSI_TYPE.STEP_CONTENT.getValue());
        this.sendMessage(reqBean, resultBean);
        return super.init(reqBean);
    }

    @Override
    public StepResult execute(StationRequestBean reqBean) {
        log.info("sxOuterPrintCheckSnStepService[execute] 参数：{}", reqBean);

        StationResultBean resultBean = new StationResultBean();
        String err;

        if (StringUtils.isEmpty(reqBean.getOrganizeCode())) {
            err = LocaleUtil.transferLanguage(reqBean.getUserInfo(), "入参缺少工厂代码");
            this.sendMessage(reqBean, resultBean, err, MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
            return StepResult.getNonComplete(err);
        }

        if (StringUtils.isEmpty(reqBean.getWorkOrderNo())) {
            err = LocaleUtil.transferLanguage(reqBean.getUserInfo(), "入参缺少工单号");
            this.sendMessage(reqBean, resultBean, err, MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
            return StepResult.getNonComplete(err);
        }

        if (StringUtils.isEmpty(reqBean.getScanInfo())) {
            err = LocaleUtil.transferLanguage(reqBean.getUserInfo(), "入参缺少扫描的条码信息");
            this.sendMessage(reqBean, resultBean, err, MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
            return StepResult.getNonComplete(err);
        }
        // 获取当前工单，并判断当前工单类型
        MesWorkOrderExt workOrderExt = workOrderExtService.getWorkOrderExtByOrderNo(reqBean.getOrganizeCode(), reqBean.getWorkOrderNo());
        if (null == workOrderExt) {
            err = String.format(LocaleUtil.transferLanguage(reqBean.getUserInfo(), "工单[%s]无效,不能操作"), reqBean.getWorkOrderNo());
            sendMessage(reqBean, resultBean, err, MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
            return StepResult.getNonComplete(err);
        }
        if (MathOperation.compareTo(workOrderExt.getCompleteQty(), workOrderExt.getQty()) >= 0) {
            err = String.format(LocaleUtil.transferLanguage(reqBean.getUserInfo(), "工单[%s]数量已完成,不能操作"), reqBean.getWorkOrderNo());
            sendMessage(reqBean, resultBean, err, MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
            return StepResult.getNonComplete(err);
        }
        if (MesPcnExtEnumUtil.WORK_ORDER_STATUS.OPEN.getValue() != workOrderExt.getWorkOrderStatus()) {
            err = String.format(LocaleUtil.transferLanguage(reqBean.getUserInfo(), "工单[%s]状态为[%s],不能操作"),
                    reqBean.getWorkOrderNo(), MesPcnExtEnumUtil.WORK_ORDER_STATUS.valueOfDescription(workOrderExt.getWorkOrderStatus()));
            sendMessage(reqBean, resultBean, err, MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
            return StepResult.getNonComplete(err);
        }

    /*    MesPackageDetail packageDetail = packageExtService.getPackageDetailByPackNo(reqBean.getOrganizeCode(), reqBean.getScanInfo());
        if(null == packageDetail){
            err = String.format(LocaleUtil.transferLanguage(reqBean.getUserInfo(), "条码[%s]查询本体条码失败"), reqBean.getScanInfo());
            sendMessage(reqBean, resultBean, err, MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
            return StepResult.getNonCompleteStop(err);
        }

        //  // 校验小包装条码对应的本体条码是否归于此工单 查询出本体条码的信息
        MesProduceSnExt produceSnExt = produceSnExtService.getProduceSnExtBySn(reqBean.getOrganizeCode(), packageDetail.getSerialNumber());
        if (produceSnExt == null) {
            err = String.format(LocaleUtil.transferLanguage(reqBean.getUserInfo(), "条码[%s]无效"), reqBean.getSerialNumber());
            sendMessage(reqBean, resultBean, err, MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
            return StepResult.getNonCompleteStop(err);
        }*/

        // 判断当前工单类型
        if (!(MesPcnExtEnumUtil.WORK_ORDER_TYPE.REWORK_ORDER.getValue() == workOrderExt.getWorkOrderType())) {
           // 当前为正常工单 应扫描小包装条码

            //校验大包装条码表里面不能存在此小包装条码
            List<MesOuterPackageDetail> mesOuterPackageDetailList = iOuterPackageSnService.getOuterPackageDetailListByPackageNo(reqBean.getOrganizeCode(),reqBean.getScanInfo());
            if(!(mesOuterPackageDetailList.isEmpty())){
                err = String.format(LocaleUtil.transferLanguage(reqBean.getUserInfo(), "此小包装条码[%s]已经绑定大包装条码"), reqBean.getScanInfo());
                this.sendMessage(reqBean, resultBean, err, MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
                return StepResult.getNonComplete(err);
            }

            // 校验小包装条码是否归属于此工单，校验小包装条码对应的本体条码是否归于此工单，校验小包装条码对应本体条码状态是不是正常下线的
            // 通过组织机构代码和扫描的小包装条码查询出工单信息
            MesPackage pack = packageExtService.getPackageByPackNo(reqBean.getOrganizeCode(), reqBean.getScanInfo());
            if(null == pack){
                err = String.format(LocaleUtil.transferLanguage(reqBean.getUserInfo(), "小包装条码[%s]上一个工位未操作，请检查！"), reqBean.getScanInfo());
                this.sendMessage(reqBean, resultBean, err, MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
                return StepResult.getNonComplete(err);
            }
            // 通过小包装查询得到包装详细信息和条码信息
            MesPackageDetail packageDetail = packageExtService.getPackageDetailByPackNo(reqBean.getOrganizeCode(), reqBean.getScanInfo());
            if(null == packageDetail){
                err = String.format(LocaleUtil.transferLanguage(reqBean.getUserInfo(), "条码[%s]查询本体条码失败"), reqBean.getScanInfo());
                sendMessage(reqBean, resultBean, err, MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
                return StepResult.getNonCompleteStop(err);
            }
            //  // 校验小包装条码对应的本体条码是否归于此工单 查询出本体条码的信息
            MesProduceSnExt produceSnExt = produceSnExtService.getProduceSnExtBySn(reqBean.getOrganizeCode(), packageDetail.getSerialNumber());
            if (produceSnExt == null) {
                err = String.format(LocaleUtil.transferLanguage(reqBean.getUserInfo(), "条码[%s]无效"), reqBean.getSerialNumber());
                sendMessage(reqBean, resultBean, err, MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
                return StepResult.getNonCompleteStop(err);
            }

            // 从redis里面取到小包装条码的记录
            List<InnerPackageRecordModel> outerPackageRecordModelList = getLastRecord(reqBean);
            if (null == outerPackageRecordModelList || outerPackageRecordModelList.size() == 0) {

            } else {
                List<String> list =  outerPackageRecordModelList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getPackageNo()))).map(InnerPackageRecordModel::getPackageNo).collect(Collectors.toList());
                if ( null != list && list.size() != 0) {
                    Integer index = list.indexOf(reqBean.getScanInfo());
                    if (index.compareTo(-1) == 0) {

                    }else{
                        err = String.format(LocaleUtil.transferLanguage(reqBean.getUserInfo(), "当前小包装条码[%s]已扫描，不可重复扫描"), reqBean.getScanInfo());
                        this.sendMessage(reqBean, resultBean, err, MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
                        return StepResult.getNonComplete(err);
                    }
                }

                List<Integer> snTypeList =  outerPackageRecordModelList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getSnType()))).map(InnerPackageRecordModel::getSnType).collect(Collectors.toList());
                if ( null != snTypeList && snTypeList.size() != 0) {
                    Integer i =  snTypeList.get(0);
                    if (i != produceSnExt.getSnType()) {
                        err = String.format(LocaleUtil.transferLanguage(reqBean.getUserInfo(), "当前小包装条码[%s]和之前扫描的小包装条码类型不符，请检查"), reqBean.getScanInfo());
                        this.sendMessage(reqBean, resultBean, err, MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
                        return StepResult.getNonComplete(err);
                    }
                }
            }

            // 若当前工单号和扫描的小包装条码工单号一致
            if(!StringUtils.isEmpty(pack.getWorkOrderNo()) && pack.getWorkOrderNo().equals(reqBean.getWorkOrderNo())){

//                MesPackageDetail packageDetail = packageExtService.getPackageDetailByPackNo(reqBean.getOrganizeCode(), reqBean.getScanInfo());
//                if(null == packageDetail){
//                    err = String.format(LocaleUtil.transferLanguage(reqBean.getUserInfo(), "条码[%s]查询本体条码失败"), reqBean.getScanInfo());
//                    sendMessage(reqBean, resultBean, err, MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
//                    return StepResult.getNonCompleteStop(err);
//                }
//
//                //  // 校验小包装条码对应的本体条码是否归于此工单 查询出本体条码的信息
//                MesProduceSnExt produceSnExt = produceSnExtService.getProduceSnExtBySn(reqBean.getOrganizeCode(), packageDetail.getSerialNumber());
//                if (produceSnExt == null) {
//                    err = String.format(LocaleUtil.transferLanguage(reqBean.getUserInfo(), "条码[%s]无效"), reqBean.getSerialNumber());
//                    sendMessage(reqBean, resultBean, err, MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
//                    return StepResult.getNonCompleteStop(err);
//                }
                // 若当前工单号和扫描的小包装条码对应的本体条码的工单号一致
                if(!StringUtils.isEmpty(produceSnExt.getWorkOrderNo()) && produceSnExt.getWorkOrderNo().equals(reqBean.getWorkOrderNo())){
                    // 当本体条码为正常下线的状态
                    if(produceSnExt.getSnStatus().equals(MesPcnExtEnumUtil.PRODUCE_SN_STATUS.OFFLINE.getValue())){
                        // 返回成功 正常工单处理后置(进行跳号防错)
                        reqBean.getDataMap().put(MesPcnExtConstWords.WORK_ORDER_NO, reqBean.getWorkOrderNo());
                        // 放入包装条码信息
                        reqBean.getDataMap().put(MesPcnExtConstWords.MES_PACKAGE_EXT, pack);
                        reqBean.getDataMap().put(MesPcnExtConstWords.INNER_PACKAGE_NO, reqBean.getScanInfo());
                        reqBean.setSerialNumber(produceSnExt.getSerialNumber());
                        reqBean.setPartNo(workOrderExt.getPartNo());
                        reqBean.setPartName(workOrderExt.getPartNameRdd());
                        StepResult stepResult = StepResult.getSuccessComplete();
                        stepResult.setNextTriggerEvent(MesPcnExtEnumUtil.WORK_ORDER_TYPE.STANDARD_ORDER.name());
                        return stepResult;
                    }else{
                        err = String.format(LocaleUtil.transferLanguage(reqBean.getUserInfo(), "扫描的小包装条码[%s]对应的本体条码[%s]的状态不为正常下线"), reqBean.getScanInfo(),packageDetail.getSerialNumber());
                        sendMessage(reqBean, resultBean, err, MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
                        return StepResult.getNonCompleteStop(err);
                    }
                }else{
                    err = String.format(LocaleUtil.transferLanguage(reqBean.getUserInfo(), "扫描的小包装条码[%s]对应的本体条码[%s]的工单和当前工单不一致"), reqBean.getScanInfo(),packageDetail.getSerialNumber());
                    sendMessage(reqBean, resultBean, err, MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
                    return StepResult.getNonCompleteStop(err);
                }

            }else{
                err = String.format(LocaleUtil.transferLanguage(reqBean.getUserInfo(), "扫描的内包装条码[%s]不属于当前工单号{%s}"), reqBean.getScanInfo(),reqBean.getWorkOrderNo());
                this.sendMessage(reqBean, resultBean, err, MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
                return StepResult.getNonComplete(err);
            }
        // 若为返工工单 此时扫描的为大包装条码
        } else {
            // 校验大包装条码是否归属于此工单，校验小包装条码对应的本体条码是否归于此工单，校验物料号和当前工单物料号一致
            List<MesOuterPackage> mesOuterPackages = iOuterPackageSnService.getOuterPackageListByPackageNo(reqBean.getOrganizeCode(),reqBean.getScanInfo());
            if(null == mesOuterPackages || mesOuterPackages.size() == 0){
                err = String.format(LocaleUtil.transferLanguage(reqBean.getUserInfo(), "扫描的大包装条码[%s]不存在"), reqBean.getScanInfo());
                sendMessage(reqBean, resultBean, err, MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
                return StepResult.getNonCompleteStop(err);
            }
            if(!mesOuterPackages.get(0).getWorkOrderNo().equals(reqBean.getWorkOrderNo())){
                err = String.format(LocaleUtil.transferLanguage(reqBean.getUserInfo(), "扫描的大包装条码[%s]不存在当前返工工单[%s]"), reqBean.getScanInfo(),reqBean.getWorkOrderNo());
                sendMessage(reqBean, resultBean, err, MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
                return StepResult.getNonCompleteStop(err);
            }
            if((mesOuterPackages.get(0).getIsSealed() != MesPcnExtEnumUtil.PACKAGE_IS_SEALED.UNSEALED.getValue())){
                err = String.format(LocaleUtil.transferLanguage(reqBean.getUserInfo(), "扫描的大包装条码[%s]状态不为未封箱"), reqBean.getScanInfo());
                sendMessage(reqBean, resultBean, err, MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
                return StepResult.getNonCompleteStop(err);
            }
            // 放入大包装条码
            reqBean.getDataMap().put(MesPcnExtConstWords.OUTER_PACKAGE_NO_TYPE,mesOuterPackages.get(0).getSampleType());
            reqBean.getDataMap().put(MesPcnExtConstWords.OUTER_PACKAGE_NO,reqBean.getScanInfo());
            reqBean.getDataMap().put(MesPcnExtConstWords.WORK_ORDER_NO, reqBean.getWorkOrderNo());
            reqBean.setSerialNumber("");
            reqBean.setPartNo(workOrderExt.getPartNo());
            reqBean.setPartName(workOrderExt.getPartNameRdd());
            StepResult stepResult = StepResult.getSuccessComplete();

            err = String.format(LocaleUtil.transferLanguage(reqBean.getUserInfo(), "大包装条码[%s]扫描成功"), reqBean.getScanInfo());
            this.sendMessage(reqBean, resultBean, err, MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT);
            // 进入返工流程
            //stepResult.setNextTriggerEvent(MesPcnExtEnumUtil.WORK_ORDER_TYPE.REWORK_ORDER.name());
            return stepResult;
        }

    }

    private String getLastSelectOrderKey(StationRequestBean reqBean) {
        return getCacheKey(reqBean, MesPcnExtConstWords.INNER_PACKAGE);
    }

    private List<InnerPackageRecordModel> getLastRecord(StationRequestBean reqBean) {
        List<InnerPackageRecordModel> outerPackageRecordModelList = (List<InnerPackageRecordModel>) redisMesPcn.getObject(getLastSelectOrderKey(reqBean));
        if(null == outerPackageRecordModelList || outerPackageRecordModelList.size() == 0){
            return outerPackageRecordModelList;
        }else {
            List<InnerPackageRecordModel> newList = outerPackageRecordModelList.stream().filter(o -> o.getWorkOrderNo().equals(reqBean.getWorkOrderNo()) && o.getOrganizeCode().equals(reqBean.getOrganizeCode())).collect(Collectors.toList());
            return newList;
        }
    }

}
