// src/lib/jobs/NotificationService.ts
// Service für das Erstellen von Benachrichtigungen

import { Payload } from 'payload'

// =============================================================================
// Types
// =============================================================================

export type NotificationType =
  | 'task_assigned'
  | 'task_due'
  | 'task_overdue'
  | 'approval_required'
  | 'approved'
  | 'rejected'
  | 'video_published'
  | 'comment'
  | 'mention'
  | 'token_expiring'
  | 'token_expired'
  | 'token_refresh_failed'
  | 'token_refreshed'
  | 'system'

export interface NotificationData {
  recipientId: number
  type: NotificationType
  title: string
  message?: string
  link?: string
  relatedVideoId?: number
  relatedTaskId?: number
  relatedAccountId?: number
}

export interface NotificationResult {
  success: boolean
  notificationId?: number
  error?: string
}

// =============================================================================
// Notification Service
// =============================================================================

export class NotificationService {
  private payload: Payload

  constructor(payload: Payload) {
    this.payload = payload
  }

  /**
   * Erstellt eine einzelne Benachrichtigung
   */
  async createNotification(data: NotificationData): Promise<NotificationResult> {
    try {
      const notification = await this.payload.create({
        collection: 'yt-notifications',
        data: {
          recipient: data.recipientId,
          type: data.type,
          title: data.title,
          message: data.message,
          link: data.link,
          relatedVideo: data.relatedVideoId,
          relatedTask: data.relatedTaskId,
          relatedAccount: data.relatedAccountId,
          read: false,
        },
      })

      return {
        success: true,
        notificationId: notification.id as number,
      }
    } catch (error) {
      const message = error instanceof Error ? error.message : String(error)
      console.error('[NotificationService] Error creating notification:', error)
      return {
        success: false,
        error: message,
      }
    }
  }

  /**
   * Erstellt Benachrichtigungen für mehrere Empfänger
   */
  async notifyMany(
    recipientIds: number[],
    data: Omit<NotificationData, 'recipientId'>
  ): Promise<NotificationResult[]> {
    const results: NotificationResult[] = []

    for (const recipientId of recipientIds) {
      const result = await this.createNotification({
        ...data,
        recipientId,
      })
      results.push(result)
    }

    return results
  }

  /**
   * Erstellt Benachrichtigungen für alle YouTube Manager
   */
  async notifyYouTubeManagers(
    data: Omit<NotificationData, 'recipientId'>
  ): Promise<NotificationResult[]> {
    try {
      // Alle User mit YouTube-Manager Rolle finden
      const users = await this.payload.find({
        collection: 'users',
        where: {
          or: [
            { roles: { contains: 'youtube_manager' } },
            { isSuperAdmin: { equals: true } },
          ],
        },
        limit: 100,
      })

      const recipientIds = users.docs.map((u) => u.id as number)

      if (recipientIds.length === 0) {
        console.warn('[NotificationService] No YouTube managers found')
        return []
      }

      return this.notifyMany(recipientIds, data)
    } catch (error) {
      console.error('[NotificationService] Error finding YouTube managers:', error)
      return []
    }
  }

  /**
   * Erstellt Token-Ablauf-Benachrichtigung
   */
  async notifyTokenExpiring(
    accountId: number,
    accountName: string,
    platform: string,
    daysUntilExpiry: number
  ): Promise<NotificationResult[]> {
    return this.notifyYouTubeManagers({
      type: 'token_expiring',
      title: `Token läuft bald ab: ${accountName}`,
      message: `Der ${platform}-Token für "${accountName}" läuft in ${daysUntilExpiry} Tagen ab. Bitte rechtzeitig erneuern.`,
      link: `/admin/collections/social-accounts/${accountId}`,
      relatedAccountId: accountId,
    })
  }

  /**
   * Erstellt Token-Abgelaufen-Benachrichtigung
   */
  async notifyTokenExpired(
    accountId: number,
    accountName: string,
    platform: string
  ): Promise<NotificationResult[]> {
    return this.notifyYouTubeManagers({
      type: 'token_expired',
      title: `Token abgelaufen: ${accountName}`,
      message: `Der ${platform}-Token für "${accountName}" ist abgelaufen. Bitte neu authentifizieren.`,
      link: `/admin/collections/social-accounts/${accountId}`,
      relatedAccountId: accountId,
    })
  }

  /**
   * Erstellt Token-Refresh-Fehlgeschlagen-Benachrichtigung
   */
  async notifyTokenRefreshFailed(
    accountId: number,
    accountName: string,
    platform: string,
    errorMessage: string
  ): Promise<NotificationResult[]> {
    return this.notifyYouTubeManagers({
      type: 'token_refresh_failed',
      title: `Token-Refresh fehlgeschlagen: ${accountName}`,
      message: `Der automatische Token-Refresh für "${accountName}" (${platform}) ist fehlgeschlagen: ${errorMessage}`,
      link: `/admin/collections/social-accounts/${accountId}`,
      relatedAccountId: accountId,
    })
  }

  /**
   * Erstellt Token-Erfolgreich-Erneuert-Benachrichtigung (optional, nur bei Warnung)
   */
  async notifyTokenRefreshed(
    accountId: number,
    accountName: string,
    platform: string,
    newExpiryDate: Date
  ): Promise<NotificationResult[]> {
    const daysUntilExpiry = Math.ceil(
      (newExpiryDate.getTime() - Date.now()) / (1000 * 60 * 60 * 24)
    )

    return this.notifyYouTubeManagers({
      type: 'token_refreshed',
      title: `Token erneuert: ${accountName}`,
      message: `Der ${platform}-Token für "${accountName}" wurde erfolgreich erneuert. Gültig für ${daysUntilExpiry} Tage.`,
      link: `/admin/collections/social-accounts/${accountId}`,
      relatedAccountId: accountId,
    })
  }
}

export default NotificationService
