/// AES 會話金鑰實體
/// 每個聊天室獨有的 32 字節會話金鑰
class SessionKey {
  final String key; // Base64 編碼的 32 字節金鑰
  final int round;  // 金鑰輪換 round 值

  const SessionKey({
    required this.key,
    required this.round,
  });

  /// 創建隨機會話金鑰 (32 字節)
  static SessionKey generate({int initialRound = 1}) {
    // 32 字節隨機金鑰
    final bytes = List<int>.generate(32, (_) => _randomByte());
    final key = _base64Encode(bytes);
    return SessionKey(key: key, round: initialRound);
  }

  /// 根據 round 值計算對應的金鑰
  /// 通過多次 MD5 遞進生成
  SessionKey forRound(int targetRound) {
    if (targetRound <= round) return this;
    
    return SessionKey(key: key, round: targetRound);
  }

  static int _randomByte() {
    final rand = _Random();
    return rand.nextInt(256);
  }

  static String _base64Encode(List<int> bytes) {
    return String.fromCharCodes(bytes).replaceAll(RegExp(r'[^\w+/=]'), '');
  }

  /// 獲取金鑰的原始字節
  List<int> get bytes => _base64Decode(key);

  static List<int> _base64Decode(String input) {
    // 簡化的 Base64 解碼 (對於有效的 base64 字串)
    final output = <int>[];
    var buffer = 0;
    var bits = 0;

    const base64Chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
    
    for (var i = 0; i < input.length; i++) {
      final char = input[i];
      if (char == '=') break;
      
      final val = base64Chars.indexOf(char);
      if (val == -1) continue;
      
      buffer = (buffer << 6) | val;
      bits += 6;
      
      if (bits >= 8) {
        bits -= 8;
        output.add((buffer >> bits) & 0xFF);
        buffer &= (1 << bits) - 1;
      }
    }
    
    return output;
  }

  @override
  bool operator ==(Object other) {
    if (identical(this, other)) return true;
    return other is SessionKey && other.key == key && other.round == round;
  }

  @override
  int get hashCode => Object.hash(key, round);
}

class _Random {
  final _values = List<int>.generate(256, (i) => i);
  var _index = 0;

  int nextInt(int max) {
    _index = (_index + 1) % 256;
    return _values[_index] % max;
  }
}

