/**
 * EmailNotificationAdapter — system-communications-notifications (Task 6).
 *
 * Delivers notifications via email using the Resend REST client.
 * `canDeliver` reads `user_preferences.notification_channels.email` via the
 * query function (no raw schema table imports in this file).
 */
import type {
  NotificationAdapter,
  DeliverableNotification,
  DeliveryResult,
  NotificationType,
} from '@zync/types'
import type { Db } from '@zync/db/queries'
import type { Env } from '@zync/types'
import {
  getUserEmailPrefs,
  getUserEmailAndLocale,
} from '@zync/db/queries'
import { sendEmail } from '../email/send-email'
import { buildActionButtonsHtml } from '../email/escape'

/** Notification type → email template key mapping */
function templateKeyForType(type: NotificationType): string {
  switch (type) {
    case 'invoice_sent':
    case 'invoice_paid':
    case 'invoice_overdue':
    case 'invoice_cancelled':
    case 'invoice_viewed':
      return 'invoice-sent'
    case 'user_invited':
      return 'invitation'
    default:
      return 'invoice-sent'
  }
}

export class EmailNotificationAdapter implements NotificationAdapter {
  readonly id = 'email' as const

  constructor(
    private readonly db: Db,
    private readonly env: Env,
    private readonly tenantId: string,
  ) {}

  async canDeliver(userId: string, type: NotificationType): Promise<boolean> {
    try {
      const prefs = await getUserEmailPrefs(this.db, userId, this.tenantId)
      if (!prefs) return false
      const emailTypes: string[] = prefs.emailTypes ?? []
      return emailTypes.includes(type)
    } catch {
      return false
    }
  }

  async deliver(userId: string, notification: DeliverableNotification): Promise<DeliveryResult> {
    // Silent no-op when delivery would be disallowed
    const canSend = await this.canDeliver(userId, notification.type)
    if (!canSend) return { delivered: false }

    try {
      const userInfo = await getUserEmailAndLocale(this.db, userId, this.tenantId)
      if (!userInfo?.email) {
        return { delivered: false, error: 'User email not found' }
      }

      const locale: 'he-IL' | 'en-US' =
        userInfo.locale === 'en' || userInfo.locale === 'en-US' ? 'en-US' : 'he-IL'

      // Render action buttons as HTML links (callbackAction dropped for email)
      const buttonHtml = buildActionButtonsHtml(notification.actionButtons)

      await sendEmail(
        {
          to: userInfo.email,
          templateKey: templateKeyForType(notification.type),
          vars: {
            title: notification.title,
            body: notification.body,
            actionButtons: buttonHtml,
            subject: notification.title,
          },
          locale,
        },
        this.env,
      )

      return { delivered: true }
    } catch (err) {
      return {
        delivered: false,
        error: err instanceof Error ? err.message : String(err),
      }
    }
  }
}
