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

import cn.estsh.i3plus.ext.mes.api.busi.IProductEncodeCfgExtService;
import cn.estsh.i3plus.ext.mes.pojo.bean.MesPartExt;
import cn.estsh.i3plus.ext.mes.pojo.model.MatchRuleCodeModel;
import cn.estsh.i3plus.ext.mes.pojo.sqlpack.MesExtHqlPack;
import cn.estsh.i3plus.ext.mes.pojo.util.MesExtConstWords;
import cn.estsh.i3plus.ext.mes.pojo.util.MesExtEnumUtil;
import cn.estsh.i3plus.platform.common.convert.ConvertBean;
import cn.estsh.i3plus.platform.common.exception.ImppExceptionEnum;
import cn.estsh.i3plus.platform.common.tool.TimeTool;
import cn.estsh.i3plus.pojo.base.bean.DdlPackBean;
import cn.estsh.i3plus.pojo.base.bean.ListPager;
import cn.estsh.i3plus.pojo.base.common.Pager;
import cn.estsh.i3plus.pojo.base.common.PagerHelper;
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
import cn.estsh.i3plus.pojo.mes.bean.MesProductEncodeCfg;
import cn.estsh.i3plus.pojo.mes.repository.MesProductEncodeCfgRepository;
import cn.estsh.impp.framework.boot.exception.ImppExceptionBuilder;
import cn.estsh.impp.framework.boot.util.LocaleUtils;
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;

/**
 * @Author: wangjie
 * @CreateDate: 2019/8/23 1:16 PM
 * @Description: 编码规则
 **/

@Service
public class ProductEncodeCfgExtService implements IProductEncodeCfgExtService {

    @Autowired
    private MesProductEncodeCfgRepository productEncodeCfgRepository;

    @Override
    public ListPager<MesProductEncodeCfg> queryMesProductEncodeCfgByPager(MesProductEncodeCfg productEncodeCfg, Pager pager) {
        if (productEncodeCfg == null) {
            pager = PagerHelper.getPager(pager, productEncodeCfgRepository.listCount());
            return new ListPager(productEncodeCfgRepository.listPager(pager), pager);
        } else {
            DdlPackBean hqlPack = MesExtHqlPack.getProductEncodeCfg(productEncodeCfg);
            pager = PagerHelper.getPager(pager, productEncodeCfgRepository.findByHqlWhereCount(hqlPack));
            hqlPack.setOrderByStr(productEncodeCfg.orderBy());
            List<MesProductEncodeCfg> productEncodeCfgs = productEncodeCfgRepository.findByHqlWherePage(hqlPack, pager);
            productEncodeCfgs = this.transferCodeToName(productEncodeCfgs);
            return new ListPager(productEncodeCfgs, pager);
        }
    }

    /**
     * 设置冗余字段用于导出
     * @param productEncodeCfgs
     * @return
     */
    private List<MesProductEncodeCfg> transferCodeToName(List<MesProductEncodeCfg> productEncodeCfgs) {
        for (MesProductEncodeCfg productEncodeCfg : productEncodeCfgs) {
            if(!StringUtils.isEmpty(productEncodeCfg.getCodeType())){
                productEncodeCfg.setCodeTypeName(LocaleUtils.getLocaleRes(MesExtEnumUtil.ENCODE_CODE_TYPE.valueOfDescription(productEncodeCfg.getCodeType())));
            }
            if(!StringUtils.isEmpty(productEncodeCfg.getMatchType())){
                productEncodeCfg.setMatchTypeName(LocaleUtils.getLocaleRes(MesExtEnumUtil.ENCODE_MATCH_TYPE.valueOfDescription(productEncodeCfg.getMatchType())));
            }
        }
        return productEncodeCfgs;
    }

    @Override
    public MesProductEncodeCfg insertMesProductEncodeCfg(MesProductEncodeCfg productEncodeCfg) {
        MesProductEncodeCfg productEncodeCfgDb = productEncodeCfgRepository.getByProperty(
                new String[]{MesExtConstWords.ORGANIZE_CODE, MesExtConstWords.IS_DELETED, 
                        MesExtConstWords.CODE_TYPE, MesExtConstWords.MATCH_TYPE, MesExtConstWords.MATCH_VALUE},
                new Object[]{productEncodeCfg.getOrganizeCode(), CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), 
                        productEncodeCfg.getCodeType(), productEncodeCfg.getMatchType(), productEncodeCfg.getMatchValue()});
        if (null != productEncodeCfgDb){
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_EXIT.getCode())
                    .setErrorDetail("编码类型为[%s]，匹配类型为[%s]，匹配值为[%s]的记录已存在"
                            , MesExtEnumUtil.ENCODE_CODE_TYPE.valueOfDescription(productEncodeCfg.getCodeType()),
                            MesExtEnumUtil.ENCODE_MATCH_TYPE.valueOfDescription(productEncodeCfg.getMatchType()), productEncodeCfg.getMatchValue())
                    .build();
        }
        ConvertBean.serviceModelInitialize(productEncodeCfg, productEncodeCfg.getCreateUser());
        return productEncodeCfgRepository.insert(productEncodeCfg);
    }

    @Override
    public MesProductEncodeCfg updateMesProductEncodeCfg(MesProductEncodeCfg productEncodeCfg) {
        MesProductEncodeCfg productEncodeCfgDb = productEncodeCfgRepository.getById(productEncodeCfg.getId());
        if (productEncodeCfgDb == null) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                    .setErrorDetail("编码类型为[%s]，匹配类型为[%s]，匹配值为[%s]的记录不存在"
                            , MesExtEnumUtil.ENCODE_CODE_TYPE.valueOfDescription(productEncodeCfg.getCodeType())
                            , MesExtEnumUtil.ENCODE_MATCH_TYPE.valueOfDescription(productEncodeCfg.getMatchType())
                            ,  productEncodeCfg.getMatchValue())
                    .build();
        }
        productEncodeCfgDb.setRuleCode(productEncodeCfg.getRuleCode());
        ConvertBean.serviceModelUpdate(productEncodeCfgDb, productEncodeCfg.getModifyUser());
        return productEncodeCfgRepository.save(productEncodeCfgDb);
    }

    @Override
    public int updateMesProductEncodeCfgStatusById(Long id, int status, String userName) {
        if (status != CommonEnumUtil.IS_VAILD.INVAILD.getValue() && status != CommonEnumUtil.IS_VAILD.VAILD.getValue()) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("启用，禁用枚举状态值[%s]未被定义", status)
                    .build();
        }
        return productEncodeCfgRepository.updateByProperties(new String[]{MesExtConstWords.ID}, new Object[]{id},
                new String[]{MesExtConstWords.IS_VALID, MesExtConstWords.MODIFY_USER, MesExtConstWords.MODIFY_DATE_TIME},
                new Object[]{status, userName, TimeTool.getNowTime(true)});
    }

    @Override
    public String getRuleCodeByMatchType(String organizeCode, Integer codeType, MesPartExt partDb, String workCenterCode) {
        MatchRuleCodeModel model = new MatchRuleCodeModel();
        model.setOrganizeCode(organizeCode);
        model.setCodeType(codeType);
        switch (MesExtEnumUtil.ENCODE_CODE_TYPE.getByValue(codeType)) {
            case SERIAL_SN:
                model.setMatchType(partDb.getProcessMatchType());
                break;
            case STANDARD_SERIAL_SN :
            case REWORK_SERIAL_SN :
            case ATTEMPT_SERIAL_SN :
                model.setMatchType(partDb.getProductMatchType());
                break;
            case PACK_SN :
                model.setMatchType(partDb.getPackageMatchType());
                break;
            default :
                break;
        }
        switch (MesExtEnumUtil.ENCODE_MATCH_TYPE.getByValue(model.getMatchType())) {
            case ORGANIZATION :
                break;
            case PART :
                model.setPartNo(partDb.getPartNo());
                break;
            case WORK_CENTER :
                model.setWorkCenterCode(workCenterCode);
                break;
            case PPT_CODE :
                model.setPptCode(partDb.getPptCode());
                break;
            case CATEGORY_CODE1 :
                model.setCategoryCode1(partDb.getCategoryCode1());
                break;
            case CATEGORY_CODE2 :
                model.setCategoryCode2(partDb.getCategoryCode2());
                break;
            case CATEGORY_CODE3 :
                model.setCategoryCode3(partDb.getCategoryCode3());
                break;
            default :
                break;
        }
        return getRuleCodeByMatchType(model);
    }

    @Override
    public String getRuleCodeByMatchType(MatchRuleCodeModel matchRuleCodeModel) {
        if (null == matchRuleCodeModel) {
            throw ImppExceptionBuilder.newInstance()
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("获取编码规则未封装入参")
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .build();
        }
        if (StringUtils.isEmpty(matchRuleCodeModel.getOrganizeCode())) {
            throw ImppExceptionBuilder.newInstance()
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("获取编码规则入参缺少工厂")
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .build();
        }
        if (StringUtils.isEmpty(matchRuleCodeModel.getMatchType()) || null == MesExtEnumUtil.ENCODE_MATCH_TYPE.getByValue(matchRuleCodeModel.getMatchType())) {
            throw ImppExceptionBuilder.newInstance()
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("获取编码规则入参匹配类型无效")
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .build();
        }
        if (StringUtils.isEmpty(matchRuleCodeModel.getCodeType()) || null == MesExtEnumUtil.ENCODE_CODE_TYPE.getByValue(matchRuleCodeModel.getCodeType())) {
            throw ImppExceptionBuilder.newInstance()
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("获取编码规则入参编码类型无效")
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .build();
        }

        List<MesProductEncodeCfg> encodeCfgList = productEncodeCfgRepository.findByProperty(
                new String[]{MesExtConstWords.ORGANIZE_CODE, MesExtConstWords.IS_DELETED, MesExtConstWords.IS_VALID,
                        MesExtConstWords.CODE_TYPE, MesExtConstWords.MATCH_TYPE},
                new Object[]{matchRuleCodeModel.getOrganizeCode(), CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(),
                        matchRuleCodeModel.getCodeType(), matchRuleCodeModel.getMatchType()});
        if (CollectionUtils.isEmpty(encodeCfgList)) {
            throw ImppExceptionBuilder.newInstance().setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                    .setErrorDetail("根据编码类型[%s]匹配类型[%s]未查询到产品编码配置",
                            MesExtEnumUtil.ENCODE_CODE_TYPE.valueOfDescription(matchRuleCodeModel.getCodeType()),
                            MesExtEnumUtil.ENCODE_MATCH_TYPE.valueOfDescription(matchRuleCodeModel.getMatchType()))
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .build();
        }

        switch (MesExtEnumUtil.ENCODE_MATCH_TYPE.getByValue(matchRuleCodeModel.getMatchType())) {
            case ORGANIZATION :
                return getRuleCode(encodeCfgList, matchRuleCodeModel.getCodeType(), matchRuleCodeModel.getMatchType(),matchRuleCodeModel.getOrganizeCode());
            case PART :
                return getRuleCode(encodeCfgList, matchRuleCodeModel.getCodeType(), matchRuleCodeModel.getMatchType(),matchRuleCodeModel.getPartNo());
            case WORK_CENTER :
                return getRuleCode(encodeCfgList, matchRuleCodeModel.getCodeType(), matchRuleCodeModel.getMatchType(),matchRuleCodeModel.getWorkCenterCode());
            case PPT_CODE :
                return getRuleCode(encodeCfgList, matchRuleCodeModel.getCodeType(), matchRuleCodeModel.getMatchType(),matchRuleCodeModel.getPptCode());
            case CATEGORY_CODE1 :
                return getRuleCode(encodeCfgList, matchRuleCodeModel.getCodeType(), matchRuleCodeModel.getMatchType(),matchRuleCodeModel.getCategoryCode1());
            case CATEGORY_CODE2 :
                return getRuleCode(encodeCfgList, matchRuleCodeModel.getCodeType(), matchRuleCodeModel.getMatchType(),matchRuleCodeModel.getCategoryCode2());
            case CATEGORY_CODE3 :
                return getRuleCode(encodeCfgList, matchRuleCodeModel.getCodeType(), matchRuleCodeModel.getMatchType(),matchRuleCodeModel.getCategoryCode3());
            default :
                throw ImppExceptionBuilder.newInstance().setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                        .setErrorDetail("根据编码类型[%s]匹配类型[%s]未获取到匹配的编码规则代码",
                                MesExtEnumUtil.ENCODE_CODE_TYPE.valueOfDescription(matchRuleCodeModel.getCodeType()),
                                MesExtEnumUtil.ENCODE_MATCH_TYPE.valueOfDescription(matchRuleCodeModel.getMatchType()))
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                        .build();
        }
    }

    @Override
    public MesProductEncodeCfg getMesProductEncodeCfg(MesProductEncodeCfg productEncodeCfg) {
        return productEncodeCfgRepository.getByProperty(
                new String[]{MesExtConstWords.ORGANIZE_CODE, MesExtConstWords.IS_DELETED, MesExtConstWords.IS_VALID,
                        MesExtConstWords.CODE_TYPE, MesExtConstWords.MATCH_TYPE, MesExtConstWords.MATCH_VALUE},
                new Object[]{productEncodeCfg.getOrganizeCode(), CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue(),
                        productEncodeCfg.getCodeType(), productEncodeCfg.getMatchType(), productEncodeCfg.getMatchValue()});
    }

    private String getRuleCode(List<MesProductEncodeCfg> encodeCfgList, Integer codeType, Integer matchType, String matchValue) {
        if (StringUtils.isEmpty(matchValue)) {
            throw ImppExceptionBuilder.newInstance().setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("获取编码规则入参缺少编码类型[%s]匹配类型[%s]的匹配值",
                            MesExtEnumUtil.ENCODE_CODE_TYPE.valueOfDescription(codeType),
                            MesExtEnumUtil.ENCODE_MATCH_TYPE.valueOfDescription(matchType))
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .build();
        }
        for (MesProductEncodeCfg encodeCfg : encodeCfgList) {
            if (null == encodeCfg || StringUtils.isEmpty(encodeCfg.getMatchValue()) || StringUtils.isEmpty(encodeCfg.getRuleCode())) {
                continue;
            }
            if (matchValue.equals(encodeCfg.getMatchValue())) {
                return encodeCfg.getRuleCode();
            }
        }
        throw ImppExceptionBuilder.newInstance().setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                .setErrorDetail("根据编码类型[%s]匹配类型[%s]未获取到匹配的编码规则代码",
                        MesExtEnumUtil.ENCODE_CODE_TYPE.valueOfDescription(codeType),
                        MesExtEnumUtil.ENCODE_MATCH_TYPE.valueOfDescription(matchType))
                .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                .build();
    }


}
