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

import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesNumberRuleMatchDispatchService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProduceSnExtService;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionAssemblyContext;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords;
import cn.estsh.i3plus.pojo.mes.bean.MesProduceSn;
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 org.springframework.util.StringUtils;

import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 自制件规则匹配
 */
@Slf4j
@Service
public class MesNumberRuleMatchSnService implements IMesNumberRuleMatchDispatchService {

    @Autowired
    private IMesProduceSnExtService produceSnExtService;

    @Override
    public Map<String, Object> matchNumberRule(String organizeCode, String sn, Object... params) {

        Map<String, Object> result = new HashMap<>();
        result.put(MesPcnExtConstWords.RESULT, false);

        if (!MesProductionAssemblyContext.class.isAssignableFrom(params[0].getClass())) {
            result.put(MesPcnExtConstWords.MESSAGE, "参数匹配规则信息不是装配件匹配规则!");
            return result;
        }

        MesProductionAssemblyContext context = (MesProductionAssemblyContext) params[0];

        if (StringUtils.isEmpty(context.getAssemblyPartNo())) {
            result.put(MesPcnExtConstWords.MESSAGE, "装配件匹配规则[自制件条码]未维护零件号!");
            return result;
        }

        List<MesProduceSn> produceSnList = produceSnExtService.getProduceSnList(organizeCode, sn);
        if (CollectionUtils.isEmpty(produceSnList)) {
            result.put(MesPcnExtConstWords.MESSAGE, String.format("零件条码[%s]信息不存在!", sn));
            return result;
        }

        List<MesProduceSn> standardList = produceSnList.stream()
                .filter(o -> (null != o && !StringUtils.isEmpty(o.getSnStatus()) && o.getSnStatus().compareTo(MesExtEnumUtil.PRODUCE_SN_STATUS.UNKNOW.getValue()) != 0))
                .sorted(Comparator.comparing(MesProduceSn::getCreateDatetime).reversed()).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(standardList)) {
            result.put(MesPcnExtConstWords.MESSAGE, String.format("零件条码[%s]信息状态[未知]!", sn));
            return result;
        }

        MesProduceSn produceSn = standardList.get(0);
        if (StringUtils.isEmpty(produceSn.getSnStatus()) || StringUtils.isEmpty(produceSn.getQcStatus()) || StringUtils.isEmpty(produceSn.getPartNo())) {
            result.put(MesPcnExtConstWords.MESSAGE, String.format("零件条码[%s]信息异常:状态[%s]质量[%s]零件号[%s]!", sn, produceSn.getSnStatus(), produceSn.getQcStatus(), produceSn.getPartNo()));
            return result;
        }

        if (produceSn.getQcStatus().compareTo(MesExtEnumUtil.PRODUCE_QC_STATUS.QUALIFIED.getValue()) != 0 && produceSn.getQcStatus().compareTo(MesExtEnumUtil.PRODUCE_QC_STATUS.SUSPICIOUS_TO_QUALIFIED.getValue()) != 0) {
            result.put(MesPcnExtConstWords.MESSAGE, String.format("零件条码[%s]信息质量状态[%s]!", sn, MesExtEnumUtil.PRODUCE_QC_STATUS.valueOfDescription(produceSn.getQcStatus())));
            return result;
        }

        //创建/已完成/已拆解都可以被装配
        if (!MesExtEnumUtil.PRODUCE_SN_STATUS.checkAllowAssembly(produceSn.getSnStatus())) {
            result.put(MesPcnExtConstWords.MESSAGE, String.format("零件条码[%s]信息条码状态[%s]!", sn, MesExtEnumUtil.PRODUCE_SN_STATUS.valueOfDescription(produceSn.getSnStatus())));
            return result;
        }

        if (!context.getAssemblyPartNo().equals(produceSn.getPartNo())) {
            result.put(MesPcnExtConstWords.MESSAGE, String.format("零件条码[%s]信息零件号[%s]!", sn, produceSn.getPartNo()));
            return result;
        }

        ((MesProductionAssemblyContext) params[0]).setProductSnId(produceSn.getId());

        result.put(MesPcnExtConstWords.RESULT, true);

        return result;
    }
}
