/**
 * Notifications Service - Polls and manages user notifications
 */

import { directus } from './directus.js'
import { auth } from './auth.js'

class NotificationsService {
    constructor() {
        this.unreadCount = 0
        this.notifications = []
        this.listeners = new Set()
        this.pollTimer = null
        this.pollInterval = 60 * 1000 // 60 seconds
        this.userHash = null
    }

    async init() {
        if (!auth.isLoggedIn()) return

        this.userHash = await this._getUserHash()
        if (!this.userHash) return

        await this.refresh()
        this.startPolling()
    }

    async _getUserHash() {
        const user = await auth.getUser()
        return user?.id || null
    }

    async refresh() {
        if (!this.userHash) return

        if (!auth.isLoggedIn()) {
            this.destroy()
            return
        }

        try {
            const [count, notifications] = await Promise.all([
                directus.getUnreadCount(this.userHash),
                directus.getNotifications(this.userHash)
            ])
            this.unreadCount = count
            this.notifications = notifications
            this.notify()
        } catch (e) {
            if (e.status === 401 || e.status === 403) {
                this.stopPolling()
            }
        }
    }

    startPolling() {
        this.stopPolling()
        this.pollTimer = setInterval(() => this.refresh(), this.pollInterval)

        document.addEventListener('visibilitychange', this._onVisibility)
    }

    stopPolling() {
        if (this.pollTimer) {
            clearInterval(this.pollTimer)
            this.pollTimer = null
        }
        document.removeEventListener('visibilitychange', this._onVisibility)
    }

    _onVisibility = () => {
        if (document.visibilityState === 'visible') {
            this.refresh()
        }
    }

    async markRead(id) {
        await directus.markNotificationRead(id)
        const n = this.notifications.find(n => n.id === id)
        if (n) {
            n.read = true
            this.unreadCount = Math.max(0, this.unreadCount - 1)
            this.notify()
        }
    }

    async markAllRead() {
        if (!this.userHash) return
        await directus.markAllNotificationsRead(this.userHash)
        this.notifications.forEach(n => n.read = true)
        this.unreadCount = 0
        this.notify()
    }

    async remove(id) {
        await directus.deleteNotification(id)
        this.notifications = this.notifications.filter(n => n.id !== id)
        this.unreadCount = this.notifications.filter(n => !n.read).length
        this.notify()
    }

    subscribe(callback) {
        this.listeners.add(callback)
        return () => this.listeners.delete(callback)
    }

    notify() {
        for (const cb of this.listeners) {
            cb(this.unreadCount, this.notifications)
        }
    }

    destroy() {
        this.stopPolling()
        this.listeners.clear()
        this.notifications = []
        this.unreadCount = 0
        this.userHash = null
    }
}

export const notificationsService = new NotificationsService()
