import { randomUUID } from 'crypto'
import { prisma } from '@/lib/prisma'
import { sendStyledNotificationEmail, emailDelay } from '@/lib/email'
import type { NotificationEmailContext } from '@/lib/email'

export type NotificationItem = {
  email: string
  name: string
  type: string // ADVANCEMENT_NOTIFICATION, REJECTION_NOTIFICATION, etc.
  context: NotificationEmailContext
  projectId?: string
  userId?: string
  roundId?: string
}

export type BatchResult = {
  sent: number
  failed: number
  batchId: string
  errors: Array<{ email: string; error: string }>
}

/**
 * Send notifications in batches with throttling and per-email logging.
 * Each email is logged to NotificationLog with SENT or FAILED status.
 */
export async function sendBatchNotifications(
  items: NotificationItem[],
  options?: { batchSize?: number; batchDelayMs?: number }
): Promise<BatchResult> {
  const batchId = randomUUID()
  const batchSize = options?.batchSize ?? 10
  const batchDelayMs = options?.batchDelayMs ?? 500

  let sent = 0
  let failed = 0
  const errors: Array<{ email: string; error: string }> = []

  for (let i = 0; i < items.length; i += batchSize) {
    const chunk = items.slice(i, i + batchSize)

    for (const item of chunk) {
      try {
        await sendStyledNotificationEmail(
          item.email,
          item.name,
          item.type,
          item.context,
        )
        sent++

        // Log success (fire-and-forget)
        prisma.notificationLog.create({
          data: {
            userId: item.userId || null,
            channel: 'EMAIL',
            type: item.type,
            status: 'SENT',
            email: item.email,
            roundId: item.roundId || null,
            projectId: item.projectId || null,
            batchId,
          },
        }).catch((err) => console.error('[notification-sender] Log write failed:', err))
      } catch (err) {
        const errorMsg = err instanceof Error ? err.message : String(err)
        failed++
        errors.push({ email: item.email, error: errorMsg })
        console.error(`[notification-sender] Failed for ${item.email}:`, err)

        // Log failure (fire-and-forget)
        prisma.notificationLog.create({
          data: {
            userId: item.userId || null,
            channel: 'EMAIL',
            type: item.type,
            status: 'FAILED',
            email: item.email,
            roundId: item.roundId || null,
            projectId: item.projectId || null,
            batchId,
            errorMsg,
          },
        }).catch((logErr) => console.error('[notification-sender] Log write failed:', logErr))
      }

      await emailDelay()
    }

    // Delay between chunks to avoid overwhelming SMTP
    if (i + batchSize < items.length) {
      await new Promise((resolve) => setTimeout(resolve, batchDelayMs))
    }
  }

  return { sent, failed, batchId, errors }
}
