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

import cn.estsh.i3plus.ext.mes.pcn.api.base.IMesCustomerPartService;
import cn.estsh.i3plus.ext.mes.pcn.api.base.IMesPartService;
import cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.print.IPrintTemplateStrategyService;
import cn.estsh.i3plus.ext.mes.pcn.apiservice.util.BarCodeUtils;
import cn.estsh.i3plus.ext.mes.pcn.apiservice.util.MesPcnException;
import cn.estsh.i3plus.ext.mes.pcn.pojo.model.MesProduceSnPrintDataModel;
import cn.estsh.i3plus.ext.mes.pcn.pojo.model.MesProduceSnPrintModel;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords;
import cn.estsh.i3plus.mes.pcn.api.iservice.busi.ISyncFuncService;
import cn.estsh.i3plus.platform.common.convert.ConvertBean;
import cn.estsh.i3plus.platform.common.tool.TimeTool;
import cn.estsh.i3plus.pojo.base.bean.DdlPackBean;
import cn.estsh.i3plus.pojo.base.codemaker.SnowflakeIdMaker;
import cn.estsh.i3plus.pojo.base.tool.DdlPreparedPack;
import cn.estsh.i3plus.pojo.mes.bean.*;
import cn.estsh.i3plus.pojo.mes.model.GenSerialNoModel;
import cn.estsh.i3plus.pojo.mes.model.StationRequestBean;
import cn.estsh.i3plus.pojo.mes.model.StepResult;
import cn.estsh.i3plus.pojo.mes.repository.MesNumberRuleRepository;
import cn.estsh.i3plus.pojo.mes.util.MesExtEnumUtil;
import com.alibaba.fastjson.JSONObject;
import com.google.zxing.WriterException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.*;

/**
 * @Description : 客户标签打印
 * @Reference :
 * @Author : xinwang.yi
 * @CreateDate : 2024/9/29 16:43
 * @Modify:
 **/
@Component
@Slf4j
public class WuhanSnPrintStrategy implements IPrintTemplateStrategyService {

    @Autowired
    private IMesPartService mesPartService;

    @Autowired
    private MesNumberRuleRepository numberRuleRepository;

    @Autowired
    private SnowflakeIdMaker snowflakeIdMaker;

    @Autowired
    private ISyncFuncService syncFuncService;

    @Autowired
    private IMesCustomerPartService mesCustomerPartService;

    @Override
    public MesProduceSnPrintModel execute(GenSerialNoModel genSerialNoModel, MesProduceSnPrintModel model,
                                          MesNumberRule numberRule, StepResult stepResult, StationRequestBean reqBean,
                                          Boolean isStep) {
        //物料信息
        MesPart mesPart = mesPartService.getMesPartByPartNo(model.getPartNo(), model.getOrganizeCode());
        MesCustomerPart customerPart = (!Objects.isNull(genSerialNoModel) && !CollectionUtils.isEmpty(genSerialNoModel.getDataMap()) && genSerialNoModel.getDataMap().containsKey(MesCustomerPart.class.getSimpleName())) ? (MesCustomerPart) genSerialNoModel.getDataMap().get(MesCustomerPart.class.getSimpleName()) : mesCustomerPartService.getMesCustomerPart(model.getOrganizeCode(),model.getPartNo());
        if(Objects.isNull(customerPart)){
            MesPcnException.throwMesBusiException("零件号：%s客户物料信息不存在",model.getPartNo());
        }
        // 客户零件号
        String custPartNo = mesCustomerPartService.getCustPartNo(model.getOrganizeCode(),model.getPartNo());
        // 客户零件号 前缀 排除后四位
        String custPartNoPrefix = StringUtils.isEmpty(custPartNo) ? "" : custPartNo.substring(0, custPartNo.length() - 4);
        // 客户零件号 后四位
        String custPartNoAfterFour = StringUtils.isEmpty(custPartNo) ? "" : custPartNo.substring(custPartNo.length() - 4).toUpperCase();
        numberRule = Objects.isNull(numberRule) ? getMesNumberRule(mesPart) : numberRule;

        // 返回的结果集合
        List<Map<String, Object>> printDataMapList = new ArrayList<>();
        if (!isStep) {
            genSerialNoModel.putDataMap(MesCustomerPart.class.getSimpleName(),customerPart).partSnParam(mesPart.getPartSnParam());
            for (int i = 0; i < model.getPrintQty(); i++) {
                //保存条码信息
                MesProduceSn produceSn = generateMesProduceSn(mesPart, syncFuncService.syncSerialNo(genSerialNoModel, model.getUserName(), model.getOrganizeCode(), 1).getResultList().get(0).toString(), model.getUserName(), model.getQty());
                Map<String, Object> printMap = getPrintMap(produceSn.getCustSn(), custPartNoPrefix, custPartNoAfterFour, numberRule);
                //封装打印信息
                MesProduceSnPrintDataModel printDataModel = getModel(mesPart, produceSn.getCustSn(), model.getUserName(), JSONObject.toJSONString(printMap));
                model.getMesProduceSnPrintDataModelList().add(printDataModel);
                model.getMesProduceSnList().add(produceSn);
                //保存打印记录
                model.getMesPrintedSnLogList().add(getMesPrintedSnLog(printDataModel, model.getUserName(), model.getOrganizeCode()));
            }
        } else {
            Map<String, Object> printMap = getPrintMap(model.getProductSn(), custPartNoPrefix, custPartNoAfterFour, numberRule);
            printDataMapList.add(printMap);
            List<Map<String, Object>> resultMapList = new ArrayList<>();
            resultMapList.add(packResultMap(model, printDataMapList));
            model.setPrintContextList(resultMapList);
            model.getMesPrintedSnLogList().add(getMesPrintedSnLog(mesPart, model.getProductSn(), reqBean.getUserInfo(), JSONObject.toJSONString(printMap)));
        }

        return model;
    }

    private MesNumberRule getMesNumberRule(MesPart mesPart) {
        String custMatchRule = StringUtils.isEmpty(mesPart.getCustMatchRule()) ? "WH_NO_SORT_CUST_SN_RULE" : mesPart.getCustMatchRule();
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(mesPart.getOrganizeCode());
        DdlPreparedPack.getStringEqualPack(custMatchRule, MesPcnExtConstWords.RULE_CODE, packBean);
        return numberRuleRepository.getByProperty(packBean);
    }

    private Map<String, Object> packResultMap(MesProduceSnPrintModel printModel, List<Map<String, Object>> printTemplateDateList) {
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put(MesPcnExtConstWords.LABEL_TEMPLATE, printModel.getMesLabelTemplate());
        resultMap.put(MesPcnExtConstWords.TEMPLATE_DATA, printTemplateDateList);
        resultMap.put(MesPcnExtConstWords.TEMPLATE_CODE, printModel.getMesLabelTemplate().getTemplateCode());
        resultMap.put(MesPcnExtConstWords.PRINTER, printModel.getPrinter());
        return resultMap;
    }

    private MesPrintedSnLog getMesPrintedSnLog(MesPart mesPart, String productSn, String userName, String printData) {
        MesPrintedSnLog snLog = new MesPrintedSnLog();
        snLog.setBarcode(productSn);
        snLog.setPartNo(mesPart.getPartNo());
        snLog.setPartName(mesPart.getPartName());
        snLog.setPrintData(printData);
        ConvertBean.serviceModelInitialize(snLog, userName);
        snLog.setOrganizeCode(mesPart.getOrganizeCode());
        return snLog;
    }

    private MesProduceSn generateMesProduceSn(MesPart mesPart, String sn, String userName, Double qty) {
        MesProduceSn mesProduceSn = new MesProduceSn();
        mesProduceSn.setSerialNumber(snowflakeIdMaker.nextId() + "");
        mesProduceSn.setProductSn(sn);
        mesProduceSn.setCustSn(sn);
        mesProduceSn.setPartNo(mesPart.getPartNo());
        mesProduceSn.setPartName(mesPart.getPartName());
        mesProduceSn.setProcessLabelTemplate(mesPart.getProcessLabelTemplate());
        mesProduceSn.setCustLabelTemplate(mesPart.getCustLabelTemplate());
        mesProduceSn.setProdLabelTemplate(mesPart.getProductLabelTemplate());
        mesProduceSn.setQty(qty);
        mesProduceSn.setSnStatus(MesExtEnumUtil.PRODUCE_SN_STATUS.CREATE.getValue());
        mesProduceSn.setQcStatus(MesExtEnumUtil.PRODUCE_QC_STATUS.QUALIFIED.getValue());
        mesProduceSn.setLotNo(TimeTool.getToday());
        mesProduceSn.setPrintCount(MesPcnExtConstWords.ONE);
        mesProduceSn.setPrintStatus(MesExtEnumUtil.PRINT_STATUS.PRINTED.getValue());
        mesProduceSn.setOrganizeCode(mesPart.getOrganizeCode());
        ConvertBean.serviceModelInitialize(mesProduceSn, userName);
        return mesProduceSn;
    }

    private MesProduceSnPrintDataModel getModel(MesPart mesPart, String productSn, String userName, String printData) {
        MesProduceSnPrintDataModel mesProduceSnPrintDataModel = new MesProduceSnPrintDataModel();
        mesProduceSnPrintDataModel.setPartNo(mesPart.getPartNo());
        mesProduceSnPrintDataModel.setPartName(mesPart.getPartName());
        mesProduceSnPrintDataModel.setBarcode(productSn);
        mesProduceSnPrintDataModel.setPrintDate(TimeTool.getNowTime(true));
        mesProduceSnPrintDataModel.setPrintData(printData);
        mesProduceSnPrintDataModel.setUserName(userName);
        return mesProduceSnPrintDataModel;
    }

    private MesPrintedSnLog getMesPrintedSnLog(MesProduceSnPrintDataModel printDataModel, String userName, String organizeCode) {
        MesPrintedSnLog snLog = new MesPrintedSnLog();
        BeanUtils.copyProperties(printDataModel, snLog);
        ConvertBean.serviceModelInitialize(snLog, userName);
        snLog.setOrganizeCode(organizeCode);
        return snLog;
    }

    private Map<String, Object> getPrintMap(String productSn, String custPartNoPrefix, String custPartNoAfterFour, MesNumberRule numberRule) {
        // 单个标签参数值
        Map<String, Object> resultMap = new HashMap<>();
        // 客户条码
        resultMap.put(MesPcnExtConstWords.CUST_SN, productSn);
        // 客户零件号 前缀 排除后四位
        resultMap.put(MesPcnExtConstWords.CUST_PART_NO_PREFIX, custPartNoPrefix);
        // 客户零件号 后四位
        resultMap.put(MesPcnExtConstWords.CUST_PART_NO_AFTER_FOUR, custPartNoAfterFour);

        String[] split = productSn.split("");
        StringBuilder rsStr = new StringBuilder();
        for (int i = 0; i < split.length - 1; i++) {
            rsStr.append(split[i]).append("%RS%");
        }
        rsStr.append(split[split.length - 1]);
        StringBuilder gsStr = new StringBuilder();
        String[] split1 = rsStr.toString().split("");
        for (int i = 0; i < split1.length - 1; i++) {
            gsStr.append(split1[i]).append("%GS%");
        }
        gsStr.append(split1[split1.length - 1]);
        String[] split2 = gsStr.toString().split("");

        String sn = split2[0] + "%EOT%";

        if (numberRule == null) {
            log.error("CustSnPrintStrategy --- exec --- numberRule 为空");
            return resultMap;
        }

        if (StringUtils.isEmpty(numberRule.getRuleLengthSpiltExt())) {
            log.error("CustSnPrintStrategy --- exec --- 规则属性长度拼接 为空");
            return resultMap;
        }

        // 规则属性长度拼接
        String[] ruleLengthSpiltExt = numberRule.getRuleLengthSpiltExt().split(MesPcnExtConstWords.COMMA);

        /*
         *           1            2           3        4         5         6           7        8    9     10          11        12
         * 编码规则：{spiltRule}{spiltRule}{spiltRule}{partNo}{spiltRule}{spiltRule}{spiltRule}{year}{day}{spiltRule}{serialNo}{spiltRule}
         * 规则属性长度拼接：14,14,5,8,7,9,7,2,3,5,4,9
         * 拼接固定字符：[)>%RS%06%GS%Y,4110000000000X,%GS%P,%GS%12V,545238347,%GS%T1A,A2B4C,%RS%%EOT%
         * 条码：[)>06Y4110000000000XP26560848Z12V545238347T1A24269A2B4C0005
         * 转换后条码：[)>%RS%06%GS%Y4110000000000X%GS%P26560850%GS%12V545238347%GS%T1A24269A2B4C0019%RS
         * 客户条码 VPPS 取 第 2
         * 客户条码 DUNS 取 第 5
         * 客户条码后半部分取 7 的后两位 1A到 11
         * */

        int vppsLengthStart = 0;
        int vppsLengthEnd = 0;
        int dunsLengthStart = 0;
        int dunsLengthEnd = 0;
        int afterContentPerfixLengthStart = 0;
        int afterContentPerfixLengthEnd = 0;
        int afterContentLengthStart = 0;
        int afterContentLengthEnd = 0;
        for (int index = 0; index < ruleLengthSpiltExt.length; index++) {
            if (index < 1) vppsLengthStart += Integer.parseInt(ruleLengthSpiltExt[index]);
            if (index < 2) vppsLengthEnd += Integer.parseInt(ruleLengthSpiltExt[index]);
            if (index < 5) dunsLengthStart += Integer.parseInt(ruleLengthSpiltExt[index]);
            if (index < 6) dunsLengthEnd += Integer.parseInt(ruleLengthSpiltExt[index]);
            if (index < 6) afterContentPerfixLengthStart += Integer.parseInt(ruleLengthSpiltExt[index]);
            if (index < 7) afterContentPerfixLengthEnd += Integer.parseInt(ruleLengthSpiltExt[index]);
            if (index < 7) afterContentLengthStart += Integer.parseInt(ruleLengthSpiltExt[index]);
            if (index < 11) afterContentLengthEnd += Integer.parseInt(ruleLengthSpiltExt[index]);
        }

        String custSnVPPS = sn.substring(vppsLengthStart, vppsLengthEnd);
        String custSnDUNS = sn.substring(dunsLengthStart, dunsLengthEnd);
        String custSnAfterPerfixContent = sn.substring(afterContentPerfixLengthStart, afterContentPerfixLengthEnd);
        custSnAfterPerfixContent = custSnAfterPerfixContent.substring(custSnAfterPerfixContent.length() - 2, custSnAfterPerfixContent.length());
        String custSnAfterContent = custSnAfterPerfixContent + sn.substring(afterContentLengthStart, afterContentLengthEnd);

        // 客户条码 VPPS
        resultMap.put(MesPcnExtConstWords.CUST_SN_VPPS, custSnVPPS);
        // 客户条码 DUNS
        resultMap.put(MesPcnExtConstWords.CUST_SN_DUNS, custSnDUNS);
        // 客户条码 CUST_AFTER_CONTENT
        resultMap.put(MesPcnExtConstWords.CUST_SN_AFTER_CONTENT, custSnAfterContent);
        // 客户条码 dataMatrix
        ByteArrayOutputStream dataMatrixCode;
        try {
            dataMatrixCode = BarCodeUtils.createDataMatrixCode(productSn);
        } catch (WriterException e) {
            log.error("CustSnPrintStrategy --- execute --- 报错:{}", e.getMessage());
            return resultMap;
        } catch (IOException e) {
            log.error("CustSnPrintStrategy --- execute --- 报错:{}", e.getMessage());
            return resultMap;
        }
        resultMap.put(MesPcnExtConstWords.CUST_SN_DATA_MATRIX, Base64.getEncoder().encodeToString(dataMatrixCode.toByteArray()));
        return resultMap;
    }

}
