// Postgres bytea <-> Uint8Array.
//
// PostgREST serializes bytea as a "\x<hex>" string in JSON. When inserting via
// the Supabase client, sending the same literal back round-trips cleanly.

export function bytesToPgHex(bytes: Uint8Array): string {
  let out = '\\x';
  for (let i = 0; i < bytes.length; i++) {
    out += bytes[i]!.toString(16).padStart(2, '0');
  }
  return out;
}

export function pgHexToBytes(hex: string): Uint8Array {
  if (!hex.startsWith('\\x')) {
    throw new Error(`not a postgres hex literal: ${hex.slice(0, 8)}…`);
  }
  const stripped = hex.slice(2);
  if (stripped.length % 2 !== 0) throw new Error('odd hex length');
  const out = new Uint8Array(stripped.length / 2);
  for (let i = 0; i < stripped.length; i += 2) {
    out[i / 2] = Number.parseInt(stripped.slice(i, i + 2), 16);
  }
  return out;
}

// Accepts either:
//   - PostgREST/REST `\x<hex>` strings (what the .from('table').select() path
//     returns for bytea), or
//   - Realtime `postgres_changes` payloads, which encode bytea as plain
//     base64 (no `\x` prefix).
// Useful when the same row can arrive through both paths in the same UI.
export function pgBytesToBytes(value: string): Uint8Array {
  if (value.startsWith('\\x')) {
    return pgHexToBytes(value);
  }
  // Assume base64 (the realtime serializer's default for bytea).
  const bin = atob(value);
  const out = new Uint8Array(bin.length);
  for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i);
  return out;
}
