/** Убирает переносы/неразрывные пробелы из вставки из почты и мессенджеров (иначе `malformed`). */
export function normalizeLicenseTokenInput(token: string): string {
  return token.replace(/[\s\u00a0\u200b-\u200d\ufeff\u2028\u2029]+/gu, '').trim();
}

const B64URL = {
  encode(bytes: Uint8Array): string {
    if (typeof Buffer !== 'undefined') {
      return Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength).toString('base64url');
    }
    let bin = '';
    for (const byte of bytes) {
      bin += String.fromCharCode(byte);
    }
    const b64 = btoa(bin);
    return b64.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/u, '');
  },
  decode(s: string): Uint8Array {
    if (typeof Buffer !== 'undefined') {
      try {
        return new Uint8Array(Buffer.from(s, 'base64url'));
      } catch {
        /* fall through */
      }
    }
    const pad = s.length % 4 === 0 ? '' : '='.repeat(4 - (s.length % 4));
    const b64 = s.replace(/-/g, '+').replace(/_/g, '/') + pad;
    const bin = atob(b64);
    const out = new Uint8Array(bin.length);
    for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i) & 0xff;
    return out;
  },
};

/** Тело UTF-8 + подпись Ed25519 (64 байта), разделитель «.». */
export function splitSignedLicenseToken(token: string): { bodyUtf8: string; signature: Uint8Array } | null {
  const t = normalizeLicenseTokenInput(token);
  const dot = t.indexOf('.');
  if (dot <= 0) return null;
  const a = t.slice(0, dot);
  const b = t.slice(dot + 1);
  if (!a || !b) return null;
  try {
    const bodyBytes = B64URL.decode(a);
    const sigBytes = B64URL.decode(b);
    const bodyUtf8 = new TextDecoder().decode(bodyBytes);
    return { bodyUtf8, signature: sigBytes };
  } catch {
    return null;
  }
}

export function joinSignedLicenseToken(bodyUtf8: string, signature: Uint8Array): string {
  const bodyBytes = new TextEncoder().encode(bodyUtf8);
  return `${B64URL.encode(bodyBytes)}.${B64URL.encode(signature)}`;
}
