package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.rulematch.containerbind;

import cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.rulematch.MesNumberRuleMatchRegularExpressionService;
import cn.estsh.i3plus.ext.mes.pcn.apiservice.util.MesPcnException;
import cn.estsh.i3plus.ext.mes.pcn.pojo.model.MesContainerPartsModel;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords;
import cn.estsh.i3plus.platform.common.tool.CheckTool;
import cn.estsh.i3plus.pojo.base.bean.DdlPackBean;
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
import cn.estsh.i3plus.pojo.base.tool.DdlPreparedPack;
import cn.estsh.i3plus.pojo.mes.bean.*;
import cn.estsh.i3plus.pojo.mes.repository.MesCustPartInvoicedRepository;
import cn.estsh.i3plus.pojo.mes.repository.MesCustomerPartRepository;
import cn.estsh.i3plus.pojo.mes.repository.MesPackingDefineRepository;
import cn.estsh.i3plus.pojo.mes.repository.MesPartRepository;
import cn.estsh.i3plus.pojo.mes.util.MesExtEnumUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 供应商箱码加料
 */
@Slf4j
@Component
public class MesContainerBindCooperationPackageService extends MesAbstractContainerBindDispatchService {
    @Autowired
    private MesPartRepository mesPartRDao;
    @Autowired
    private MesPackingDefineRepository mesPackingDefineRDao;
    @Autowired
    private MesCustomerPartRepository mesCustomerPartRDao;

    @Autowired
    private MesCustPartInvoicedRepository partInvoicedRao;

    public MesContainerBindCooperationPackageService() {
        super(null, MesExtEnumUtil.CONTAINER_PART_MATCH_TYPE.MATCH_TYPE_40);
    }

    @Override
    public Map<String, Object> matchNumberRule(String organizeCode, String barcode, MesContainerPartsModel model) {
        Map<String, Object> result = new HashMap<>();
        result.put(MesPcnExtConstWords.DATA_TYPE, MesExtEnumUtil.CONTAINER_BARCODE_DATA_TYPE.STATUS_20.getValue());
        result.put(MesPcnExtConstWords.RESULT, false);

        List<MesPackingDefine> packingDefines = mesPackingDefineRDao.findByProperty(new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.IS_VALID},
                new Object[]{organizeCode, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue()});

        for (MesPackingDefine packingDefine : packingDefines) {
            Double qty = checkPackingDefine(organizeCode, packingDefine, barcode, model.getPartNo());
            if (qty != null && qty > 0) {
                result.put(MesPcnExtConstWords.QTY, qty);
                result.put(MesPcnExtConstWords.RESULT, true);
                return result;
            }
        }
        return result;
    }

    private Double checkPackingDefine(String organizeCode, MesPackingDefine packingDefine, String barcode, String rulePartNo) {
        //解析获取信息保存
        if (StringUtils.isEmpty(packingDefine.getSplitChar())) {
            return null;
        }
        try {
            String[] split = barcode.split("\\" + packingDefine.getSplitChar());
            //工厂校验
            checkOrganizeCode(organizeCode, packingDefine, split);
            //获取物料信息是否存在
            MesPart part = getMesPart(organizeCode, packingDefine, split);
            if (part == null || !Objects.equals(part.getPartNo(), rulePartNo)) {
                return null;
            }
            //获取数量信息是否存在
            return getQty(packingDefine, split);
        } catch (Exception ex) {
            return null;
        }
    }

    private void checkOrganizeCode(String organizeCode, MesPackingDefine packingDefine, String[] split) {
        if (Objects.equals(packingDefine.getCheckOrganizeCode(), CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue())) {
            return;
        }
        if (StringUtils.isEmpty(packingDefine.getOrganizeIndex()) || packingDefine.getOrganizeIndex() > split.length
                || StringUtils.isEmpty(split[packingDefine.getOrganizeIndex() - 1])) {
            MesPcnException.throwMesBusiException("工厂所在位置不存在,请检查数据!");
        }
        String splitOrganizeCode = split[packingDefine.getOrganizeIndex() - 1];
        if (!Objects.equals(splitOrganizeCode, organizeCode)) {
            MesPcnException.throwMesBusiException("箱条码工厂[%s]和当前工厂[%s]不匹配,请检查数据!", splitOrganizeCode, organizeCode);
        }
    }

    private MesPart getMesPart(String organizeCode, MesPackingDefine packingDefine, String[] split) {
        if (StringUtils.isEmpty(packingDefine.getPartNoIndex()) || packingDefine.getPartNoIndex() > split.length
                || StringUtils.isEmpty(split[packingDefine.getPartNoIndex() - 1])) {
            MesPcnException.throwMesBusiException("物料号所在位置不存在,请检查数据!");
        }
        String partNo = split[packingDefine.getPartNoIndex() - 1];
        if (Objects.equals(packingDefine.getPackBarcodeCustPartNo(), CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue())) {
            DdlPackBean invoicePackBean = DdlPackBean.getDdlPackBean(organizeCode);
            DdlPreparedPack.getStringEqualPack(partNo, MesPcnExtConstWords.CUST_PART_NO, invoicePackBean);
            MesCustPartInvoiced invoiced = partInvoicedRao.getByProperty(invoicePackBean);
            if (invoiced != null && !StringUtils.isEmpty(invoiced.getPartNo())) {
                partNo = invoiced.getPartNo();
            } else {
                DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
                DdlPreparedPack.getStringEqualPack(partNo, MesPcnExtConstWords.CUST_PART_NO, packBean);
                MesCustomerPart mesCustomerPart = mesCustomerPartRDao.getByProperty(packBean);
                if (mesCustomerPart == null) {
                    MesPcnException.throwMesBusiException("客户零件号[%s]信息不存在,请检查数据!", partNo);
                }
                partNo = mesCustomerPart.getErpPartNo();
            }
            if (StringUtils.isEmpty(partNo)) {
                MesPcnException.throwMesBusiException("客户零件号[%s]未绑定物料号数据,请检查数据!", split[packingDefine.getPartNoIndex() - 1]);
            }
        }
        return checkPart(organizeCode, partNo);
    }

    private MesPart checkPart(String organizeCode, String partNo) {
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getStringEqualPack(partNo, MesPcnExtConstWords.PART_NO, packBean);
        MesPart mesPart = mesPartRDao.getByProperty(packBean);
        if (Objects.isNull(mesPart)) {
            MesPcnException.throwMesBusiException("物料[%s]信息不存在,请检查数据!", partNo);
        }
        return mesPart;
    }

    private Double getQty(MesPackingDefine packingDefine, String[] split) {
        if (StringUtils.isEmpty(packingDefine.getQtyIndex()) || packingDefine.getQtyIndex() > split.length
                || StringUtils.isEmpty(split[packingDefine.getQtyIndex() - 1])) {
            MesPcnException.throwMesBusiException("数量所在位置不存在,请检查数据!");
        }
        //校验是否数字
        if (!CheckTool.isNumber(split[packingDefine.getQtyIndex() - 1])) {
            MesPcnException.throwMesBusiException("数量所在位置不为数字类型,请检查数据!");
        }
        return Double.parseDouble(split[packingDefine.getQtyIndex() - 1]);
    }
}
