package com.eactive.ext.kjb.ums;

import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.util.UUID;

public class UUIDBase62Util {
    private static final String BASE62 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";

    public static String uuidStringToBase62(String uuidStr) {
        UUID uuid = UUID.fromString(uuidStr);
        ByteBuffer bb = ByteBuffer.wrap(new byte[16]);
        bb.putLong(uuid.getMostSignificantBits());
        bb.putLong(uuid.getLeastSignificantBits());
        BigInteger bigInt = new BigInteger(1, bb.array());
        return toBase62(bigInt);
    }

    public static String base62ToUuidString(String base62Str) {
        BigInteger bigInt = fromBase62(base62Str);
        byte[] bytes = toByteArray(bigInt, 16);
        ByteBuffer bb = ByteBuffer.wrap(bytes);
        long msb = bb.getLong();
        long lsb = bb.getLong();
        return new UUID(msb, lsb).toString();
    }

    private static String toBase62(BigInteger value) {
        StringBuilder sb = new StringBuilder();
        while (value.compareTo(BigInteger.ZERO) > 0) {
            BigInteger[] divRem = value.divideAndRemainder(BigInteger.valueOf(62));
            sb.append(BASE62.charAt(divRem[1].intValue()));
            value = divRem[0];
        }
        // pad to 22 chars for consistent length
        while (sb.length() < 22) sb.append('0');
        return sb.reverse().toString();
    }

    private static BigInteger fromBase62(String base62) {
        BigInteger result = BigInteger.ZERO;
        for (char c : base62.toCharArray()) {
            int digit = BASE62.indexOf(c);
            if (digit == -1) throw new IllegalArgumentException("Invalid Base62 character: " + c);
            result = result.multiply(BigInteger.valueOf(62)).add(BigInteger.valueOf(digit));
        }
        return result;
    }

    private static byte[] toByteArray(BigInteger bigInt, int size) {
        byte[] src = bigInt.toByteArray();
        byte[] dst = new byte[size];
        int srcPos = Math.max(0, src.length - size);
        int dstPos = Math.max(0, size - src.length);
        int length = Math.min(size, src.length);
        System.arraycopy(src, srcPos, dst, dstPos, length);
        return dst;
    }

    public static void main(String[] args) {
        String uuid = UUID.randomUUID().toString();
        String base62 = uuidStringToBase62(uuid);
        String decoded = base62ToUuidString(base62);

        System.out.println("UUID  : " + uuid);
        System.out.println("Base62: " + base62 + " (" + base62.length() + ")");
        System.out.println("Decoded: " + decoded);
        System.out.println("Same? " + uuid.equals(decoded));
    }
}
