package com.greenorange.promotion.utils;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class OrderNumberUtils {


    // 定义日期格式化器，精确到秒
    private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyyMMddHHmmss");

    // 定义序列号最大值
    private static final int MAX_SEQUENCE = 999999;

    // 当前日期，初始化为当天
    private static String currentDate = getCurrentDate();

    // 自增序列号，线程安全
    private static final AtomicInteger sequence = new AtomicInteger(0);

    // 锁对象，用于保护自增序列号的生成
    private static final Lock lock = new ReentrantLock();


    public static String generateOrderId() {
        // 获取当前日期
        String today = getCurrentDate();

        // 如果日期发生变化，重置序列号
        if (!today.equals(currentDate)) {
            currentDate = today;
            sequence.set(0);  // 重置序列号
        }

        // 获取时间戳（精确到秒）
        String timestamp = DATE_FORMAT.format(new Date());

        // 获取4位随机数
        String randomNumber = generateRandomNumber();

        // 获取6位自增序列号，并确保不超过最大值
        int seq = getNextSequence();

        // 格式化序列号为6位
        String formattedSequence = String.format("%06d", seq);

        // 拼接生成订单号
        return timestamp + randomNumber + formattedSequence;
    }

    // 获取当前日期（格式：yyyyMMdd）
    private static String getCurrentDate() {
        return new SimpleDateFormat("yyyyMMdd").format(new Date());
    }

    // 生成4位随机数（范围：0000到9999）
    private static String generateRandomNumber() {
        int random = (int) (Math.random() * 10000); // 生成0到9999之间的随机数
        return String.format("%04d", random); // 格式化为4位
    }

    // 获取下一个自增序列号，使用ReentrantLock来确保线程安全
    private static int getNextSequence() {
        lock.lock();  // 获取锁
        try {
            int seq = sequence.incrementAndGet();
            if (seq > MAX_SEQUENCE) {
                sequence.set(0);  // 达到最大值后重置
                seq = sequence.incrementAndGet();
            }
            return seq;
        } finally {
            lock.unlock();  // 确保在最终释放锁
        }
    }



}
