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

import cn.estsh.i3plus.ext.mes.pcn.api.base.bu.IMesBusiConfigService;
import cn.estsh.i3plus.ext.mes.pcn.api.base.bu3.IMesOuterPackageDetailService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.bu.IBuQmsOqcManageService;
import cn.estsh.i3plus.ext.mes.pcn.apiservice.dao.bu.IBuProduceSnExtDao;
import cn.estsh.i3plus.ext.mes.pcn.apiservice.dao.bu.IBuProduceSnRepairDao;
import cn.estsh.i3plus.ext.mes.pcn.apiservice.daoimpl.bu.BuProduceSnExtDao;
import cn.estsh.i3plus.ext.mes.pcn.apiservice.daoimpl.bu.BuProduceSnRepairDao;
import cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.base.bu.MesBusiConfigService;
import cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.base.bu3.MesOuterPackageDetailService;
import cn.estsh.i3plus.ext.mes.pcn.pojo.bean.MesBusiConfig;
import cn.estsh.i3plus.ext.mes.pcn.pojo.bean.MesOuterPackageDetail;
import cn.estsh.i3plus.ext.mes.pcn.pojo.model.bu.BuOqcProduceSnModel;
import cn.estsh.i3plus.ext.mes.pcn.pojo.model.bu.SxBuOqcDataModel;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtEnumUtil;
import cn.estsh.impp.framework.boot.util.SpringContextsUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description 出货检验 成品 条码组信息
 * @author wangjie
 * @version 1.0
 * @date 2021/1/13 9:28
 **/
@Slf4j
public class BuQmsOqcBySnExecAmountService implements IBuQmsOqcManageService {

    public BuQmsOqcBySnExecAmountService() {}

    @Override
    public SxBuOqcDataModel exec(Map<String, Object> params) {

        SxBuOqcDataModel oqcDataModel = (SxBuOqcDataModel) params.get(MesPcnExtConstWords.MODEL);

        if (null == oqcDataModel) return oqcDataModel;

        log.info("BU-QMS出货检验公共方法 --- 成品出货检验 --- 获取条码组信息 --- 工单类型[{}] --- 线程ID[{}]", oqcDataModel.getWorkOrderTypeName(), Thread.currentThread().getName());

        return new SxBuOqcHandlerFactory(oqcDataModel).createHandler();

    }

}

@Slf4j
class SxBuOqcHandlerFactory {

    private SxBuOqcDataModel oqcDataModel;

    public SxBuOqcHandlerFactory(SxBuOqcDataModel oqcDataModel) {

        this.oqcDataModel = oqcDataModel;

    }

    public SxBuOqcDataModel createHandler() {

        if (null == oqcDataModel || StringUtils.isEmpty(oqcDataModel.getWorkOrderType())) return oqcDataModel;

        switch (MesPcnExtEnumUtil.WORK_ORDER_TYPE.getByValue(oqcDataModel.getWorkOrderType())) {

            case REWORK_ORDER :
                return new SxBuOqcRepairOrderHandler(oqcDataModel).exec();
            case STANDARD_ORDER:
            case ATTEMPT_ORDER:
            default:
                return new SxBuOqcNormalOrderHandler(oqcDataModel).exec();

        }
    }

    private class SxBuOqcNormalOrderHandler extends SxBuOqcAmountHandler {

        private SxBuOqcDataModel oqcDataModel;

        private IBuProduceSnExtDao produceSnExtDao;

        //private IMesBusiConfigService busiConfigService;

        public SxBuOqcNormalOrderHandler(SxBuOqcDataModel oqcDataModel) {

            this.oqcDataModel = oqcDataModel;

            produceSnExtDao = SpringContextsUtil.getBean(BuProduceSnExtDao.class);

            //busiConfigService = SpringContextsUtil.getBean(MesBusiConfigService.class);
        }

        public SxBuOqcDataModel exec() {

            log.info("BU-QMS出货检验公共方法 --- 成品出货检验 --- 获取条码组信息 --- 正常工单 START --- 线程ID[{}]", Thread.currentThread().getName());

            List<BuOqcProduceSnModel> produceSnList = produceSnExtDao.querySnListByOrderNoAndWorkTime4Oqc(oqcDataModel.getOrganizeCode(), oqcDataModel.getWorkOrderNo(), oqcDataModel.getWorkTime(), oqcDataModel.getShiftCode());
            if(!CollectionUtils.isEmpty(produceSnList)) oqcDataModel.setWorkCenterCode(produceSnList.get(0).getWorkCenterCode());
            log.info("出货检验-produceSnList-{} ---- 产线代码{}",produceSnList.get(0).getWorkCenterCode(), oqcDataModel.getWorkCenterCode());

            super.execAmount(produceSnList, oqcDataModel, super.getBigPackageMap());

            log.info("BU-QMS出货检验公共方法 --- 成品出货检验 --- 获取条码组信息 --- 正常工单 SUCCESS --- 线程ID[{}]", Thread.currentThread().getName());

            return oqcDataModel;
        }
    }

    private class SxBuOqcRepairOrderHandler extends SxBuOqcAmountHandler {

        private SxBuOqcDataModel oqcDataModel;

        private IBuProduceSnRepairDao produceSnRepairDao;

        public SxBuOqcRepairOrderHandler(SxBuOqcDataModel oqcDataModel) {

            this.oqcDataModel = oqcDataModel;

            produceSnRepairDao = SpringContextsUtil.getBean(BuProduceSnRepairDao.class);
        }

        public SxBuOqcDataModel exec() {

            log.info("BU-QMS出货检验公共方法 --- 成品出货检验 --- 获取条码组信息 --- 返工工单 START --- 线程ID[{}]", Thread.currentThread().getName());

            List<BuOqcProduceSnModel> produceSnList = produceSnRepairDao.querySnRepairListByOrderNoAndWorkTime4Oqc(oqcDataModel.getOrganizeCode(), oqcDataModel.getWorkOrderNo(), oqcDataModel.getWorkTime(), oqcDataModel.getShiftCode());

            super.execAmount(produceSnList, oqcDataModel, super.getBigPackageMap());

            log.info("BU-QMS出货检验公共方法 --- 成品出货检验 --- 获取条码组信息 --- 返工工单 SUCCESS --- 线程ID[{}]", Thread.currentThread().getName());

            return oqcDataModel;
        }
    }

    private class SxBuOqcAmountHandler {

        private IMesBusiConfigService busiConfigService;

        private IMesOuterPackageDetailService outerPackageDetailService;

        public SxBuOqcAmountHandler() {
            busiConfigService = SpringContextsUtil.getBean(MesBusiConfigService.class);
            outerPackageDetailService = SpringContextsUtil.getBean(MesOuterPackageDetailService.class);
        }

        public void execAmount(List<BuOqcProduceSnModel> produceSnList, SxBuOqcDataModel oqcDataModel, Map<String, String> bigPackageMap) {
            List<Map<String, String>> prodMapList = null;

            produceSnList = CollectionUtils.isEmpty(produceSnList) ? null :
                    produceSnList.stream().filter(o ->
                            (null != o && o.getLastWorkOrderNo().equals(oqcDataModel.getWorkOrderNo()) && MesPcnExtEnumUtil.PRODUCE_SN_QC_STATUS.QUALIFIED.getValue() == o.getQcStatus()
                            && (MesPcnExtEnumUtil.PRODUCE_SN_STATUS.ERR_OFFLINE.getValue() == o.getSnStatus() || MesPcnExtEnumUtil.PRODUCE_SN_STATUS.OFFLINE.getValue() == o.getSnStatus())
                            && !StringUtils.isEmpty(o.getOutWorkCenterTime())))
                    .collect(Collectors.toList());

            if (CollectionUtils.isEmpty(produceSnList)) return;

            produceSnList = produceSnList.stream().filter(o -> null != o).sorted(Comparator.comparing(BuOqcProduceSnModel::getOutWorkCenterTime)).collect(Collectors.toList());

            //boolean isNeedBigPackFlag = false;
            for (BuOqcProduceSnModel produceSn : produceSnList) {
                if (null == produceSn) continue;

                if (CollectionUtils.isEmpty(prodMapList)) {
                    prodMapList = new ArrayList<>();
                }

                Map<String, String> prodMap = new HashMap<>();
                prodMap.put(MesPcnExtConstWords.SERIAL_NUMBER, produceSn.getSerialNumber());
                prodMap.put(MesPcnExtConstWords.PACKAGENO, produceSn.getPackageNo());
                prodMap.put(MesPcnExtConstWords.OUT_WC_TIME, produceSn.getOutWorkCenterTime());

                if(!CollectionUtils.isEmpty(bigPackageMap)){
                    //净水器线标志
                    //if(!prodMap.containsKey(MesPcnExtConstWords.IS_NEED_BIG_PACK_NO)) prodMap.put(MesPcnExtConstWords.IS_NEED_BIG_PACK_NO, "true");
                    //isNeedBigPackFlag = true;
                    //if(!StringUtils.isEmpty(bigPackageMap.get(MesPcnExtConstWords.RESULT))){
                    //    String bigPackageNo = bigPackageMap.get(produceSn.getPackageNo());
                    //    if(!StringUtils.isEmpty(bigPackageNo)){
                    //        prodMap.put(MesPcnExtConstWords.BIG_PACKAGE_NO, bigPackageNo);
                    //    }
                    //}else{
                    prodMap.put(MesPcnExtConstWords.BIG_PACKAGE_NO, bigPackageMap.containsKey(produceSn.getPackageNo()) ? bigPackageMap.get(produceSn.getPackageNo()) : produceSn.getPackageNo());
                    //}
                }else{
                    prodMap.put(MesPcnExtConstWords.BIG_PACKAGE_NO, produceSn.getPackageNo());
                }
                prodMapList.add(prodMap);

                if (!StringUtils.isEmpty(oqcDataModel.getSerialNumber()) && oqcDataModel.getSerialNumber().equals(produceSn.getSerialNumber())) break;
            }
            //oqcDataModel.setIsNeedBigPackFlag(isNeedBigPackFlag);
            oqcDataModel.setProdMapList(prodMapList);
        }

        private Map<String, String> getBigPackageMap() {
            if(StringUtils.isEmpty(oqcDataModel.getWorkCenterCode())) return null;
            Map<String, String> resultMap = new HashMap<>(1);
            MesBusiConfig mesBusiConfig = busiConfigService.queryBusiConfigeByCfgCode(MesPcnExtConstWords.WATER_PURIFIER_CODE, oqcDataModel.getOrganizeCode());
            //boolean isWaterPurifierWorkCenter = false;
            if(mesBusiConfig != null && !StringUtils.isEmpty(mesBusiConfig.getCfgValue())){
                List<String> workCenterCodeList = Arrays.stream(mesBusiConfig.getCfgValue().split(MesPcnExtConstWords.COMMA)).collect(Collectors.toList());
                if(workCenterCodeList.contains(oqcDataModel.getWorkCenterCode())) {
                    // 根据小包装条码获取大包装条码
                    // key:小包装条码 value: 大包装条码
                    List<MesOuterPackageDetail> boundOuterPackDetailList = outerPackageDetailService.findBoundOuterPackDetailByWorkOrderNo(oqcDataModel.getOrganizeCode(), oqcDataModel.getWorkOrderNo());
                    Map<String, String> bigPackageNoMap = boundOuterPackDetailList.stream().filter(o -> o.getBindStatus() == MesPcnExtEnumUtil.PACKAGE_BIND_STATUS.BINGDING.getValue()).collect(Collectors.toMap(o -> o.getInnerPackageNo(), o -> o.getOuterPackageNo()));
                    bigPackageNoMap.putAll(resultMap);
                    return bigPackageNoMap;
                }
            }
            return null;
        }

    }
}


