package com.kexue.skills.common.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.UUID;

/**
 * @description: ID管理类
 **/
@Component
public class IDUtils {
    public static final Logger logger = LoggerFactory.getLogger(IDUtils.class);

    @Value("${snowflake.workid:1}")
    private long workId;

    private static SnowflakeIdGenerator snowflakeIdGenerator;

    public static String getUUID(){
        return UUID.randomUUID().toString().replace("-","");
    }

    @PostConstruct
    public void init() {
        snowflakeIdGenerator = new SnowflakeIdGenerator(workId);
        logger.info("Snowflake ID generator initialized with workId: {}", workId);
    }

    public static long getSnowflakeId() {
        if (snowflakeIdGenerator == null) {
            // 如果未初始化，使用默认workId
            snowflakeIdGenerator = new SnowflakeIdGenerator(1L);
        }
        return snowflakeIdGenerator.nextId();
    }

    public static String getSnowflakeIdStr() {
        if (snowflakeIdGenerator == null) {
            // 如果未初始化，使用默认workId
            snowflakeIdGenerator = new SnowflakeIdGenerator(1L);
        }
        return String.valueOf(snowflakeIdGenerator.nextId());
    }

    /**
     * 雪花算法实现
     */
    static class SnowflakeIdGenerator {
        // 起始时间戳 (2020-01-01 00:00:00)
        private static final long START_TIMESTAMP = 1577808000000L;
        // 机器ID位数
        private static final long MACHINE_ID_BITS = 10L;
        // 序列号位数
        private static final long SEQUENCE_BITS = 12L;
        // 机器ID最大值
        private static final long MAX_MACHINE_ID = (1L << MACHINE_ID_BITS) - 1;
        // 序列号最大值
        private static final long MAX_SEQUENCE = (1L << SEQUENCE_BITS) - 1;
        // 机器ID左移位数
        private static final long MACHINE_ID_SHIFT = SEQUENCE_BITS;
        // 时间戳左移位数
        private static final long TIMESTAMP_SHIFT = SEQUENCE_BITS + MACHINE_ID_BITS;

        private long machineId;
        private long sequence = 0L;
        private long lastTimestamp = -1L;

        public SnowflakeIdGenerator(long machineId) {
            if (machineId > MAX_MACHINE_ID || machineId < 0) {
                throw new IllegalArgumentException("Machine ID must be between 0 and " + MAX_MACHINE_ID);
            }
            this.machineId = machineId;
        }

        public synchronized long nextId() {
            long timestamp = System.currentTimeMillis();

            if (timestamp < lastTimestamp) {
                throw new RuntimeException("Clock moved backwards. Refusing to generate id");
            }

            if (timestamp == lastTimestamp) {
                sequence = (sequence + 1) & MAX_SEQUENCE;
                if (sequence == 0) {
                    timestamp = tilNextMillis(lastTimestamp);
                }
            } else {
                sequence = 0L;
            }

            lastTimestamp = timestamp;

            return ((timestamp - START_TIMESTAMP) << TIMESTAMP_SHIFT) |
                    (machineId << MACHINE_ID_SHIFT) |
                    sequence;
        }

        private long tilNextMillis(long lastTimestamp) {
            long timestamp = System.currentTimeMillis();
            while (timestamp <= lastTimestamp) {
                timestamp = System.currentTimeMillis();
            }
            return timestamp;
        }
    }

    public static void main(String[] args) {
        System.out.println(getUUID());
        logger.debug("test");
        
        // 测试雪花算法
        for (int i = 0; i < 10; i++) {
            System.out.println("Snowflake ID: " + getSnowflakeId());
        }
    }
}
