/**
 * Email adapter — DOCUMENTED INTEGRATION POINT (communications spec).
 *
 * foundation-auth-rbac must SEND transactional emails (verification, password
 * reset, invitations) but the communications module (Resend templating, queue
 * dispatch, unsubscribe handling) is owned by a downstream spec. Until it
 * lands, these helpers enqueue a typed message onto the shared QUEUE binding —
 * the documented contract consumed by the registered auth-email queue handler.
 * The producer is fail-closed: a queue outage reaches the auth flow instead of
 * reporting a verification/reset/invitation as delivered.
 */
import type { Env } from '@zync/types'

export type AuthEmailMessage = (
  | { kind: 'verify_email'; to: string; token: string; userId: string }
  | { kind: 'password_reset'; to: string; token: string; userId: string }
  | { kind: 'invitation'; to: string; token: string; tenantId: string; invitedBy: string }
  | { kind: 'email_change_verify'; to: string; verifyUrl: string; userId: string }
  | { kind: 'email_change_requested'; to: string; newEmail: string; userId: string }
) & { appOrigin?: string }

async function enqueue(env: Env, msg: AuthEmailMessage): Promise<void> {
  await env.QUEUE.send({ type: 'auth.email', ...msg })
}

/** Send the email-verification link (carries a signed token). */
export async function sendVerificationEmail(
  env: Env,
  to: string,
  token: string,
  userId: string,
  appOrigin?: string,
): Promise<void> {
  await enqueue(env, {
    kind: 'verify_email',
    to,
    token,
    userId,
    ...(appOrigin ? { appOrigin } : {}),
  })
}

/** Send the 1h password-reset link (carries a signed token). */
export async function sendPasswordResetEmail(
  env: Env,
  to: string,
  token: string,
  userId: string,
  appOrigin?: string,
): Promise<void> {
  await enqueue(env, {
    kind: 'password_reset',
    to,
    token,
    userId,
    ...(appOrigin ? { appOrigin } : {}),
  })
}

/** Send a tenant invitation (carries the PLAINTEXT opaque token; DB stores its hash). */
export async function sendInvitationEmail(
  env: Env,
  to: string,
  token: string,
  tenantId: string,
  invitedBy: string,
  appOrigin?: string,
): Promise<void> {
  await enqueue(env, {
    kind: 'invitation',
    to,
    token,
    tenantId,
    invitedBy,
    ...(appOrigin ? { appOrigin } : {}),
  })
}

/** Send email-change verification link to the new address. */
export async function sendEmailChangeVerification(
  env: Env,
  to: string,
  verifyUrl: string,
  userId: string,
  appOrigin?: string,
): Promise<void> {
  await enqueue(env, {
    kind: 'email_change_verify',
    to,
    verifyUrl,
    userId,
    ...(appOrigin ? { appOrigin } : {}),
  })
}

/** Notify the current address that an email change was requested. */
export async function sendEmailChangeRequested(
  env: Env,
  to: string,
  newEmail: string,
  userId: string,
  appOrigin?: string,
): Promise<void> {
  await enqueue(env, {
    kind: 'email_change_requested',
    to,
    newEmail,
    userId,
    ...(appOrigin ? { appOrigin } : {}),
  })
}
