/**
 * Email Job Definition
 *
 * Definiert den E-Mail-Versand-Job für die Queue.
 * Unterstützt Multi-Tenant SMTP-Konfiguration.
 */

import { Job } from 'bullmq'
import { getQueue, QUEUE_NAMES, defaultJobOptions } from '../queue-service'

// Job-Daten Typen
export interface EmailJobData {
  // E-Mail-Inhalte
  to: string | string[]
  subject: string
  html?: string
  text?: string
  replyTo?: string

  // Tenant-Kontext
  tenantId: number
  tenantSlug?: string

  // Metadaten
  triggeredBy?: string // User ID oder System
  source?: 'api' | 'form' | 'notification' | 'alert'
  correlationId?: string // Für Tracking

  // Optionen
  priority?: 'high' | 'normal' | 'low'
}

export interface EmailJobResult {
  success: boolean
  messageId?: string
  error?: string
  timestamp: string
  attempts: number
}

// Priority-Mapping für BullMQ (niedrigere Zahl = höhere Priorität)
const PRIORITY_MAP = {
  high: 1,
  normal: 5,
  low: 10,
}

/**
 * Fügt einen E-Mail-Job zur Queue hinzu
 */
export async function enqueueEmail(data: EmailJobData): Promise<Job<EmailJobData>> {
  const queue = getQueue(QUEUE_NAMES.EMAIL)

  const jobOptions = {
    ...defaultJobOptions,
    priority: PRIORITY_MAP[data.priority || 'normal'],
    // Job-ID für Deduplizierung (optional)
    jobId: data.correlationId,
  }

  const job = await queue.add('send-email', data, jobOptions)

  console.log(`[EmailQueue] Job ${job.id} queued for ${Array.isArray(data.to) ? data.to.join(', ') : data.to}`)

  return job
}

/**
 * Fügt einen verzögerten E-Mail-Job zur Queue hinzu
 */
export async function enqueueDelayedEmail(
  data: EmailJobData,
  delayMs: number
): Promise<Job<EmailJobData>> {
  const queue = getQueue(QUEUE_NAMES.EMAIL)

  const job = await queue.add('send-email', data, {
    ...defaultJobOptions,
    priority: PRIORITY_MAP[data.priority || 'normal'],
    delay: delayMs,
  })

  console.log(`[EmailQueue] Delayed job ${job.id} queued (delay: ${delayMs}ms)`)

  return job
}

/**
 * Fügt mehrere E-Mails als Batch zur Queue hinzu
 */
export async function enqueueEmailBatch(
  emails: EmailJobData[]
): Promise<Job<EmailJobData>[]> {
  const queue = getQueue(QUEUE_NAMES.EMAIL)

  const jobs = await queue.addBulk(
    emails.map((data) => ({
      name: 'send-email',
      data,
      opts: {
        ...defaultJobOptions,
        priority: PRIORITY_MAP[data.priority || 'normal'],
      },
    }))
  )

  console.log(`[EmailQueue] ${jobs.length} batch jobs queued`)

  return jobs
}

/**
 * Prüft ob ein Job bereits existiert (für Deduplizierung)
 */
export async function isEmailJobPending(correlationId: string): Promise<boolean> {
  const queue = getQueue(QUEUE_NAMES.EMAIL)

  const job = await queue.getJob(correlationId)
  if (!job) return false

  const state = await job.getState()
  return state === 'waiting' || state === 'active' || state === 'delayed'
}

/**
 * Holt den Status eines E-Mail-Jobs
 */
export async function getEmailJobStatus(jobId: string): Promise<{
  state: string
  progress: number
  result?: EmailJobResult
  failedReason?: string
} | null> {
  const queue = getQueue(QUEUE_NAMES.EMAIL)

  const job = await queue.getJob(jobId)
  if (!job) return null

  const [state, progress] = await Promise.all([
    job.getState(),
    job.progress,
  ])

  return {
    state,
    progress: typeof progress === 'number' ? progress : 0,
    result: job.returnvalue as EmailJobResult | undefined,
    failedReason: job.failedReason,
  }
}
