/**
 * Notification Manager
 *
 * Manages notification preferences, quiet hours, rate limiting, and history.
 */
import { EventEmitter } from 'events';
const DEFAULT_PREFERENCES = {
    channels: ['cli'],
    maxPerHour: 20,
    quietHoursMinPriority: 'urgent',
};
const PRIORITY_LEVELS = {
    low: 0,
    normal: 1,
    high: 2,
    urgent: 3,
};
// ============================================================================
// Notification Manager
// ============================================================================
export class NotificationManager extends EventEmitter {
    preferences;
    history = [];
    maxHistory = 1000;
    constructor(preferences = {}) {
        super();
        this.preferences = { ...DEFAULT_PREFERENCES, ...preferences };
    }
    /**
     * Check if a notification should be sent
     */
    shouldSend(msg) {
        // Check channel enabled
        if (!this.preferences.channels.includes(msg.channelType)) {
            return { allowed: false, reason: `Channel ${msg.channelType} not enabled` };
        }
        // Check quiet hours
        if (this.isQuietHours()) {
            const minLevel = PRIORITY_LEVELS[this.preferences.quietHoursMinPriority];
            const msgLevel = PRIORITY_LEVELS[msg.priority];
            if (msgLevel < minLevel) {
                return { allowed: false, reason: 'Quiet hours - priority too low' };
            }
        }
        // Check rate limit
        if (this.isRateLimited()) {
            return { allowed: false, reason: 'Rate limit exceeded' };
        }
        return { allowed: true };
    }
    /**
     * Record a notification
     */
    record(msg, delivered) {
        this.history.push({
            timestamp: new Date(),
            channelType: msg.channelType,
            priority: msg.priority,
            delivered,
        });
        // Trim history
        if (this.history.length > this.maxHistory) {
            this.history = this.history.slice(-this.maxHistory);
        }
    }
    /**
     * Check if currently in quiet hours
     */
    isQuietHours() {
        if (this.preferences.quietHoursStart === undefined ||
            this.preferences.quietHoursEnd === undefined) {
            return false;
        }
        const hour = new Date().getHours();
        const start = this.preferences.quietHoursStart;
        const end = this.preferences.quietHoursEnd;
        if (start <= end) {
            return hour >= start && hour < end;
        }
        // Wraps midnight (e.g., 22-7)
        return hour >= start || hour < end;
    }
    /**
     * Check if rate limit is exceeded
     */
    isRateLimited() {
        const oneHourAgo = Date.now() - 3600000;
        const recentCount = this.history.filter(r => r.timestamp.getTime() > oneHourAgo && r.delivered).length;
        return recentCount >= this.preferences.maxPerHour;
    }
    /**
     * Update preferences
     */
    setPreferences(prefs) {
        this.preferences = { ...this.preferences, ...prefs };
        this.emit('preferences:updated', this.preferences);
    }
    /**
     * Get current preferences
     */
    getPreferences() {
        return { ...this.preferences };
    }
    /**
     * Get notification history
     */
    getHistory(limit) {
        const sorted = [...this.history].sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime());
        return limit ? sorted.slice(0, limit) : sorted;
    }
    /**
     * Get stats
     */
    getStats() {
        const oneHourAgo = Date.now() - 3600000;
        const lastHour = this.history.filter(r => r.timestamp.getTime() > oneHourAgo);
        const delivered = this.history.filter(r => r.delivered);
        return {
            totalSent: this.history.length,
            lastHour: lastHour.length,
            deliveryRate: this.history.length > 0
                ? delivered.length / this.history.length
                : 1,
        };
    }
}
// ============================================================================
// Singleton
// ============================================================================
let managerInstance = null;
export function getNotificationManager(prefs) {
    if (!managerInstance) {
        managerInstance = new NotificationManager(prefs);
    }
    return managerInstance;
}
export function resetNotificationManager() {
    managerInstance = null;
}
//# sourceMappingURL=notification-manager.js.map