package com.hw.common.core.utils.uuid;

import java.util.concurrent.atomic.AtomicInteger;

import com.hw.common.core.utils.DateUtils;
import com.hw.common.core.utils.StringUtils;

/**
 * @author ruoyi 序列生成类
 */
public class Seq {
    // 通用序列类型
    public static final String commSeqType = "COMMON";

    // 上传序列类型
    public static final String uploadSeqType = "UPLOAD";

    // 通用接口序列数
    private static AtomicInteger commSeq = new AtomicInteger(1);

    // 上传接口序列数
    private static AtomicInteger uploadSeq = new AtomicInteger(1);

    // 机器标识
    private static final String machineCode = "A";


    // 成品出库记录序列类型
    public static final String productOutstockSeqType = "PRODUCTOUTSTOCK";

    // 成品出库记录接口序列数
    private static AtomicInteger productOutstockSeq = new AtomicInteger(1);

    // 成品出库记录标识
    public static final String productInstockCode = "PI";

    // 成品入库记录序列类型
    public static final String productInstockSeqType = "PRODUCTINSTOCK";

    // 成品入库记录接口序列数
    private static AtomicInteger productInstockSeq = new AtomicInteger(1);

    // 成品入库记录标识
    public static final String productOutstockCode = "PO";


    // 原材料出库记录序列类型
    public static final String rawOutstockSeqType = "RAWOUTSTOCK";

    // 原材料出库记录接口序列数
    private static AtomicInteger rawOutstockSeq = new AtomicInteger(1);

    // 原材料出库记录标识
    public static final String rawOutstockSeqCode = "RO";


    // 原材料退库记录序列类型
    public static final String rawReturnSeqType = "RAWRETURN";

    // 原材料退库记录接口序列数
    private static AtomicInteger rawReturnSeq = new AtomicInteger(1);

    // 原材料退库记录标识
    public static final String rawReturnCode = "RR";

    // 工单编号序列类型
    public static final String orderCodeSeqType = "ORDER_CODE";

    // 工单编号序列数
    private static AtomicInteger orderCodeSeq = new AtomicInteger(1);

    // 工单编号记录标识
    public static final String orderCodeCode = "OC";

    // 派工编号序列类型
    public static final String dispatchCodeSeqType = "DISPATCH_CODE";

    // 派工编号序列数
    private static AtomicInteger dispatchCodeSeq = new AtomicInteger(1);

    // 派工编号记录标识
    public static final String dispatchCodeCode = "PG";

    // 派工计划编号序列类型
    public static final String planCodeSeqType = "PLAN_CODE";

    // 派工计划编号序列数
    private static AtomicInteger planCodeSeq = new AtomicInteger(1);

    // 派工计划编号记录标识
    public static final String planCodeCode = "JL";

    // 生产计划明细编号记录标识
    public static final String mesProductPlanDetailSeqType = "PRODUCTPLANDETAIL";

    // 生产计划明细接口序列数
    private static AtomicInteger mesProductPlanDetailSeq = new AtomicInteger(1);

    // 生产计划明细标识
    public static final String mesProductPlanDetailCode = "PD";

    // 生产批次代码记录标识
    public static final String mesBatchCodeSeqType = "BATCH_CODE";

    // 生产批次代码序列数
    private static AtomicInteger mesBatchCodeSeq = new AtomicInteger(1);

    // 生产批次代码标识
    public static final String mesBatchCodeCode = "PC";

    // 条码内容记录标识
    public static final String mesBarcodeSeqType = "BAR_CODE";

    // 条码内容序列数
    private static AtomicInteger mesBarcodeSeq = new AtomicInteger(1);

    // 条码内容标识
    public static final String mesBarcodeCode = "TM";

    // 成品条码内容记录标识
    public static final String mesCompBarcodeSeqType = "COMP_BAR_CODE";

    // 成品条码内容序列数
    private static AtomicInteger mesCompBarcodeSeq = new AtomicInteger(1);

    // 成品条码内容标识
    public static final String mesCompBarcodeCode = "CP";


    // 设备报修工单编号记录标识
    public static final String dmsBillsFaultInstanceSeqType = "DMSBILLSFAULTINSTANCE";

    // 设备报修工单接口序列数
    private static AtomicInteger dmsBillsFaultInstanceSeq = new AtomicInteger(1);

    // 设备报修工单标识
    public static final String dmsBillsFaultInstanceSeqCode = "BF";



    // 物料转库记录序列类型
    public static final String wmsTransferSeqType = "WMSTRANSFER";

    // 物料转库记录接口序列数
    private static AtomicInteger wmsTransferSeq = new AtomicInteger(1);

    // 物料转库记录标识
    public static final String wmsTransferSeqCode = "TF";




    //检修计划序列类型
    public static final  String planRepairSeqType = "PLANREPAIR";
    //检修计划接口序列数
    private static AtomicInteger planRepairSeq = new AtomicInteger(1);
    //检修记录标识
    public static final String planRepairCode = "PR";
    //检修工单序列类型
    public static final String repairInstanceSeqTupe = "REPAIRINSTANCE";
    //检修工单接口序列数
    private static AtomicInteger repairInstanceSeq = new AtomicInteger(1);
    //检修工单标识
    public static final String repairInstanceCode = "RI";

    //检修计划序列类型
    public static final  String planInspectSeqType = "PLANINSPECT";
    //检修计划接口序列数
    private static AtomicInteger planInspectSeq = new AtomicInteger(1);
    //检修记录标识
    public static final String planInspectCode = "PIC";
    //检修工单序列类型
    public static final String InspectInstanceSeqTupe = "INSPECTINSTANCE";
    //检修工单接口序列数
    private static AtomicInteger INSPECTInstanceSeq = new AtomicInteger(1);
    //检修工单标识
    public static final String InspectInstanceCode = "IIC";


    // 保养计划序列类型
    public static final String planMaintSeqType = "PLANMAINT";

    // 保养计划接口序列数
    private static AtomicInteger planMaintSeq = new AtomicInteger(1);

    // 保养记录标识
    public static final String planMaintCode = "PM";


    // 保养工单序列类型
    public static final String maintInstanceSeqType = "MAINTINSTANCE";

    // 保养工单接口序列数
    private static AtomicInteger maintInstanceSeq = new AtomicInteger(1);

    // 保养工单标识
    public static final String maintInstanceCode = "MI";




    // 润滑计划序列类型
    public static final String planLubeSeqType = "PLANLUBE";

    // 润滑计划接口序列数
    private static AtomicInteger planLubeSeq = new AtomicInteger(1);

    // 润滑记录标识
    public static final String planLubeCode = "PL";


    // 润滑工单序列类型
    public static final String lubeInstanceSeqType = "LUBEINSTANCE";

    // 润滑工单接口序列数
    private static AtomicInteger lubeInstanceSeq = new AtomicInteger(1);

    // 润滑工单标识
    public static final String lubeInstanceCode = "LI";



    // 物料移库记录序列类型
    public static final String wmsMoveSeqType = "WMSMOVE";

    // 物料移库记录接口序列数
    private static AtomicInteger wmsMoveSeq = new AtomicInteger(1);

    // 物料移库记录标识
    public static final String wmsMoveSeqCode = "MO";


    // 物料合库记录序列类型
    public static final String wmsMergeSeqType = "WMSMERGE";

    // 物料合库记录接口序列数
    private static AtomicInteger wmsMergeSeq = new AtomicInteger(1);

    // 物料合库记录标识
    public static final String wmsMergeSeqCode = "ME";



    // 原材料入库记录序列类型
    public static final String rawInstockSeqType = "RAWINSTOCK";

    // 原材料入库记录接口序列数
    private static AtomicInteger rawInstockSeq = new AtomicInteger(1);

    // 原材料入库记录标识
    public static final String rawInstockSeqCode = "RI";


    // 仓储盘点记录序列类型
    public static final String wmsInventoryCheckSeqType = "inventorycheck";

    // 仓储盘点记录接口序列数
    private static AtomicInteger wmsInventoryCheckSeq = new AtomicInteger(1);

    // 仓储盘点记录标识
    public static final String wmsInventoryCheckSeqCode = "IC";

    /**
     * 获取通用序列号
     *
     * @return 序列值
     */
    public static String getId() {
        return getId(commSeqType);
    }

    /**
     * 默认16位序列号 yyMMddHHmmss + 一位机器标识 + 3长度循环递增字符串
     *
     * @return 序列值
     */
    public static String getId(String type) {
        AtomicInteger atomicInt = commSeq;
        if (uploadSeqType.equals(type)) {
            atomicInt = uploadSeq;
        }
        return getId(atomicInt, 3);
    }

    /**
     * 通用接口序列号 yyMMddHHmmss + 一位机器标识 + length长度循环递增字符串
     *
     * @param atomicInt 序列数
     * @param length    数值长度
     * @return 序列值
     */
    public static String getId(AtomicInteger atomicInt, int length) {
        String result = DateUtils.dateTimeNow();
        result += machineCode;
        result += getSeq(atomicInt, length);
        return result;
    }

    /**
     * 序列循环递增字符串[1, 10 的 (length)幂次方), 用0左补齐length位数
     *
     * @return 序列值
     */
    private synchronized static String getSeq(AtomicInteger atomicInt, int length) {
        // 先取值再+1
        int value = atomicInt.getAndIncrement();

        // 如果更新后值>=10 的 (length)幂次方则重置为1
        int maxSeq = (int) Math.pow(10, length);
        if (atomicInt.get() >= maxSeq) {
            atomicInt.set(1);
        }
        // 转字符串，用0左补齐
        return StringUtils.padl(value, length);
    }


    /**
     * 默认16位序列号 yyMMddHHmmss + 一位机器标识 + 3长度循环递增字符串
     *
     * @return 序列值
     */
    public static String getId(String type,String code) {
        AtomicInteger atomicInt = commSeq;
        if (productOutstockSeqType.equals(type)) {
            atomicInt = productOutstockSeq;
        }else if (rawReturnSeqType.equals(type)) {
            atomicInt = rawReturnSeq;
        }else if (orderCodeSeqType.equals(type)) {
            atomicInt = orderCodeSeq;
        } else if (mesProductPlanDetailSeqType.equals(type)) {
            atomicInt = mesProductPlanDetailSeq;
        }else if (dispatchCodeSeqType.equals(type)) {
            atomicInt = dispatchCodeSeq;
        }else if (planCodeSeqType.equals(type)) {
            atomicInt = planCodeSeq;
        }else if (mesBatchCodeSeqType.equals(type)) {
            atomicInt = mesBatchCodeSeq;
        }else if (mesBarcodeSeqType.equals(type)) {
            atomicInt = mesBarcodeSeq;
        }else if (dmsBillsFaultInstanceSeqType.equals(type)) {
            atomicInt = dmsBillsFaultInstanceSeq;
        }else if (rawOutstockSeqType.equals(type)) {
            atomicInt = rawOutstockSeq;
        }else if (wmsTransferSeqType.equals(type)) {
            atomicInt = wmsTransferSeq;
        }else if (planMaintSeqType.equals(type)) {
            atomicInt = planMaintSeq;
        }else if(maintInstanceSeqType.equals(type)) {
            atomicInt = maintInstanceSeq;
        }else if (planLubeSeqType.equals(type)) {
            atomicInt = planLubeSeq;
        }else if(lubeInstanceSeqType.equals(type)) {
            atomicInt = lubeInstanceSeq;
        }else if(mesCompBarcodeSeqType.equals(type)) {
            atomicInt = mesCompBarcodeSeq;
        }else if(productInstockSeqType.equals(type)) {
            atomicInt = productInstockSeq;
        }else if(wmsMoveSeqType.equals(type)) {
            atomicInt = wmsMoveSeq;
        }else if(wmsMergeSeqType.equals(type)) {
            atomicInt = wmsMergeSeq;
        }else if(rawInstockSeqType.equals(type)) {
            atomicInt = rawInstockSeq;
        }else if(wmsInventoryCheckSeqType.equals(type)) {
            atomicInt = wmsInventoryCheckSeq;
        }
        return getId(atomicInt, 3, code);
    }


    /**
     * 通用接口序列号 yyMMddHHmmss + 一位机器标识 + length长度循环递增字符串
     *
     * @param atomicInt 序列数
     * @param length    数值长度
     * @return 序列值
     */
    public static String getId(AtomicInteger atomicInt, int length, String code) {
        String result = DateUtils.dateTimeNow();
        result += code;
        result += getSeq(atomicInt, length);
        return result;
    }

}
