import { ref, computed } from 'vue'
import { defineStore } from 'pinia'
import type {
  Notification,
  NotificationPreferences,
  NotificationStats
} from '@/types/notification'
import * as notificationService from '@/services/notification'

export const useNotificationsStore = defineStore('notifications', () => {
  const notifications = ref<Notification[]>([])
  const preferences = ref<NotificationPreferences | null>(null)
  const stats = ref<NotificationStats | null>(null)
  const loading = ref(false)
  const error = ref<string | null>(null)

  const unreadCount = computed(() => stats.value?.unread || 0)
  const unreadNotifications = computed(() => 
    notifications.value.filter((n: Notification) => !n.read)
  )

  async function fetchNotifications(unreadOnly = false) {
    loading.value = true
    error.value = null
    try {
      notifications.value = await notificationService.getNotifications(0, 50, unreadOnly)
    } catch (err) {
      error.value = err instanceof Error ? err.message : 'Failed to fetch notifications'
      throw err
    } finally {
      loading.value = false
    }
  }

  async function fetchStats() {
    try {
      stats.value = await notificationService.getNotificationStats()
    } catch (err) {
      console.error('Failed to fetch notification stats:', err)
    }
  }

  async function markAsRead(notificationIds: number[]) {
    try {
      await notificationService.markNotificationsRead(notificationIds)
      
      // Update local state
      notifications.value = notifications.value.map((n: Notification) => 
        notificationIds.includes(n.id) ? { ...n, read: true, read_at: new Date().toISOString() } : n
      )
      
      // Refresh stats
      await fetchStats()
    } catch (err) {
      error.value = err instanceof Error ? err.message : 'Failed to mark notifications as read'
      throw err
    }
  }

  async function markAllAsRead() {
    try {
      await notificationService.markAllNotificationsRead()
      
      // Update local state
      notifications.value = notifications.value.map((n: Notification) => ({ 
        ...n, 
        read: true, 
        read_at: new Date().toISOString() 
      }))
      
      // Refresh stats
      await fetchStats()
    } catch (err) {
      error.value = err instanceof Error ? err.message : 'Failed to mark all notifications as read'
      throw err
    }
  }

  async function deleteNotification(notificationId: number) {
    try {
      await notificationService.deleteNotification(notificationId)
      
      // Remove from local state
      notifications.value = notifications.value.filter((n: Notification) => n.id !== notificationId)
      
      // Refresh stats
      await fetchStats()
    } catch (err) {
      error.value = err instanceof Error ? err.message : 'Failed to delete notification'
      throw err
    }
  }

  async function fetchPreferences() {
    loading.value = true
    error.value = null
    try {
      preferences.value = await notificationService.getNotificationPreferences()
    } catch (err) {
      error.value = err instanceof Error ? err.message : 'Failed to fetch preferences'
      throw err
    } finally {
      loading.value = false
    }
  }

  async function updatePreferences(data: Partial<NotificationPreferences>) {
    loading.value = true
    error.value = null
    try {
      preferences.value = await notificationService.updateNotificationPreferences(data)
    } catch (err) {
      error.value = err instanceof Error ? err.message : 'Failed to update preferences'
      throw err
    } finally {
      loading.value = false
    }
  }

  // Poll for new notifications
  function startPolling(intervalMs = 30000) {
    const pollInterval = setInterval(async () => {
      await fetchStats()
    }, intervalMs)

    return () => clearInterval(pollInterval)
  }

  return {
    notifications,
    preferences,
    stats,
    loading,
    error,
    unreadCount,
    unreadNotifications,
    fetchNotifications,
    fetchStats,
    markAsRead,
    markAllAsRead,
    deleteNotification,
    fetchPreferences,
    updatePreferences,
    startPolling
  }
})
