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

import cn.estsh.i3plus.ext.mes.pcn.api.base.IPartExtService;
import cn.estsh.i3plus.ext.mes.pcn.api.base.ISxWorkOrderExtService;
import cn.estsh.i3plus.ext.mes.pcn.api.base.IWorkCenterExtService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IProduceSnExtService;
import cn.estsh.i3plus.ext.mes.pcn.pojo.bean.*;
import cn.estsh.i3plus.ext.mes.pcn.pojo.model.ProduceSnExtModel;
import cn.estsh.i3plus.ext.mes.pcn.pojo.model.WorkCenterExtModel;
import cn.estsh.i3plus.ext.mes.pcn.pojo.model.WorkOrderExtModel;
import cn.estsh.i3plus.ext.mes.pcn.pojo.repository.*;
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.convert.ConvertBean;
import cn.estsh.i3plus.platform.common.tool.MathOperation;
import cn.estsh.i3plus.platform.common.tool.TimeTool;
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
import cn.estsh.i3plus.pojo.base.enumutil.MesPcnEnumUtil;
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 lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.Optional;

/**
 * @Description : 工步业务-本体包装产量统计工步
 * @Reference :
 * @Author : wangjie
 * @CreateDate : 2019-07-11
 * @Modify:
 **/
@Slf4j
@Service("sxNoumenonPackageOutPutStatisticsStepServiceBak")
public class SxNoumenonPackageOutPutStatisticsStepServiceBak extends BaseStepService {

    @Autowired
    private MesOqcPackageDetailRepository oqcPackageDetailRepository;

    @Autowired
    private IWorkCenterExtService workCenterExtService;

    @Autowired
    private MesOutPutStatisticsRepository outPutStatisticsRepository;

    @Autowired
    private MesOutPutStatisticsOqcRepository outPutStatisticsOqcRepository;

    @Autowired
    private MesOqcCheckRepository oqcCheckRepository;

    @Autowired
    private SxOqcSingleRepository sxOqcSingleRepository;

    @Autowired
    private ISxWorkOrderExtService workOrderExtService;

    @Autowired
    private IProduceSnExtService produceSnExtService;

    @Autowired
    private IPartExtService partExtService;

    @Autowired
    private SxPartOqcRepository partOqcRepository;

    @Override
    public StepResult execute(StationRequestBean reqBean) {
        log.info("SxNoumenonPackageOutPutStatisticsStepService[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);
            foundExThrowNoShowMsg();
        }

        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);
            foundExThrowNoShowMsg();
        }

        WorkCenterExtModel centerModel = (WorkCenterExtModel) reqBean.getDataMap().get(MesPcnExtConstWords.WORK_CENTER);
        if (null == centerModel || (StringUtils.isEmpty(centerModel.getShiftCode()) || StringUtils.isEmpty(centerModel.getWorkTime()))) {
            MesWorkCenterExt workCenterExt = workCenterExtService.getWorkCenterExtByWorkCenterCode(reqBean.getOrganizeCode(), reqBean.getWorkCenterCode());
            if (null == workCenterExt) {
                err = String.format(LocaleUtil.transferLanguage(reqBean.getUserInfo(), "生产线代码[%s]无效"), reqBean.getWorkCenterCode());
                this.sendMessage(reqBean, resultBean, err, MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
                foundExThrowNoShowMsg();
            }
            if (StringUtils.isEmpty(workCenterExt.getShiftCode()) || StringUtils.isEmpty(workCenterExt.getWorkTime())) {
                err = String.format(LocaleUtil.transferLanguage(reqBean.getUserInfo(), "生产线代码[%s]未启动班次"), reqBean.getWorkCenterCode());
                this.sendMessage(reqBean, resultBean, err, MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
                foundExThrowNoShowMsg();
            }
            centerModel = new WorkCenterExtModel();
            BeanUtils.copyProperties(workCenterExt, centerModel, MesPcnExtConstWords.ID);
            reqBean.getDataMap().put(MesPcnExtConstWords.WORK_CENTER, centerModel);
        }

        WorkOrderExtModel orderModel = (WorkOrderExtModel) reqBean.getDataMap().get(MesPcnExtConstWords.WORK_ORDER);
        if (null == orderModel) {
            orderModel = getWorkOrderExtModel(reqBean);
        }
        if (null == orderModel) {
            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);
            foundExThrowNoShowMsg();
        }

        MesPartExt partExt = partExtService.getPartExt(reqBean.getOrganizeCode(), orderModel.getPartNo());
        if (null == partExt) {
            err = String.format(LocaleUtil.transferLanguage(reqBean.getUserInfo(), "物料编码[%s]无效"), orderModel.getPartNo());
            sendMessage(reqBean, resultBean, err, MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
            foundExThrowNoShowMsg();
        }

        ProduceSnExtModel snModel = (ProduceSnExtModel) reqBean.getDataMap().get(MesPcnExtConstWords.PRODUCE_SN);
        if (null == snModel || !snModel.getSerialNumber().equals(reqBean.getSerialNumber())) {
            snModel = getProduceSnExtModel(reqBean);
        }

        Boolean sxOqcSingleBoo = (StringUtils.isEmpty(partExt.getIsOqc()) || CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue() == partExt.getIsOqc());
        SxOqcSingle sxOqcSingle = null;

        MesOutPutStatistics param = new MesOutPutStatistics();
        param.setWorkCenterCode(reqBean.getWorkCenterCode());
        param.setWorkOrderNo(reqBean.getWorkOrderNo());
        param.setShiftCode(centerModel.getShiftCode());
        param.setWorkTime(centerModel.getWorkTime());

        List<MesOutPutStatistics> outPutStatisticsList = outPutStatisticsRepository.findByProperty(
                new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.IS_VALID, MesPcnExtConstWords.WORK_ORDER_NO},
                new Object[]{reqBean.getOrganizeCode(), CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), reqBean.getWorkOrderNo()},
                " order by createDatetime desc ");
        WorkCenterExtModel finalCenterModel = centerModel;
        Optional<MesOutPutStatistics> outPutStatisticsOp = CollectionUtils.isEmpty(outPutStatisticsList) ? null :
                outPutStatisticsList.stream().filter(o -> (null != o && o.getWorkTime().equals(finalCenterModel.getWorkTime()) && o.getShiftCode().equals(finalCenterModel.getShiftCode()))).findFirst();
        MesOutPutStatistics outPutStatistics;
        if (null == outPutStatisticsOp || !outPutStatisticsOp.isPresent()) {
            if (!CollectionUtils.isEmpty(outPutStatisticsList)) {
                MesOutPutStatisticsOqc outPutStatisticsOqc = outPutStatisticsOqcRepository.getByProperty(
                        new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.IS_VALID, MesPcnExtConstWords.PID},
                        new Object[]{reqBean.getOrganizeCode(), CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), outPutStatisticsList.get(0).getId()});
                if (null != outPutStatisticsOqc && !StringUtils.isEmpty(outPutStatisticsOqc.getCheckLimit()) &&
                        MathOperation.compareTo(outPutStatisticsOqc.getCheckLimit(), outPutStatisticsList.get(0).getQty()) > 0) {
                    Double overLimit = MathOperation.sub(outPutStatisticsOqc.getCheckLimit(), outPutStatisticsList.get(0).getQty());
                    outPutStatisticsOqc.setCheckLimit(outPutStatisticsList.get(0).getQty());
                    ConvertBean.serviceModelUpdate(outPutStatisticsOqc, reqBean.getUserInfo());
                    outPutStatisticsOqc.setSystemSyncStatus(MesPcnExtEnumUtil.IF_SYNC_STATUS.NO_SYNC.getValue());
                    outPutStatisticsOqcRepository.save(outPutStatisticsOqc);

                    List<MesOqcCheck> oqcCheckList = oqcCheckRepository.findByProperty(
                            new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.IS_VALID,
                                    MesPcnExtConstWords.ORDER_NO, MesPcnExtConstWords.WORK_CENTER_CODE, MesPcnExtConstWords.SHIFT_CODE, MesPcnExtConstWords.WORK_TIME},
                            new Object[]{reqBean.getOrganizeCode(), CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(),
                                    reqBean.getWorkOrderNo(), reqBean.getWorkCenterCode(), outPutStatisticsOqc.getShiftCode(), outPutStatisticsOqc.getWorkTime()});
                    Optional<MesOqcCheck> oqcCheckOp1 = CollectionUtils.isEmpty(oqcCheckList) ? null : oqcCheckList.stream()
                            .filter(o -> (null != o && MesPcnExtEnumUtil.OQC_CHECK_TYPE.TEARDOWN_INSPECTION.getValue() != o.getOqcType() &&
                                    MesPcnExtEnumUtil.ASSOCIATED_STATUS.OPEN.getValue() == o.getAssociatedStatus())).findFirst();
                    if (null != oqcCheckOp1 && oqcCheckOp1.isPresent()) {
                        MesOqcCheck oqcCheck1 = oqcCheckOp1.get();
                        oqcCheck1.setBatchLimit(MathOperation.sub(oqcCheck1.getBatchLimit(), overLimit));
                        if (MathOperation.compareTo(oqcCheck1.getBatchLimit(), oqcCheck1.getCheckLimit()) == 0) {
                            oqcCheck1.setAssociatedStatus(MesPcnExtEnumUtil.ASSOCIATED_STATUS.CLOSE.getValue());
                        }
                        ConvertBean.serviceModelUpdate(oqcCheck1, reqBean.getUserInfo());
                        oqcCheckRepository.save(oqcCheck1);

                        Optional<MesOqcCheck> oqcCheckOp2 = oqcCheckList.stream().filter(o -> (null != o &&
                                MesPcnExtEnumUtil.OQC_CHECK_TYPE.TEARDOWN_INSPECTION.getValue() == o.getOqcType() && o.getSerialNumber().equals(oqcCheck1.getSerialNumber()))).findFirst();
                        if (null != oqcCheckOp2 && oqcCheckOp2.isPresent()) {
                            MesOqcCheck oqcCheck2 = oqcCheckOp2.get();
                            oqcCheck2.setCheckLimit(oqcCheck1.getBatchLimit());
                            oqcCheck2.setBatchLimit(oqcCheck1.getBatchLimit());
                            ConvertBean.serviceModelUpdate(oqcCheck2, reqBean.getUserInfo());
                            oqcCheckRepository.save(oqcCheck2);
                        }
                    }
                }
            }


            outPutStatistics = new MesOutPutStatistics();
            outPutStatistics.setWorkCenterCode(reqBean.getWorkCenterCode());
            outPutStatistics.setWorkOrderNo(reqBean.getWorkOrderNo());
            outPutStatistics.setPartNo(reqBean.getPartNo());
            outPutStatistics.setPartNameRdd(reqBean.getPartName());
            outPutStatistics.setShiftCode(centerModel.getShiftCode());
            outPutStatistics.setWorkTime(centerModel.getWorkTime());
            outPutStatistics.setOrderStartTime(orderModel.getStartTime());
            outPutStatistics.setQty(new Double(1));
            outPutStatistics.setPlanQty(orderModel.getQty());
            outPutStatistics.setPlanRemakeQty(orderModel.getPlanQty());
            if (MesPcnExtEnumUtil.PRODUCE_SN_TYPE.REMAKE_SN.getValue() == snModel.getSnType()) {
                outPutStatistics.setRemakeQty(new Double(1));
            } else {
                outPutStatistics.setRemakeQty(new Double(0));
            }
            outPutStatistics.setWorkOrderType(orderModel.getWorkOrderType());
            outPutStatistics.setOrganizeCode(reqBean.getOrganizeCode());
            outPutStatistics.setCategoryCode(centerModel.getCategoryCode());
            outPutStatistics.setCareerCode(centerModel.getCareerCode());
            outPutStatistics.setOutPutFlag(orderModel.getOutPutFlag());
            outPutStatistics.setSystemSyncStatus(MesPcnExtEnumUtil.IF_SYNC_STATUS.NO_SYNC.getValue());
            ConvertBean.serviceModelInitialize(outPutStatistics, reqBean.getUserInfo());
            outPutStatistics.setStartTime(outPutStatistics.getModifyDatetime());
            outPutStatistics.setEndTime(outPutStatistics.getStartTime());

            MesOutPutStatisticsOqc outPutStatisticsOqc = new MesOutPutStatisticsOqc();
            BeanUtils.copyProperties(outPutStatistics, outPutStatisticsOqc);
            outPutStatisticsOqc.setCheckLimit(new Double(0));
            outPutStatisticsOqc.setSpotCheckQty(new Double(0));
            outPutStatisticsOqc.setCheckResult(MesPcnExtEnumUtil.OQC_TOTAL_STATUS.UNTREATED.getValue());
            outPutStatisticsOqc.setSystemSyncStatus(MesPcnExtEnumUtil.IF_SYNC_STATUS.NO_SYNC.getValue());
            outPutStatisticsOqc.setPid(outPutStatisticsRepository.insert(outPutStatistics).getId());
            outPutStatisticsOqcRepository.insert(outPutStatisticsOqc);

        } else {
            outPutStatistics = outPutStatisticsOp.get();
            outPutStatistics.setQty(MathOperation.add(outPutStatistics.getQty(), new Double(1)));
            if (MesPcnExtEnumUtil.PRODUCE_SN_TYPE.REMAKE_SN.getValue() == snModel.getSnType()) {
                outPutStatistics.setRemakeQty(MathOperation.add(outPutStatistics.getRemakeQty(), new Double(1)));
            }
            ConvertBean.serviceModelUpdate(outPutStatistics, reqBean.getUserInfo());
            outPutStatistics.setEndTime(outPutStatistics.getModifyDatetime());
            outPutStatistics.setSystemSyncStatus(MesPcnExtEnumUtil.IF_SYNC_STATUS.NO_SYNC.getValue());
            outPutStatisticsRepository.save(outPutStatistics);

            //出货检验
            if (!sxOqcSingleBoo) {
                MesOqcCheck oqcCheck = oqcCheckRepository.getByProperty(
                        new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.IS_VALID,
                                MesPcnExtConstWords.ORDER_NO, MesPcnExtConstWords.SHIFT_CODE, MesPcnExtConstWords.WORK_TIME, MesPcnExtConstWords.ASSOCIATED_STATUS},
                        new Object[]{reqBean.getOrganizeCode(), CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(),
                                reqBean.getWorkOrderNo(), outPutStatistics.getShiftCode(), outPutStatistics.getWorkTime(), MesPcnExtEnumUtil.ASSOCIATED_STATUS.OPEN.getValue()});
                if (null != oqcCheck) {
                    MesOqcPackageDetail oqcPackageDetail = new MesOqcPackageDetail();
                    oqcPackageDetail.setOrderNo(outPutStatistics.getWorkOrderNo());
                    oqcPackageDetail.setWorkCenterCode(outPutStatistics.getWorkCenterCode());
                    oqcPackageDetail.setOqcNo(oqcCheck.getOqcNo());
                    oqcPackageDetail.setSerialNumber(reqBean.getSerialNumber());
                    oqcPackageDetail.setPackageNo(reqBean.getPackageNo());
                    oqcPackageDetail.setOrganizeCode(reqBean.getOrganizeCode());
                    ConvertBean.serviceModelInitialize(oqcPackageDetail, reqBean.getUserInfo());
                    oqcPackageDetailRepository.insert(oqcPackageDetail);

                    oqcCheck.setCheckLimit(MathOperation.add(oqcCheck.getCheckLimit(), new Double(1)));
                    if (MathOperation.compareTo(oqcCheck.getCheckLimit(), oqcCheck.getBatchLimit()) >= 0) {
                        oqcCheck.setAssociatedStatus(MesPcnExtEnumUtil.ASSOCIATED_STATUS.CLOSE.getValue());
                    }
                    ConvertBean.serviceModelUpdate(oqcCheck, reqBean.getUserInfo());
                    oqcCheckRepository.save(oqcCheck);

                    if (!StringUtils.isEmpty(oqcCheck.getCheckResult()) && null != MesPcnExtEnumUtil.OQC_CHECK_RESULT.getByValue(oqcCheck.getCheckResult())) {
                        sxOqcSingleBoo = true;
                        sxOqcSingle = new SxOqcSingle();
                        sxOqcSingle.setOqcNo(oqcCheck.getOqcNo());
                        sxOqcSingle.setCheckResult(oqcCheck.getCheckResult());
                        sxOqcSingle.setWorkOrderNo(oqcCheck.getOrderNo());
                    }
                }
            }
        }

        if (sxOqcSingleBoo) {
            if (null == sxOqcSingle) {
                sxOqcSingle = new SxOqcSingle();
            }
            sxOqcSingle.setProductSn(reqBean.getSerialNumber());
            sxOqcSingle.setSerialNumber(reqBean.getSerialNumber());
            sxOqcSingle.setPackageNo(reqBean.getPackageNo());
            sxOqcSingle.setPartNo(outPutStatistics.getPartNo());
            sxOqcSingle.setSyncStatus(MesPcnExtEnumUtil.IF_SYNC_STATUS.NO_SYNC.getValue());
            sxOqcSingle.setOrganizeCode(reqBean.getOrganizeCode());
            ConvertBean.serviceModelInitialize(sxOqcSingle, reqBean.getUserInfo());
            sxOqcSingleRepository.insert(sxOqcSingle);
        }

        List<SxPartOqc> partOqcList = partOqcRepository.findByProperty(
                new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.IS_VALID, MesPcnExtConstWords.PART_NO},
                new Object[]{reqBean.getOrganizeCode(), CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), partExt.getPartNo()});
        if (CollectionUtils.isEmpty(partOqcList)) {
            SxPartOqc partOqc = new SxPartOqc();
            partOqc.setPartNo(partExt.getPartNo());
            partOqc.setIsOqc(StringUtils.isEmpty(partOqc.getIsOqc()) ? CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue() : partOqc.getIsOqc());
            partOqc.setSyncStatus(MesPcnExtEnumUtil.IF_SYNC_STATUS.NO_SYNC.getValue());
            partOqc.setOrganizeCode(reqBean.getOrganizeCode());
            ConvertBean.serviceModelInitialize(partOqc, reqBean.getUserInfo());
            partOqcRepository.insert(partOqc);
        } else {
            for (SxPartOqc partOqc : partOqcList) {
                if (null == partOqc) {
                    continue;
                }
                Integer isOqc = StringUtils.isEmpty(partExt.getIsOqc()) ? CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue() : partExt.getIsOqc();
                if (isOqc.compareTo(partOqc.getIsOqc()) != 0) {
                    partOqc.setIsOqc(isOqc);
                    partOqc.setSyncStatus(MesPcnExtEnumUtil.IF_SYNC_STATUS.NO_SYNC.getValue());
                    ConvertBean.serviceModelUpdate(partOqc, reqBean.getUserInfo());
                    partOqcRepository.save(partOqc);
                }
            }
        }

        return StepResult.getSuccessComplete();
    }

    private WorkOrderExtModel getWorkOrderExtModel(StationRequestBean reqBean) {
        WorkOrderExtModel orderModel = null;
        MesWorkOrderExt workOrderExt = workOrderExtService.getWorkOrderExtByOrderNo(reqBean.getOrganizeCode(), reqBean.getWorkOrderNo());
        if (null != workOrderExt) {
            orderModel = new WorkOrderExtModel();
            BeanUtils.copyProperties(workOrderExt, orderModel, MesPcnExtConstWords.ID);
        }
        return orderModel;
    }

    private ProduceSnExtModel getProduceSnExtModel(StationRequestBean reqBean) {
        ProduceSnExtModel snModel = null;
        MesProduceSnExt produceSnExt = produceSnExtService.getProduceSnExtBySn(reqBean.getOrganizeCode(), reqBean.getSerialNumber());
        if (null != produceSnExt) {
            snModel = new ProduceSnExtModel();
            BeanUtils.copyProperties(produceSnExt, snModel, MesPcnExtConstWords.ID);
        }
        return snModel;
    }

}
