using System.Text;

namespace NB.Map;

public static class RoomHelper
{
    #region 房间id

    private const string Base36Chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    private const int RoomSeqBits = 16; // 每个服务最多 65535 个房间

    /// <summary>
    /// 生成房间码（固定5位）
    /// </summary>
    /// <param name="serviceId"></param>
    /// <param name="roomSeq"></param>
    /// <returns></returns>
    public static string GenerateCode(uint serviceId, int roomSeq)
    {
        long packed = ((long)serviceId << RoomSeqBits) | (uint)roomSeq;
        string code = EncodeBase36(packed);

        // 固定5位，不够左侧补0
        return code.PadLeft(5, '0');
    }

    /// <summary>
    /// 解析房间码
    /// </summary>
    /// <param name="code"></param>
    /// <param name="serviceId"></param>
    /// <param name="roomSeq"></param>
    public static void ParseCode(string code, out uint serviceId, out int roomSeq)
    {
        long packed = DecodeBase36(code);
        roomSeq = (int)(packed & ((1 << RoomSeqBits) - 1));
        serviceId = (uint)(packed >> RoomSeqBits);
    }

    private static string EncodeBase36(long value)
    {
        if (value == 0) return "0";
        StringBuilder sb = new StringBuilder();
        while (value > 0)
        {
            int remainder = (int)(value % 36);
            sb.Insert(0, Base36Chars[remainder]);
            value /= 36;
        }

        return sb.ToString();
    }

    private static long DecodeBase36(string str)
    {
        long result = 0;
        foreach (char c in str)
        {
            int val = Base36Chars.IndexOf(c);
            if (val < 0) throw new ArgumentException("Invalid Base36 character: " + c);
            result = result * 36 + val;
        }

        return result;
    }

    #endregion
    
}