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

import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProduceSnExtService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionDispatchContextStepService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionProcessContextStepService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.recyclablepackage.IMesRecyclablePackageBindingService;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesEquipVariableCollectContext;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionProcessContext;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionPsInContext;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionRecyclablePackageContext;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords;
import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.BaseStepService;
import cn.estsh.i3plus.pojo.mes.bean.MesProdRouteOptParam;
import cn.estsh.i3plus.pojo.mes.bean.MesProduceSn;
import cn.estsh.i3plus.pojo.mes.bean.MesWorkCell;
import cn.estsh.i3plus.pojo.mes.bean.recyclablepackage.MesRecyclablePackageBinding;
import cn.estsh.i3plus.pojo.mes.bean.recyclablepackage.MesRecyclablePackageBindingDetail;
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.i3plus.pojo.mes.util.MesExtEnumUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

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

/**
 * @Description : 原箱进原箱出
 * @Reference :
 * @Author : junsheng.li
 * @CreateDate 2024/9/12 11:20
 * @Modify:
 **/
@Slf4j
@Service("mesProcessMethodSourceBoxInOutStepService")
public class MesProcessMethodSourceBoxInOutStepService extends BaseStepService {

    @Autowired
    private IMesProductionProcessContextStepService productionProcessContextStepService;

    @Autowired
    private IMesProductionDispatchContextStepService productionDispatchContextStepService;

    @Autowired
    private IMesRecyclablePackageBindingService mesRecyclablePackageBindingService;

    @Autowired
    private IMesProduceSnExtService produceSnExtService;

    @Autowired
    private MesProductSnCheckStepService productSnCheckStepService;

    @Override
    public StepResult execute(StationRequestBean reqBean) {

        StationResultBean resultBean = new StationResultBean();

        StepResult stepResult = StepResult.getSuccessComplete();

        //获取上下文信息
        MesProductionProcessContext productionProcessContext = productionProcessContextStepService.dispatchCurCellEquipment(reqBean);

        //配置错误 抛出异常
        if (!productionProcessContext.getSuccess()){
            stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), productionProcessContext.getMessage());
        }

        //存储生产过程上下文对象
        productionProcessContextStepService.dispatchProductionProcessContext(reqBean, productionProcessContext);

        //获取上下文生产扫/读信息:可回用包装条码
        List<MesEquipVariableCollectContext> equipVariableCollectContextList = productionDispatchContextStepService.getScanRecyclablePackageContext(reqBean);

        //没有待验证的可回用包装条码 并且存在已验证过的可回用包装条码,默认放行
        if (CollectionUtils.isEmpty(equipVariableCollectContextList) && productionDispatchContextStepService.checkProductionRecyclablePackageContextIsExist(reqBean)){
            return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, "当前没有需要验证的可回用包装条码,且存在已验证可回用包装条码信息,当前工步默认放行!");
        }

        if (CollectionUtils.isEmpty(equipVariableCollectContextList)){
            return stepNonCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, "当前缺失可回用包装条码信息!");
        }

        //清除本次已获取得到的可回用包装条码信息
        productionDispatchContextStepService.removeScanRecyclablePackageContext(reqBean);

        //从上下文中取出工位对象
        MesWorkCell workCell = productionProcessContext.getWorkCell();

        //上下文对象-零件条码
        List<MesProductionPsInContext> productionPsInContextList = new ArrayList<>();
        //上下文对象-可回用包装
        List<MesProductionRecyclablePackageContext> recyclablePackageContextList = new ArrayList<>();

        if (!sourceBoxInOut(reqBean, equipVariableCollectContextList, stepResult, productionPsInContextList,recyclablePackageContextList, workCell).isCompleted()) {
            return stepNonCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, stepResult.getMsg());
        }

        //保存进料主条码数据
        productionDispatchContextStepService.dispatchProductionPsInContext(reqBean, productionPsInContextList);

        //保存进料可回用包装
        productionDispatchContextStepService.dispatchProductionRecyclablePackageContext(reqBean, recyclablePackageContextList);

        return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, String.format("可回用包装条码%s校验成功!", equipVariableCollectContextList.iterator().next().getEquipVariableValue()));
    }


    public StepResult sourceBoxInOut(StationRequestBean reqBean, List<MesEquipVariableCollectContext> equipVariableCollectContextList, StepResult stepResult, List<MesProductionPsInContext> productionPsInContextList,List<MesProductionRecyclablePackageContext> recyclablePackageContextList, MesWorkCell workCell) {
        //获取包装绑定主表
        MesRecyclablePackageBinding recyclablePackageBinding = mesRecyclablePackageBindingService.getMesRecyclablePackageBindingByPackageSn(reqBean.getOrganizeCode(), equipVariableCollectContextList.iterator().next().getEquipVariableValue());
        if (Objects.isNull(recyclablePackageBinding)){
            return stepResult.isCompleted(false).msg(String.format("回收包装绑定[%s]信息不存在", equipVariableCollectContextList.iterator().next().getEquipVariableValue()));
        }
        //校验状态
        if (MesExtEnumUtil.RECYCLABLE_PACKAGE_PACKAGE_BINDING_STATUS.CLOSED.getValue() != recyclablePackageBinding.getStatus()) {
            return stepResult.isCompleted(false).msg(String.format("回收包装绑定[%s]状态不为[已关箱]", equipVariableCollectContextList.iterator().next().getEquipVariableValue()));
        }
        //获取绑定明细信息
        List<MesRecyclablePackageBindingDetail> bindingDetailList = mesRecyclablePackageBindingService.findMesRecyclablePackageBindingDetailByPid(reqBean.getOrganizeCode(), recyclablePackageBinding.getId());

        if (CollectionUtils.isEmpty(bindingDetailList)){
            return stepResult.isCompleted(false).msg(String.format("回收包装绑定[%s]明细信息不存在", equipVariableCollectContextList.iterator().next().getEquipVariableValue()));
        }
        //查询条码信息
        Map<String, List<MesProduceSn>> produceSnMap = produceSnExtService.getProduceSnMap(reqBean.getOrganizeCode(), bindingDetailList.stream().map(MesRecyclablePackageBindingDetail::getProductSn).collect(Collectors.toList()));
        for (MesRecyclablePackageBindingDetail bindingDetail : bindingDetailList) {
            //外协件
            if (CollectionUtils.isEmpty(produceSnMap) || !produceSnMap.containsKey(bindingDetail.getProductSn())) {
                for (int i = 0; i < bindingDetail.getQty(); i++) {
                    productionPsInContextList.add(new MesProductionPsInContext(reqBean.getOrganizeCode(), bindingDetail.getProductSn()).messageSource(equipVariableCollectContextList.iterator().next().getMessageSource()));
                }
                recyclablePackageContextList.add(new MesProductionRecyclablePackageContext(recyclablePackageBinding,bindingDetail));
                //自制件
            } else {
                recyclablePackageContextList.add(new MesProductionRecyclablePackageContext(recyclablePackageBinding,bindingDetail).setId(produceSnMap.get(bindingDetail.getProductSn()).iterator().next().getId()));
                productSnCheckStepService.createProductionPsInContext(reqBean, stepResult, workCell, equipVariableCollectContextList.iterator().next(), produceSnMap.get(bindingDetail.getProductSn()), productionPsInContextList);
            }
        }
        //流程包含解绑工步[工步参数]
        Optional<Map<String, MesProdRouteOptParam>> stepParamMap = getStepParams(reqBean);
        if ((null != stepParamMap && stepParamMap.isPresent() && stepParamMap.get().containsKey(MesPcnExtConstWords.CONTEXT_UNBINDING_STEP)) && !Boolean.parseBoolean(stepParamMap.get().get(MesPcnExtConstWords.CONTEXT_UNBINDING_STEP).getParamValue())) {
            mesRecyclablePackageBindingService.doMesRecyclablePackageUnBinding(recyclablePackageBinding, bindingDetailList, reqBean.getUserInfo());
        }
        return stepResult;
    }

}
