/**
 * YouTube Upload Worker
 *
 * Verarbeitet YouTube-Upload-Jobs aus der Queue.
 * Nutzt den VideoUploadService fuer die eigentliche YouTube-API-Kommunikation.
 */

import { Worker, Job } from 'bullmq'
import { getPayload } from 'payload'
import config from '@payload-config'
import { QUEUE_NAMES, getQueueRedisConnection } from '../queue-service'
import type { YouTubeUploadJobData, YouTubeUploadJobResult } from '../jobs/youtube-upload-job'
import { VideoUploadService } from '../../integrations/youtube/VideoUploadService'
import { NotificationService } from '../../jobs/NotificationService'

// Worker-Konfiguration
const CONCURRENCY = parseInt(process.env.QUEUE_YOUTUBE_UPLOAD_CONCURRENCY || '1', 10)

/**
 * YouTube Upload Job Processor
 */
async function processUploadJob(
  job: Job<YouTubeUploadJobData>,
): Promise<YouTubeUploadJobResult> {
  const { contentId, mediaId, metadata, scheduledPublishAt, triggeredBy } = job.data

  console.log(`[YouTubeUploadWorker] Processing job ${job.id} for content ${contentId}`)

  try {
    const payload = await getPayload({ config })
    const uploadService = new VideoUploadService(payload)

    const result = await uploadService.uploadVideo({
      mediaId,
      metadata,
      scheduledPublishAt,
    })

    if (!result.success) {
      throw new Error(result.error || 'Upload failed')
    }

    // YouTubeContent mit Video-ID und URL aktualisieren
    await payload.update({
      collection: 'youtube-content',
      id: contentId,
      data: {
        youtube: {
          videoId: result.youtubeVideoId,
          url: result.youtubeUrl,
        },
        status: 'published',
        actualPublishDate: new Date().toISOString(),
      },
    })

    // Benachrichtigung erstellen
    const notificationService = new NotificationService(payload)
    await notificationService.createNotification({
      recipientId: triggeredBy,
      type: 'video_published',
      title: `Video "${metadata.title}" erfolgreich hochgeladen`,
      message: `YouTube-URL: ${result.youtubeUrl}`,
      link: `/admin/collections/youtube-content/${contentId}`,
      relatedVideoId: contentId,
    })

    const jobResult: YouTubeUploadJobResult = {
      success: true,
      youtubeVideoId: result.youtubeVideoId,
      youtubeUrl: result.youtubeUrl,
      timestamp: new Date().toISOString(),
    }

    console.log(`[YouTubeUploadWorker] Job ${job.id} completed: ${result.youtubeUrl}`)
    return jobResult
  } catch (error) {
    const errorMessage = error instanceof Error ? error.message : String(error)
    console.error(`[YouTubeUploadWorker] Job ${job.id} failed:`, errorMessage)

    // Error werfen damit BullMQ Retry-Logik greift
    throw error
  }
}

/**
 * YouTube Upload Worker Instanz
 */
let uploadWorker: Worker<YouTubeUploadJobData, YouTubeUploadJobResult> | null = null

/**
 * Startet den YouTube Upload Worker
 */
export function startYouTubeUploadWorker(): Worker<YouTubeUploadJobData, YouTubeUploadJobResult> {
  if (uploadWorker) {
    console.warn('[YouTubeUploadWorker] Worker already running')
    return uploadWorker
  }

  uploadWorker = new Worker<YouTubeUploadJobData, YouTubeUploadJobResult>(
    QUEUE_NAMES.YOUTUBE_UPLOAD,
    processUploadJob,
    {
      connection: getQueueRedisConnection(),
      concurrency: CONCURRENCY,
      // Uploads dauern laenger - grosszuegigere Stalled-Detection
      stalledInterval: 120000, // 2 Minuten
      maxStalledCount: 1,
      // Laengerer Lock fuer Video-Uploads
      lockDuration: 300000, // 5 Minuten
    },
  )

  // Event Handlers
  uploadWorker.on('ready', () => {
    console.log(`[YouTubeUploadWorker] Ready (concurrency: ${CONCURRENCY})`)
  })

  uploadWorker.on('completed', (job) => {
    console.log(`[YouTubeUploadWorker] Job ${job.id} completed in ${Date.now() - job.timestamp}ms`)
  })

  uploadWorker.on('failed', (job, error) => {
    console.error(
      `[YouTubeUploadWorker] Job ${job?.id} failed after ${job?.attemptsMade} attempts:`,
      error.message,
    )
  })

  uploadWorker.on('stalled', (jobId) => {
    console.warn(`[YouTubeUploadWorker] Job ${jobId} stalled`)
  })

  uploadWorker.on('error', (error) => {
    console.error('[YouTubeUploadWorker] Error:', error)
  })

  return uploadWorker
}

/**
 * Stoppt den YouTube Upload Worker
 */
export async function stopYouTubeUploadWorker(): Promise<void> {
  if (uploadWorker) {
    console.log('[YouTubeUploadWorker] Stopping...')
    await uploadWorker.close()
    uploadWorker = null
    console.log('[YouTubeUploadWorker] Stopped')
  }
}

/**
 * Gibt die Worker-Instanz zurueck (falls aktiv)
 */
export function getYouTubeUploadWorker(): Worker<YouTubeUploadJobData, YouTubeUploadJobResult> | null {
  return uploadWorker
}
