package com.aucma.common.utils.uuid;

import com.aucma.common.utils.DateUtils;
import com.aucma.common.utils.StringUtils;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * @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";

    /**
     * 获取通用序列号
     * 
     * @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);
    }





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

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

    // 成品出库记录标识
    public static final String productOutstockCode = "PO";
    // 成品入库记录序列类型

    public static final String productInstockSeqType = "PRODUCTINSTOCK";

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

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



    // 原材料出库记录序列类型
    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 = "RP";

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

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

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


    // 四楼到五楼内部生产条码内容记录标识
    public static final String mesInternalBarcodeSeqType = "INTERNAL_BAR_CODE";

    // 四楼到五楼内部生产条码内容序列数
    private static AtomicInteger mesInternalBarcodeSeq = new AtomicInteger(1);

    // 四楼到五楼内部生产条码内容标识
    public static final String mesInternalBarcodeCode = "RN";



    // 成品条码内容记录标识
    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 mesBindBarcodeSeqType = "BIND_BAR_CODE";

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

    // 配对条码内容标识
    public static final String mesBindBarcodeCode = "BD";


    // 设备报修工单编号记录标识
    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";


    // 停用物料信息的物料编码
    public static final String stopUsingSeqType = "";

    // 停用物料信息的接口序列数
    private static AtomicInteger stopUsingSeq = new AtomicInteger(1);

    // 停用物料信息的记录标识
    public static final String stopUsingCode = "DEL";


    // 虚拟销售订单编码
    public static final String mesVirtualSaleOrderSeqType = "virtualsaleorder";

    // 虚拟销售订单信息的接口序列数
    private static AtomicInteger mesVirtualSaleOrderSeq = new AtomicInteger(1);

    // 虚拟销售订单信息的记录标识
    public static final String mesVirtualSaleOrderCode = "VS";


    // 虚拟采购订单编码
    public static final String mesVirtualPurchaseOrderSeqType = "virtualpurchaseorder";

    // 虚拟采购订单信息的接口序列数
    private static AtomicInteger mesVirtualPurchasaeOrderSeq = new AtomicInteger(1);

    // 虚拟采购订单信息的记录标识
    public static final String mesVirtualPurchaseOrderCode = "VP";

    // 采购申请提资单任务编号
    public static final String mesPurchaseApplyProcessSeqType = "purchaseApplyProcess";

    // 采购申请提资单任务编号序列数
    private static AtomicInteger mesPurchaseApplyProcessSeq = new AtomicInteger(1);

    // 采购申请提资单任务编号的记录标识
    public static final String mesPurchaseApplyProcessCode = "CG";



    // 采购合并虚拟原材料条码内容记录标识
    public static final String mesPurchaseVirtualBarcodeSeqType = "VIRTUAL_BAR_CODE";

    // 采购合并虚拟原材料条码内容序列数
    private static AtomicInteger mesPurchaseVirtualBarcodeSeq = new AtomicInteger(1);

    // 采购合并虚拟原材料条码内容标识
    public static final String mesPurchaseVirtualBarcodeCode = "VR";


    // 内部生产合并虚拟原材料条码内容记录标识
    public static final String mesInternalVirtualBarcodeSeqType = "INTERNAL_VIRTUAL_BAR_CODE";

    // 内部生产合并虚拟原材料条码内容序列数
    private static AtomicInteger mesInternalVirtualBarcodeSeq = new AtomicInteger(1);

    // 内部生产合并虚拟原材料条码内容标识
    public static final String mesInternalVirtualBarcodeCode = "VI";



    // 采购合并虚拟成品条码内容记录标识
    public static final String mesPurchaseVirtualProductBarcodeSeqType = "VIRTUAL_PRODUCT_BAR_CODE";

    // 采购合并虚拟成品条码内容序列数
    private static AtomicInteger mesPurchaseVirtualProductBarcodeSeq = new AtomicInteger(1);

    // 采购合并虚拟成品条码内容标识
    public static final String mesPurchaseVirtualProductBarcodeCode = "VC";



    // 内部生产合并虚拟成品条码内容记录标识
    public static final String mesInternalVirtualProductBarcodeSeqType = "INTERNAL_VIRTUAL_PRODUCT_BAR_CODE";

    // 内部生产虚拟成品条码内容序列数
    private static AtomicInteger mesInternalVirtualProductBarcodeSeq = new AtomicInteger(1);

    // 内部生产虚拟成品条码内容标识
    public static final String mesInternalVirtualProductBarcodeCode = "VT";



    // 采购申请单任务编号
    public static final String mesPurchaseApplySeqType = "purchaseApply";

    // 采购申请单任务编号序列数
    private static AtomicInteger mesPurchaseApplySeq = new AtomicInteger(1);

    // 采购申请单任务编号的记录标识
    public static final String mesPurchaseApplyCode = "PA";





    // 销售订单记录序列类型
    public static final String mesSaleOrderSeqType = "MESSALEORDER";

    // 销售订单记录接口序列数
    private static AtomicInteger mesSaleOrderSeq = new AtomicInteger(1);

    // 销售订单记录标识
    public static final String mesSaleOrderSeqCode = "XSDD";

    /**
     * 获取通用序列号
     *
     * @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;
        }else if (mesBindBarcodeSeqType.equals(type)) {
            atomicInt = mesBindBarcodeSeq;
        }else if (stopUsingSeqType.equals(type)) {
            atomicInt = stopUsingSeq;
        }else if (mesVirtualSaleOrderSeqType.equals(type)) {
            atomicInt = mesVirtualSaleOrderSeq;
        }else if (mesVirtualPurchaseOrderSeqType.equals(type)) {
            atomicInt = mesVirtualPurchasaeOrderSeq;
        }else if (mesPurchaseApplyProcessSeqType.equals(type)) {
            atomicInt = mesPurchaseApplyProcessSeq;
        }else if (mesPurchaseVirtualBarcodeSeqType.equals(type)) {
            atomicInt = mesPurchaseVirtualBarcodeSeq;
        }else if (mesPurchaseVirtualProductBarcodeSeqType.equals(type)) {
            atomicInt = mesPurchaseVirtualProductBarcodeSeq;
        }else if (mesInternalVirtualBarcodeSeqType.equals(type)) {
            atomicInt = mesInternalVirtualBarcodeSeq;
        }else if (mesInternalVirtualProductBarcodeSeqType.equals(type)) {
            atomicInt = mesInternalVirtualProductBarcodeSeq;
        }else if (mesInternalBarcodeSeqType.equals(type)) {
            atomicInt = mesInternalBarcodeSeq;
        }else if (mesPurchaseApplySeqType.equals(type)) {
            atomicInt = mesPurchaseApplySeq;
        }
        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;
    }

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

    /**
     * 通用接口序列号 前缀+yyMMdd + length长度循环递增字符串
     *
     * @param atomicInt 序列数
     * @param length    数值长度
     * @return 序列值
     */
    public static String getNewId(AtomicInteger atomicInt, int length, String code) {
        String result = code;
        result += DateUtils.dateTime();
        result += getSeq(atomicInt, length);
        return result;
    }

}
