import type { NotificationDto } from '~~/.api-client'
import { useUserStore } from '~~/stores/useUserStore'

export const useNotification = () => {
  const {
    getNotifications,
    getUnreadNotifications,
    getUnreadNotificationCount,
    markAllNotificationsAsRead,
    markNotificationAsRead
  } = useNotificationApi()

  const userStore = useUserStore()
  const organizationId = computed(() => userStore.selectedOrganization?.id)
  const { user } = useUserSession()
  const userId = computed(() => user.value?.keycloakId)

  const notifications = ref<NotificationDto[]>([])
  const unreadNotifications = ref<NotificationDto[]>([])
  const unreadCount = ref<number>(0)
  const isLoading = ref(false)

  const fetchNotifications = async (page: number = 0, size: number = 20) => {
    if (!organizationId.value) {
      console.warn('No organization selected')
      return
    }
    isLoading.value = true
    try {
      const response = await getNotifications(organizationId.value, page, size)
      notifications.value = response.content || []
      return response
    } catch (error) {
      console.error('Failed to fetch notifications:', error)
      throw error
    } finally {
      isLoading.value = false
    }
  }

  const fetchUnreadNotifications = async () => {
    if (!organizationId.value) {
      console.warn('No organization selected')
      return
    }
    try {
      const response = await getUnreadNotifications(organizationId.value)
      unreadNotifications.value = response || []
      return response
    } catch (error) {
      console.error('Failed to fetch unread notifications:', error)
      throw error
    }
  }

  const fetchUnreadCount = async () => {
    if (!userId.value || !organizationId.value) {
      console.warn('No user or organization selected')
      return
    }
    try {
      const count = await getUnreadNotificationCount(userId.value, organizationId.value)
      unreadCount.value = count || 0
      return count
    } catch (error) {
      console.error('Failed to fetch unread count:', error)
      throw error
    }
  }

  const markAllAsRead = async () => {
    if (!organizationId.value) {
      console.warn('No organization selected')
      return
    }
    try {
      await markAllNotificationsAsRead(organizationId.value)
      unreadCount.value = 0
      unreadNotifications.value = []
      notifications.value = notifications.value.map((n) => ({ ...n, isRead: true }))
    } catch (error) {
      console.error('Failed to mark all as read:', error)
      throw error
    }
  }

  const markAsRead = async (notificationId: string) => {
    if (!organizationId.value) {
      console.warn('No organization selected')
      return
    }
    try {
      await markNotificationAsRead(notificationId, organizationId.value)
      const index = notifications.value.findIndex((n) => n.id === notificationId)
      if (index !== -1) {
        notifications.value[index].isRead = true
      }
      // Remove from unread notifications
      unreadNotifications.value = unreadNotifications.value.filter((n) => n.id !== notificationId)

      if (unreadCount.value > 0) {
        unreadCount.value--
      }
    } catch (error) {
      console.error('Failed to mark notification as read:', error)
      throw error
    }
  }

  const handleNotificationClick = async (notification: NotificationDto) => {
    if (!notification.isRead) {
      await markAsRead(notification.id)
    }
    if (notification.clickTarget) {
      await navigateTo(notification.clickTarget)
    }
  }

  const startPeriodicRefresh = (intervalMs: number = 30000) => {
    const interval = setInterval(() => {
      void fetchUnreadCount()
    }, intervalMs)

    onUnmounted(() => {
      clearInterval(interval)
    })

    return interval
  }

  return {
    notifications,
    unreadNotifications,
    unreadCount,
    isLoading,
    fetchNotifications,
    fetchUnreadNotifications,
    fetchUnreadCount,
    markAllAsRead,
    markAsRead,
    handleNotificationClick,
    startPeriodicRefresh
  }
}
