/// Minimal RFC 4648 base32 encode/decode for TOTP secret parsing.
///
/// Mirrors the encoder in crates/relicario-core/src/item.rs:base32_encode.
/// Decode is case-insensitive, tolerates whitespace and `=` padding.

const ALPHA = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';

export function base32Encode(bytes: Uint8Array): string {
  let out = '';
  let buffer = 0;
  let bits = 0;
  for (const b of bytes) {
    buffer = (buffer << 8) | b;
    bits += 8;
    while (bits >= 5) {
      const idx = (buffer >> (bits - 5)) & 0x1f;
      out += ALPHA[idx];
      bits -= 5;
    }
  }
  if (bits > 0) {
    const idx = (buffer << (5 - bits)) & 0x1f;
    out += ALPHA[idx];
  }
  return out;
}

export function base32Decode(input: string): Uint8Array {
  const cleaned = input.replace(/\s+/g, '').replace(/=+$/g, '').toUpperCase();
  const out: number[] = [];
  let buffer = 0;
  let bits = 0;
  for (const ch of cleaned) {
    const idx = ALPHA.indexOf(ch);
    if (idx === -1) throw new Error(`base32: invalid character "${ch}"`);
    buffer = (buffer << 5) | idx;
    bits += 5;
    if (bits >= 8) {
      out.push((buffer >> (bits - 8)) & 0xff);
      bits -= 8;
    }
  }
  return new Uint8Array(out);
}
