// Notification manager that integrates Nostr events with push notifications
import { pushService, type NotificationPayload } from './push'
import { configUtils } from '@/lib/config'
import type { NostrNote } from '@/lib/nostr/client'

export interface NotificationOptions {
  enabled: boolean
  adminAnnouncements: boolean
  mentions: boolean
  replies: boolean
  sound: boolean
}

export class NotificationManager {
  private static instance: NotificationManager
  private options: NotificationOptions = {
    enabled: true,
    adminAnnouncements: true,
    mentions: true,
    replies: false,
    sound: true
  }

  static getInstance(): NotificationManager {
    if (!this.instance) {
      this.instance = new NotificationManager()
    }
    return this.instance
  }

  constructor() {
    this.loadOptions()
  }

  // Load notification options from localStorage
  private loadOptions(): void {
    try {
      const stored = localStorage.getItem('notification-options')
      if (stored) {
        this.options = { ...this.options, ...JSON.parse(stored) }
      }
    } catch (error) {
      console.warn('Failed to load notification options:', error)
    }
  }

  // Save notification options to localStorage
  private saveOptions(): void {
    try {
      localStorage.setItem('notification-options', JSON.stringify(this.options))
    } catch (error) {
      console.warn('Failed to save notification options:', error)
    }
  }

  // Get current options
  getOptions(): NotificationOptions {
    return { ...this.options }
  }

  // Update options
  updateOptions(newOptions: Partial<NotificationOptions>): void {
    this.options = { ...this.options, ...newOptions }
    this.saveOptions()
  }

  // Check if notifications should be sent for a note
  shouldNotify(note: NostrNote, userPubkey?: string): boolean {
    if (!this.options.enabled) return false

    // Admin announcements
    if (this.options.adminAnnouncements && configUtils.isAdminPubkey(note.pubkey)) {
      return true
    }

    // Mentions (if user is mentioned in the note)
    if (this.options.mentions && userPubkey && note.mentions.includes(userPubkey)) {
      return true
    }

    // Replies (if it's a reply to user's note)
    if (this.options.replies && userPubkey && note.isReply && note.replyTo) {
      // We'd need to check if the reply is to the user's note
      // This would require additional context about the user's notes
      return false
    }

    return false
  }

  // Create notification payload from Nostr note
  private createNotificationPayload(note: NostrNote): NotificationPayload {
    const isAdmin = configUtils.isAdminPubkey(note.pubkey)
    
    let title = 'New Note'
    let body = note.content
    let tag = 'nostr-note'

    if (isAdmin) {
      title = '🚨 Admin Announcement'
      tag = 'admin-announcement'
    } else if (note.isReply) {
      title = 'Reply'
      tag = 'reply'
    } else if (note.mentions.length > 0) {
      title = 'Mention'
      tag = 'mention'
    }

    // Truncate long content
    if (body.length > 100) {
      body = body.slice(0, 100) + '...'
    }

    return {
      title,
      body,
      icon: '/pwa-192x192.png',
      badge: '/pwa-192x192.png',
      tag,
      requireInteraction: isAdmin, // Admin announcements require interaction
      data: {
        noteId: note.id,
        pubkey: note.pubkey,
        isAdmin,
        url: '/',
        timestamp: note.created_at
      },
      actions: isAdmin ? [
        {
          action: 'view',
          title: 'View'
        },
        {
          action: 'dismiss',
          title: 'Dismiss'
        }
      ] : [
        {
          action: 'view',
          title: 'View'
        }
      ]
    }
  }

  // Send notification for a Nostr note
  async notifyForNote(note: NostrNote, userPubkey?: string): Promise<void> {
    try {
      if (!this.shouldNotify(note, userPubkey)) {
        return
      }

      if (!pushService.isSupported()) {
        console.warn('Push notifications not supported')
        return
      }

      const isSubscribed = await pushService.isSubscribed()
      if (!isSubscribed) {
        console.log('User not subscribed to push notifications')
        return
      }

      const payload = this.createNotificationPayload(note)
      await pushService.showLocalNotification(payload)

      console.log('Notification sent for note:', note.id)

    } catch (error) {
      console.error('Failed to send notification for note:', error)
    }
  }

  // Send test notification
  async sendTestNotification(): Promise<void> {
    const testPayload: NotificationPayload = {
      title: '🚨 Test Admin Announcement',
      body: 'This is a test notification to verify push notifications are working correctly.',
      icon: '/pwa-192x192.png',
      badge: '/pwa-192x192.png',
      tag: 'test-notification',
      requireInteraction: true,
      data: {
        url: '/',
        type: 'test',
        timestamp: Date.now()
      },
      actions: [
        {
          action: 'view',
          title: 'View App'
        },
        {
          action: 'dismiss',
          title: 'Dismiss'
        }
      ]
    }

    await pushService.showLocalNotification(testPayload)
  }

  // Handle background notification processing
  async processBackgroundNote(noteData: any): Promise<void> {
    // This would be called from the service worker
    // when receiving push notifications from a backend
    try {
      const payload = this.createNotificationPayload(noteData)
      
      // Show notification via service worker
      if ('serviceWorker' in navigator) {
        const registration = await navigator.serviceWorker.ready
        await registration.showNotification(payload.title, payload)
      }
    } catch (error) {
      console.error('Failed to process background notification:', error)
    }
  }

  // Check if user has denied notifications
  isBlocked(): boolean {
    return pushService.getPermission() === 'denied'
  }

  // Check if notifications are enabled and configured
  isConfigured(): boolean {
    return pushService.isSupported() && configUtils.hasPushConfig()
  }
}

// Export singleton instance
export const notificationManager = NotificationManager.getInstance()