import { timingSafeEqual } from '@zync/auth'

function toBase64Url(bytes: Uint8Array): string {
  return Buffer.from(bytes)
    .toString('base64')
    .replace(/\+/g, '-')
    .replace(/\//g, '_')
    .replace(/=+$/g, '')
}

async function signPayload(payload: string, key: string): Promise<string> {
  const importedKey = await crypto.subtle.importKey(
    'raw',
    new TextEncoder().encode(key),
    { name: 'HMAC', hash: 'SHA-256' },
    false,
    ['sign'],
  )
  const signature = await crypto.subtle.sign(
    'HMAC',
    importedKey,
    new TextEncoder().encode(payload),
  )
  return toBase64Url(new Uint8Array(signature))
}

export async function signSequenceUnsubToken(
  enrollmentId: string,
  tenantId: string,
  key: string,
): Promise<string> {
  return signPayload(`${enrollmentId}:${tenantId}`, key)
}

export async function verifySequenceUnsubToken(
  token: string,
  enrollmentId: string,
  tenantId: string,
  key: string,
): Promise<boolean> {
  const expected = await signSequenceUnsubToken(enrollmentId, tenantId, key)
  return timingSafeEqual(token, expected)
}

export function buildUnsubscribeUrl(enrollmentId: string, token: string): string {
  const params = new URLSearchParams({ e: token, id: enrollmentId })
  return `https://zync.is/unsubscribe/sequence?${params.toString()}`
}
