package com.sonic.bear.utils;

import com.sonic.bear.enums.ToastResultCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.security.MessageDigest;
import java.time.LocalDate;
import java.time.Year;
import java.util.Random;

@Slf4j
@Service
public class IdCardGenerator {

    private static final int MAX_STEP = 999;
    private static final int MAX_RANDOM = 9999;

    private final Random random = new Random();

    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private RedisKeyUtils redisKeyUtils;

    public String generateIdCard() {
        try {
            // 获取当前年份和一年中的天数
            LocalDate today = LocalDate.now();
            int yearLastDigit = Year.now().getValue() % 10;
            int dayOfYear = today.getDayOfYear();

            // 生成随机数 (0001-9999)
            int randomNum = random.nextInt(MAX_RANDOM) + 1;

            // 使用 Redis 计数器生成唯一值，并通过哈希生成最后三位
            Long counter = stringRedisTemplate.opsForValue().increment(redisKeyUtils.idCardCounterKey());
            if (counter == null) {
                stringRedisTemplate.opsForValue().set(redisKeyUtils.idCardCounterKey(), "0");
                counter = stringRedisTemplate.opsForValue().increment(redisKeyUtils.idCardCounterKey());
            }
            if (counter > MAX_STEP) {
                stringRedisTemplate.opsForValue().set(redisKeyUtils.idCardCounterKey(), "0");
                counter = 1L;
            }

            // 使用计数器和时间戳生成哈希值，确保步长非连续
            String hashInput = counter + String.valueOf(System.currentTimeMillis());
            int step = (Math.abs(hashString(hashInput)) % MAX_STEP) + 1; // 001-999

            // 格式化 ID：年(1位) + 日期(3位) + 随机数(4位) + 步长(3位)
            return String.format("%1d%03d%04d%03d", yearLastDigit, dayOfYear, randomNum, step);
        } catch (Exception e) {
            log.error("===> generateIdCard error : ", e);
            ToastResultCode.BIZ_ERROR1.check(true);
        }
        return null;
    }

    private int hashString(String input) throws Exception {
        MessageDigest digest = MessageDigest.getInstance("SHA-256");
        byte[] hash = digest.digest(input.getBytes());
        // 使用前4字节生成整数
        return ((hash[0] & 0xFF) << 24) | ((hash[1] & 0xFF) << 16) |
               ((hash[2] & 0xFF) << 8) | (hash[3] & 0xFF);
    }
}