import { Novu } from '@novu/js'

interface NovuNotification {
  id: string
  content: string
  read: boolean
  seen: boolean
  createdAt: string
  payload?: Record<string, unknown>
  cta?: {
    type: string
    data: {
      url?: string
    }
  }
}

let novuInstance: Novu | null = null

export const useNovu = () => {
  const config = useRuntimeConfig()
  const notifications = ref<NovuNotification[]>([])
  const unreadCount = ref(0)
  const isLoading = ref(false)
  const isInitialized = ref(false)

  const init = (subscriberId: string) => {
    if (novuInstance || !subscriberId) return

    const appId = config.public.novuAppId
    const backendUrl = config.public.novuBackendUrl
    const socketUrl = config.public.novuSocketUrl

    if (!appId || !backendUrl) {
      console.warn('[useNovu] Missing configuration: novuAppId or novuBackendUrl')
      return
    }

    novuInstance = new Novu({
      subscriberId,
      applicationIdentifier: appId,
      backendUrl,
      socketUrl: socketUrl || undefined
    })

    isInitialized.value = true

    // Subscribe to realtime updates
    novuInstance.on('notifications.notification_received', () => {
      loadNotifications()
    })

    // Load initial data
    loadNotifications()
  }

  const loadNotifications = async () => {
    if (!novuInstance) return

    isLoading.value = true
    try {
      const result = await novuInstance.notifications.list({ limit: 20 })
      const data = Array.isArray(result?.data)
        ? result.data
        : (result?.data?.notifications || [])
      notifications.value = data as NovuNotification[]
      unreadCount.value = notifications.value.filter((n: NovuNotification) => !n.read).length
    } catch (error) {
      console.error('[useNovu] Failed to load notifications:', error)
    } finally {
      isLoading.value = false
    }
  }

  const markAsRead = async (notificationId: string) => {
    if (!novuInstance) return

    try {
      await novuInstance.notifications.read({ notificationId })
      // Update locally
      const notification = notifications.value.find((n: NovuNotification) => n.id === notificationId)
      if (notification) {
        notification.read = true
        unreadCount.value = notifications.value.filter((n: NovuNotification) => !n.read).length
      }
    } catch (error) {
      console.error('[useNovu] Failed to mark as read:', error)
    }
  }

  const markAllAsRead = async () => {
    if (!novuInstance) return

    try {
      await novuInstance.notifications.readAll()
      notifications.value.forEach((n: NovuNotification) => { n.read = true })
      unreadCount.value = 0
    } catch (error) {
      console.error('[useNovu] Failed to mark all as read:', error)
    }
  }

  const markAsSeen = async (notificationId: string) => {
    if (!novuInstance) return

    try {
      await novuInstance.notifications.archive({ notificationId })
      const notification = notifications.value.find((n: NovuNotification) => n.id === notificationId)
      if (notification) {
        notification.seen = true
      }
    } catch (error) {
      console.error('[useNovu] Failed to mark as seen:', error)
    }
  }

  const destroy = () => {
    if (novuInstance) {
      novuInstance = null
      isInitialized.value = false
      notifications.value = []
      unreadCount.value = 0
    }
  }

  return {
    init,
    destroy,
    notifications,
    unreadCount,
    isLoading,
    isInitialized,
    markAsRead,
    markAllAsRead,
    markAsSeen,
    loadNotifications
  }
}
