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

import cn.estsh.i3plus.ext.mes.pcn.api.base.bu.IMesBusiConfigService;
import cn.estsh.i3plus.ext.mes.pcn.api.base.bu.IMesProductPrintTypeService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.ISxPrintTemplateMethodService;
import cn.estsh.i3plus.ext.mes.pcn.pojo.bean.MesBusiConfig;
import cn.estsh.i3plus.ext.mes.pcn.pojo.bean.MesProductPrintType;
import cn.estsh.i3plus.ext.mes.pcn.pojo.bean.MesWorkCellPrintQueue;
import cn.estsh.i3plus.ext.mes.pcn.pojo.model.BigOuterPackageModel;
import cn.estsh.i3plus.ext.mes.pcn.pojo.model.PackageExtModel;
import cn.estsh.i3plus.ext.mes.pcn.pojo.model.ProduceSnExtModel;
import cn.estsh.i3plus.ext.mes.pcn.pojo.model.SxPrintTemplateModel;
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.api.iservice.base.IMethodService;
import cn.estsh.i3plus.platform.common.exception.ImppExceptionEnum;
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
import cn.estsh.i3plus.pojo.mes.bean.MesLabelTemplate;
import cn.estsh.i3plus.pojo.mes.bean.MesLabelTemplateParam;
import cn.estsh.i3plus.pojo.mes.bean.MesMethod;
import cn.estsh.i3plus.pojo.mes.repository.MesLabelTemplateParamRepository;
import cn.estsh.i3plus.pojo.mes.repository.MesLabelTemplateRepository;
import cn.estsh.impp.framework.boot.exception.ImppExceptionBuilder;
import cn.estsh.impp.framework.boot.util.SpringContextsUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

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

/**
 * @Description 打印模板策略实现子方法
 * @Author: wangjie
 * @CreateDate: 2020/6/22 9:38 AM
 * @Description:
 **/
@Slf4j
@Service
public class SxPrintTemplateDispatchService {

    @Autowired
    private MesLabelTemplateRepository labelTemplateRepository;

    @Autowired
    private MesLabelTemplateParamRepository labelTemplateParamRepository;

    @Autowired
    private IMethodService methodService;

    @Autowired
    private IMesProductPrintTypeService productPrintTypeService;

    @Autowired
    private IMesBusiConfigService busiConfigService;

    public List<Map<String, Object>> exec(SxPrintTemplateModel printModel) {
        ISxPrintTemplateMethodService methodService = getMethodService(printModel);
        List<Map<String, Object>> printTemplateDateList = methodService.exec(printModel);
        return packResultMapList(printModel, printTemplateDateList);
    }

    private ISxPrintTemplateMethodService getMethodService(SxPrintTemplateModel printModel) {
        MesMethod method = methodService.getMesMethodByCode(printModel.getLabelTemplate().getMethodCode(), printModel.getOrganizeCode());
        ISxPrintTemplateMethodService methodService = (null == method || StringUtils.isEmpty(method.getCallClass())) ? null :
                (ISxPrintTemplateMethodService) SpringContextsUtil.getBean(method.getCallClass());
        if (null == methodService) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                    .setErrorDetail("打印模板策略[%s]校验模板代码[%s]配置的方法代码[%s]无效",
                            new Exception().getStackTrace()[1].getClassName(), printModel.getLabelTemplate().getTemplateCode(), printModel.getLabelTemplate().getMethodCode())
                    .build();
        }
        return methodService;
    }

    private List<Map<String, Object>> packResultMapList(SxPrintTemplateModel printModel, List<Map<String, Object>> printTemplateDateList) {
        if (CollectionUtils.isEmpty(printTemplateDateList)) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("打印模板策略[%s]中未获取到打印数据", new Exception().getStackTrace()[1].getClassName())
                    .build();
        }

        List<Map<String, Object>> resultMapList = new ArrayList<>();
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put(MesPcnExtConstWords.LABEL_TEMPLATE, printModel.getLabelTemplate());
        resultMap.put(MesPcnExtConstWords.TEMPLATE_DATA, printTemplateDateList);
        resultMap.put(MesPcnExtConstWords.PRINT_MODE, printModel.getPrintMode());
        resultMap.put(MesPcnExtConstWords.TEMPLATE_CODE, printModel.getLabelTemplate().getTemplateCode());
        //BarTender打印地址配置
        MesBusiConfig mesBusiConfig = busiConfigService.queryBusiConfigeByCfgCode(MesPcnExtConstWords.COMMON_TEMPLATE_URL, printModel.getLabelTemplate().getOrganizeCode());
        if(mesBusiConfig == null){
            log.info("BarTender模板地址未维护 - cfgCode - COMMON_TEMPLATE_URL");
        }else{
            resultMap.put(MesPcnExtConstWords.TEMPLATE_URL, mesBusiConfig.getCfgValue() + printModel.getLabelTemplate().getTemplateCode() +".BTW");
        }

        resultMap.put(MesPcnExtConstWords.PRINTER_CODE, printModel.getPrinterCode());
        resultMapList.add(resultMap);
        return resultMapList;
    }

    public void checkLabelTemplate(SxPrintTemplateModel printModel, String sn, String templateCode, String memo) {
        if (null == printModel.getLabelTemplate()) {
            if (StringUtils.isEmpty(templateCode)) {
                log.info("SxPrintTemplateDispatchService的templatecode没有");
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                        .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                        .setErrorDetail("打印模板策略[%s]校验缺少[%s]打印模板信息",
                                new Exception().getStackTrace()[1].getClassName(), memo)
                        .build();
            }
            MesLabelTemplate labelTemplate = labelTemplateRepository.getByProperty(
                    new String[]{MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.IS_VALID, MesPcnExtConstWords.TEMPLATE_CODE},
                    new Object[]{CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), templateCode});
            if (labelTemplate == null) {
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                        .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                        .setErrorDetail("打印模板策略[%s]通过条码[%s]关联的[%s]模板代码[%s]未找到有效的模板信息",
                                new Exception().getStackTrace()[1].getClassName(), sn, memo, templateCode)
                        .build();
            }
            if (StringUtils.isEmpty(printModel.getLabelTemplate().getMethodCode())) {
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                        .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                        .setErrorDetail("打印模板策略[%s]校验[%s]模板代码[%s]未配置方法代码",
                                new Exception().getStackTrace()[1].getClassName(), memo, templateCode)
                        .build();
            }
            List<MesLabelTemplateParam> templateParamList = labelTemplateParamRepository.findByProperty(
                    new String[]{MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.IS_VALID, MesPcnExtConstWords.TEMPLATE_CODE},
                    new Object[]{CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), templateCode});
            labelTemplate.setLabelTemplateParamList(templateParamList);

            printModel.setLabelTemplate(labelTemplate);
        }
    }

    public void checkValidAndPackPackageList(SxPrintTemplateModel printModel) {
        checkOrganizeCode(printModel.getOrganizeCode());

        if (CollectionUtils.isEmpty(printModel.getPackList())) {
            if (null == printModel.getPack() && CollectionUtils.isEmpty(printModel.getPackList())) {
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                        .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                        .setErrorDetail("打印模板策略[%s]校验缺少打印必要入参", new Exception().getStackTrace()[1].getClassName())
                        .build();
            }
            if (CollectionUtils.isEmpty(printModel.getPackList())) {
                List<PackageExtModel> packList = new ArrayList<>();
                packList.add(printModel.getPack());
                printModel.setPackList(packList);
            }
        }
    }

    public void checkValidAndBigPackageList(SxPrintTemplateModel printModel) {
        checkOrganizeCode(printModel.getOrganizeCode());

        if (CollectionUtils.isEmpty(printModel.getBigOuterPackageList())) {
            if (null == printModel.getBigOuterPackageModel() && CollectionUtils.isEmpty(printModel.getBigOuterPackageList())) {
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                        .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                        .setErrorDetail("打印模板策略[%s]校验缺少打印必要入参", new Exception().getStackTrace()[1].getClassName())
                        .build();
            }
            if (CollectionUtils.isEmpty(printModel.getBigOuterPackageList())) {
                List<BigOuterPackageModel> packList = new ArrayList<>();
                packList.add(printModel.getBigOuterPackageModel());
                printModel.setBigOuterPackageList(packList);
            }
        }
    }

    public void checkValidAndPackSnList(SxPrintTemplateModel printModel) {
        checkOrganizeCode(printModel.getOrganizeCode());

        if (CollectionUtils.isEmpty(printModel.getSnList())) {
            if (null == printModel.getSn() && CollectionUtils.isEmpty(printModel.getSnList())) {
                log.info("SxPrintTemplateDispatchService的打印模板策略校验缺少打印必要入参");
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                        .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                        .setErrorDetail("打印模板策略[%s]校验缺少打印必要入参", new Exception().getStackTrace()[1].getClassName())
                        .build();
            }
            if (CollectionUtils.isEmpty(printModel.getSnList())) {
                List<ProduceSnExtModel> snList = new ArrayList<>();
                snList.add(printModel.getSn());
                printModel.setSnList(snList);
            }
        }
    }

    private void checkOrganizeCode(String organizeCode) {
        if (StringUtils.isEmpty(organizeCode)) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("打印模板策略[%s]校验入参缺少工厂代码", new Exception().getStackTrace()[1].getClassName())
                    .build();
        }
    }

    public MesLabelTemplate getLabelTemplate(String templateCode) {
        if (StringUtils.isEmpty(templateCode)) {
            return null;
        }
        MesLabelTemplate labelTemplate = labelTemplateRepository.getByProperty(
                new String[]{MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.IS_VALID, MesPcnExtConstWords.TEMPLATE_CODE},
                new Object[]{CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), templateCode});
        if (null != labelTemplate) {
            List<MesLabelTemplateParam> templateParamList = labelTemplateParamRepository.findByProperty(
                    new String[]{MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.IS_VALID, MesPcnExtConstWords.TEMPLATE_CODE},
                    new Object[]{CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), templateCode});
            labelTemplate.setLabelTemplateParamList(templateParamList);
        }
        return labelTemplate;
    }

    public void packTemplateModel(SxPrintTemplateModel printTemplateModel, String partNo, Integer printType, String organizeCode){
        if(!StringUtils.isEmpty(partNo)){
            MesProductPrintType mesProductPrintType = productPrintTypeService.queryProdPrintTypeByPartNoAndPrintType(partNo, printType, organizeCode);
            if(mesProductPrintType == null) {
                printTemplateModel.setPrintMode(MesPcnExtEnumUtil.PRINT_MODE.LODOP.getValue());
            }else {
                printTemplateModel.setPrintMode(mesProductPrintType.getPrintMode());
            }
        }else{
            printTemplateModel.setPrintMode(MesPcnExtEnumUtil.PRINT_MODE.LODOP.getValue());
        }
    }

    public void packMesWorkCellPrintQueue(MesWorkCellPrintQueue workCellPrintQueue, String partNo, Integer printType, String organizeCode){
        if(!StringUtils.isEmpty(partNo)){
            MesProductPrintType mesProductPrintType = productPrintTypeService.queryProdPrintTypeByPartNoAndPrintType(partNo, printType, organizeCode);
            if(mesProductPrintType == null) {
                workCellPrintQueue.setPrintMode(MesPcnExtEnumUtil.PRINT_MODE.LODOP.getValue());
            }else {
                workCellPrintQueue.setPrintMode(mesProductPrintType.getPrintMode());
            }
        }else{
            workCellPrintQueue.setPrintMode(MesPcnExtEnumUtil.PRINT_MODE.LODOP.getValue());
        }
    }
}
