import { defineStore } from 'pinia' import type { NotificationDto } from '~~/.api-client' import { useNotificationApi } from '~/composables/notification/useNotificationApi' import { useLogger } from '~/composables/useLogger' import { useUserStore } from './useUserStore' export const useNotificationStore = defineStore('Notification', () => { const logger = useLogger().withTag('notificationStore') const userStore = useUserStore() const { user } = useUserSession() const { getNotifications, getUnreadNotifications, getUnreadNotificationCount, markAllNotificationsAsRead, markNotificationAsRead, clearAllNotifications, deleteNotification } = useNotificationApi() // State const notifications = ref([]) const unreadNotifications = ref([]) const unreadCount = ref(0) const isLoading = ref(false) // Getters const hasUnread = computed(() => unreadCount.value > 0) const organizationId = computed(() => userStore.selectedOrganization?.id) const userId = computed(() => user.value?.keycloakId) // Actions async function fetchNotifications(page: number = 0, size: number = 20) { if (!organizationId.value) { logger.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) { logger.error('Failed to fetch notifications:', error) throw error } finally { isLoading.value = false } } async function fetchUnreadNotifications() { if (!organizationId.value) { logger.warn('No organization selected') return } try { const response = await getUnreadNotifications(organizationId.value) unreadNotifications.value = response || [] return response } catch (error) { logger.error('Failed to fetch unread notifications:', error) throw error } } async function fetchUnreadCount() { if (!userId.value || !organizationId.value) { logger.warn('No user or organization selected') return } try { const count = await getUnreadNotificationCount(userId.value, organizationId.value) unreadCount.value = count || 0 return count } catch (error) { logger.error('Failed to fetch unread count:', error) throw error } } async function markAllAsRead() { if (!organizationId.value) { logger.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) { logger.error('Failed to mark all as read:', error) throw error } } async function markAsRead(notificationId: string) { if (!organizationId.value) { logger.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]) { 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) { logger.error('Failed to mark notification as read:', error) throw error } } async function handleNotificationClick(notification: NotificationDto) { if (!notification.isRead) { await markAsRead(notification.id) } if (notification.clickTarget) { await navigateTo(notification.clickTarget) } } function startPeriodicRefresh(intervalMs: number = 30000) { const interval = setInterval(() => { void fetchUnreadCount() }, intervalMs) onUnmounted(() => { clearInterval(interval) }) return interval } async function deleteAllNotifications() { try { await clearAllNotifications() notifications.value = [] unreadNotifications.value = [] unreadCount.value = 0 } catch (error) { logger.error('Failed to delete all notifications:', error) throw error } } async function deleteSingleNotification(notificationId: string) { try { // Check if notification was unread before deleting const notification = notifications.value.find((n) => n.id === notificationId) const wasUnread = notification && !notification.isRead await deleteNotification(notificationId) notifications.value = notifications.value.filter((n) => n.id !== notificationId) unreadNotifications.value = unreadNotifications.value.filter((n) => n.id !== notificationId) // Update unread count if the deleted notification was unread if (wasUnread && unreadCount.value > 0) { unreadCount.value-- } } catch (error) { logger.error('Failed to delete notification:', error) throw error } } return { // State notifications, unreadNotifications, unreadCount, isLoading, // Getters hasUnread, // Actions fetchNotifications, fetchUnreadNotifications, fetchUnreadCount, markAllAsRead, markAsRead, handleNotificationClick, startPeriodicRefresh, deleteAllNotifications, deleteSingleNotification } })