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

import cn.estsh.i3plus.ext.mes.pcn.api.base.INumberRuleExtService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.ISxNumberRulePackAttributeService;
import cn.estsh.i3plus.ext.mes.pcn.pojo.bean.MesNumberRuleExt;
import cn.estsh.i3plus.ext.mes.pcn.pojo.bean.MesPartExt;
import cn.estsh.i3plus.ext.mes.pcn.pojo.bean.MesWorkOrderExt;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords;
import cn.estsh.i3plus.platform.common.exception.ImppExceptionEnum;
import cn.estsh.i3plus.platform.common.tool.TimeTool;
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
import cn.estsh.i3plus.pojo.mes.model.GenSerialNoModel;
import cn.estsh.impp.framework.boot.exception.ImppExceptionBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.StringJoiner;

/**
 * @Author: wangjie
 * @CreateDate: 2019/8/23 1:16 PM
 * @Description: 编码规则封装入参属性
 **/

@Service
public class SxNumberRulePackAttributeService implements ISxNumberRulePackAttributeService {

    @Autowired
    private INumberRuleExtService numberRuleExtService;

    @Autowired
    private SxJapanGenSerialNoStrategyService sxJapanGenSerialNoStrategyService;

    @Override
    public GenSerialNoModel doPackGenSerialNoModel(Map<String, Object> map) {
        String ruleCode = (String) map.get(MesPcnExtConstWords.RULE_CODE);
        GenSerialNoModel serialNoModel = new GenSerialNoModel();
        serialNoModel.setRuleCode(ruleCode);
        if (null == map) {
            return serialNoModel;
        }

        String organizeCode = (String) map.get(MesPcnExtConstWords.ORGANIZE_CODE);
        MesNumberRuleExt numberRuleDb = numberRuleExtService.getNumberRuleExtByRuleCode(organizeCode, ruleCode);
        if (null == numberRuleDb || StringUtils.isEmpty(numberRuleDb.getMethodName())) {
            return serialNoModel;
        }
        try {
            return packGenSerialNoModelByMethod(map, serialNoModel, numberRuleDb.getMethodName());
        } catch (Exception e) {
            InvocationTargetException targetEx = (InvocationTargetException) e;
            Throwable trowEx = targetEx.getTargetException();
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail(trowEx.getMessage())
                    .build();
        }
    }

    private GenSerialNoModel packGenSerialNoModelByMethod(Map<String, Object> map, GenSerialNoModel serialNoModel, String methodName) throws Exception {
        Method method = this.getClass().getDeclaredMethod(methodName, Map.class, GenSerialNoModel.class);
        method.setAccessible(true);
        return (GenSerialNoModel) method.invoke(this, map, serialNoModel);
    }

    /**
     * 动态字符包含 物料识别码,条码末尾数
     * 年月日默认使用工单计划开始时间
     * 编码规则可增加 年 月 日 时 分 秒 前缀 流水号 动态字符 配置
     */
    private GenSerialNoModel method1(Map<String, Object> map, GenSerialNoModel serialNoModel){
        MesPartExt partExt = (MesPartExt) map.get(MesPcnExtConstWords.PART_EXT);
        if (null != partExt) {
            serialNoModel.setDynamicRule(new StringJoiner(MesPcnExtConstWords.COMMA).add(partExt.getIdentifyCode()).add(partExt.getSnLastCode()).toString());
        }

        String currentDate = (String) map.get(MesPcnExtConstWords.START_TIME);
        if (!StringUtils.isEmpty(currentDate)) {
            serialNoModel.setYear(currentDate.substring(0, 4));
            serialNoModel.setMonth(currentDate.substring(5, 7));
            serialNoModel.setDay(currentDate.substring(8, 10));
        }
        return serialNoModel;
    }

    /**
     * 动态字符包含 颜色代码
     * 年月日默认使用工单计划开始时间
     * 年:取年份最后一位数
     * 月份:10月使用大写字母O,11月使用大写字母N,12月使用大写字母D
     * 编码规则可增加 日 时 分 秒 前缀 流水号 动态字符 配置
     */
    private GenSerialNoModel method2(Map<String, Object> map, GenSerialNoModel serialNoModel){
        MesPartExt partExt = (MesPartExt) map.get(MesPcnExtConstWords.PART_EXT);
        if (null != partExt) {
            serialNoModel.setDynamicRule(partExt.getColorCode());
        }
        String currentDate = (String) map.get(MesPcnExtConstWords.START_TIME);
        if (!StringUtils.isEmpty(currentDate)) {
            serialNoModel.setYear(currentDate.substring(3, 4));
            serialNoModel.setMonth(sxJapanGenSerialNoStrategyService.getMouth(currentDate.substring(5, 7), true));
            serialNoModel.setDay(currentDate.substring(8, 10));
        } else {
            currentDate = TimeTool.getDateTimeShort();
            serialNoModel.setYear(currentDate.substring(3, 4));
            serialNoModel.setMonth(sxJapanGenSerialNoStrategyService.getMouth(currentDate.substring(4, 6), true));
            serialNoModel.setDay(currentDate.substring(6));
        }

        return serialNoModel;
    }

    /**
     * 动态字符包含 物料识别码
     * 年月日默认使用工单计划开始时间
     * 年:取年份最后两位数
     * 编码规则可增加 月 日 时 分 秒 前缀 流水号 动态字符 配置
     */
    private GenSerialNoModel method3(Map<String, Object> map, GenSerialNoModel serialNoModel){
        MesPartExt partExt = (MesPartExt) map.get(MesPcnExtConstWords.PART_EXT);
        if (null != partExt) {
            serialNoModel.setDynamicRule(partExt.getIdentifyCode());
        }

        String currentDate = (String) map.get(MesPcnExtConstWords.START_TIME);
        if (!StringUtils.isEmpty(currentDate)) {
            serialNoModel.setYear(currentDate.substring(2, 4));
            serialNoModel.setMonth(currentDate.substring(5, 7));
            serialNoModel.setDay(currentDate.substring(8, 10));
        } else {
            currentDate = TimeTool.getYear();
            serialNoModel.setYear(currentDate.substring(2));
        }

        return serialNoModel;
    }

    /**
     * 动态字符包含 物料识别码
     * 年月日默认使用工单计划开始时间
     * 编码规则可增加 年 月 日 时 分 秒 前缀 流水号 动态字符 配置
     */
    private GenSerialNoModel method4(Map<String, Object> map, GenSerialNoModel serialNoModel){
        MesPartExt partExt = (MesPartExt) map.get(MesPcnExtConstWords.PART_EXT);
        if (null != partExt) {
            serialNoModel.setDynamicRule(partExt.getIdentifyCode());
        }
        String currentDate = (String) map.get(MesPcnExtConstWords.START_TIME);
        if (!StringUtils.isEmpty(currentDate)) {
            serialNoModel.setYear(currentDate.substring(0, 4));
            serialNoModel.setMonth(currentDate.substring(5, 7));
            serialNoModel.setDay(currentDate.substring(8, 10));
        }
        return serialNoModel;
    }

    /**
     * 动态字符包含 颜色代码
     * 年月日默认使用工单计划开始时间
     * 年:取年份最后两位数
     * 月份:10月使用大写字母O,11月使用大写字母N,12月使用大写字母D
     * 编码规则可增加 日 时 分 秒 前缀 流水号 动态字符 配置
     */
    private GenSerialNoModel method5(Map<String, Object> map, GenSerialNoModel serialNoModel){
        MesPartExt partExt = (MesPartExt) map.get(MesPcnExtConstWords.PART_EXT);
        if (null != partExt) {
            serialNoModel.setDynamicRule(partExt.getColorCode());
        }
        String currentDate = (String) map.get(MesPcnExtConstWords.START_TIME);
        if (!StringUtils.isEmpty(currentDate)) {
            serialNoModel.setYear(currentDate.substring(2, 4));
            serialNoModel.setMonth(sxJapanGenSerialNoStrategyService.getMouth(currentDate.substring(5, 7), true));
            serialNoModel.setDay(currentDate.substring(8, 10));
        } else {
            currentDate = TimeTool.getDateTimeShort();
            serialNoModel.setYear(currentDate.substring(2, 4));
            serialNoModel.setMonth(sxJapanGenSerialNoStrategyService.getMouth(currentDate.substring(4, 6), true));
            serialNoModel.setDay(currentDate.substring(6));
        }

        return serialNoModel;
    }

    /**
     * 动态字符包含 物料识别码
     * 年月日默认使用工单计划开始时间
     * 年:取年份最后两位数
     * 月份:10月使用大写字母O,11月使用大写字母N,12月使用大写字母D
     * 编码规则可增加 日 时 分 秒 前缀 流水号 动态字符 配置
     */
    private GenSerialNoModel method6(Map<String, Object> map, GenSerialNoModel serialNoModel){
        MesPartExt partExt = (MesPartExt) map.get(MesPcnExtConstWords.PART_EXT);
        if (null != partExt) {
            serialNoModel.setDynamicRule(partExt.getIdentifyCode());
        }
        String currentDate = (String) map.get(MesPcnExtConstWords.START_TIME);
        if (!StringUtils.isEmpty(currentDate)) {
            serialNoModel.setYear(currentDate.substring(2, 4));
            serialNoModel.setMonth(sxJapanGenSerialNoStrategyService.getMouth(currentDate.substring(5, 7), true));
            serialNoModel.setDay(currentDate.substring(8, 10));
        } else {
            currentDate = TimeTool.getDateTimeShort();
            serialNoModel.setYear(currentDate.substring(2, 4));
            serialNoModel.setMonth(sxJapanGenSerialNoStrategyService.getMouth(currentDate.substring(4, 6), true));
            serialNoModel.setDay(currentDate.substring(6));
        }

        return serialNoModel;
    }

    /**
     * 动态字符包含 工单号
     * 年月日默认使用工单计划开始时间
     * 编码规则可增加 日 时 分 秒 前缀 流水号 动态字符【取工单号】 配置
     */
    private GenSerialNoModel method7(Map<String, Object> map, GenSerialNoModel serialNoModel){
        MesWorkOrderExt workOrderExt = (MesWorkOrderExt) map.get(MesPcnExtConstWords.WORK_ORDER);
        if (null != workOrderExt) {
            serialNoModel.setDynamicRule(workOrderExt.getOrderNo());
        }
        String currentDate = (String) map.get(MesPcnExtConstWords.START_TIME);
        if (!StringUtils.isEmpty(currentDate)) {
            serialNoModel.setYear(currentDate.substring(0, 4));
            serialNoModel.setMonth(currentDate.substring(5, 7));
            serialNoModel.setDay(currentDate.substring(8, 10));
        } else {
            currentDate = TimeTool.getDateTimeShort();
            serialNoModel.setYear(currentDate.substring(0, 4));
            serialNoModel.setMonth(currentDate.substring(4, 6));
            serialNoModel.setDay(currentDate.substring(6));
        }

        return serialNoModel;
    }

    /**
     * 动态字符包含 生产线 工单号
     * 编码规则可增加 年 月 日 时 分 秒 前缀 流水号 配置
     */
    private GenSerialNoModel jxMethodDynamicCenterAndOrder(Map<String, Object> map, GenSerialNoModel serialNoModel){
        String workOrderNo = (String) map.get(MesPcnExtConstWords.WORK_ORDER_NO);
        String workCenterCode = (String) map.get(MesPcnExtConstWords.WORK_CENTER_CODE);
        serialNoModel.setDynamicRule(new StringJoiner(MesPcnExtConstWords.COMMA).add(workCenterCode).add(workOrderNo).toString());
        return serialNoModel;
    }

    /**
     * 动态字符包含 工单号
     * 编码规则可增加 年 月 日 时 分 秒 前缀 流水号 配置
     */
    private GenSerialNoModel jxMethodDynamicOrder(Map<String, Object> map, GenSerialNoModel serialNoModel){
        String workOrderNo = (String) map.get(MesPcnExtConstWords.WORK_ORDER_NO);
        serialNoModel.setDynamicRule(workOrderNo);
        return serialNoModel;
    }

}
