/**
 * Dashboard Data Provider
 *
 * Aggregates data from scheduler, notifications, and logs for the sync monitor dashboard.
 * Caches summary stats with configurable TTL for performance.
 *
 * @module core/dashboard/dashboard-data
 */
import { JobScheduler } from '../scheduler/job-scheduler.js';
import { NotificationManager } from '../notifications/notification-manager.js';
import { SyncAuditLogger } from '../sync/sync-audit-logger.js';
import { consoleLogger } from '../../utils/logger.js';
/**
 * DashboardDataProvider - Aggregates data for the sync monitor dashboard
 *
 * Pulls data from:
 * - JobScheduler: Job statuses, last run, next run
 * - NotificationManager: Pending notifications, summaries
 * - SyncAuditLogger: Activity stats for last 24 hours
 *
 * Caching strategy:
 * - Job statuses: Real-time (no cache)
 * - Notification counts: 5-second cache
 * - Activity summary: 1-minute cache
 */
export class DashboardDataProvider {
    constructor(options = {}) {
        // Caches
        this.notificationCache = null;
        this.activityCache = null;
        /**
         * Map scheduled job to dashboard format
         */
        this.mapJobToDashboard = (job) => {
            return {
                id: job.id,
                type: job.type,
                status: job.status,
                lastRun: job.schedule.lastRun,
                nextRun: job.schedule.nextRun,
                lastError: job.lastError,
                retryCount: job.schedule.retryCount > 0 ? job.schedule.retryCount : undefined,
            };
        };
        this.logger = options.logger ?? consoleLogger;
        this.notificationCacheTtlMs = options.notificationCacheTtlMs ?? 5000;
        this.activityCacheTtlMs = options.activityCacheTtlMs ?? 60000;
        this.recentNotificationsLimit = options.recentNotificationsLimit ?? 5;
        // Use provided instances or create new ones
        this.scheduler = options.scheduler ?? new JobScheduler({ logger: this.logger });
        this.notificationManager = options.notificationManager ?? new NotificationManager({
            specweavePath: options.specweavePath,
            logger: this.logger,
        });
        this.auditLogger = options.auditLogger ?? new SyncAuditLogger({
            specweavePath: options.specweavePath,
            logger: this.logger,
        });
    }
    /**
     * Get complete dashboard data
     *
     * @returns Aggregated dashboard data
     */
    async getData() {
        const [jobs, notifications, activity] = await Promise.all([
            this.getJobsData(),
            this.getNotificationsData(),
            this.getActivityData(),
        ]);
        return {
            jobs,
            notifications,
            activity,
            generatedAt: new Date().toISOString(),
        };
    }
    /**
     * Get jobs data (real-time, no cache)
     */
    async getJobsData() {
        const jobs = this.scheduler.getAllJobs();
        return jobs.map(this.mapJobToDashboard);
    }
    /**
     * Get notifications data (cached)
     */
    async getNotificationsData() {
        // Check cache
        if (this.notificationCache && Date.now() < this.notificationCache.expiresAt) {
            return this.notificationCache.data;
        }
        // Fetch fresh data
        const [summary, pending] = await Promise.all([
            this.notificationManager.getSummary(),
            this.notificationManager.getPending(),
        ]);
        const data = {
            total: summary.total,
            pending: summary.pending,
            bySeverity: {
                info: summary.bySeverity['info'] || 0,
                warning: summary.bySeverity['warning'] || 0,
                critical: summary.bySeverity['critical'] || 0,
            },
            recent: pending.slice(0, this.recentNotificationsLimit),
        };
        // Cache result
        this.notificationCache = {
            data,
            expiresAt: Date.now() + this.notificationCacheTtlMs,
        };
        return data;
    }
    /**
     * Get activity data (cached)
     */
    async getActivityData() {
        // Check cache
        if (this.activityCache && Date.now() < this.activityCache.expiresAt) {
            return this.activityCache.data;
        }
        // Fetch fresh data from audit logger
        const since = new Date(Date.now() - 24 * 60 * 60 * 1000); // Last 24 hours
        const stats = await this.auditLogger.getStats(since);
        const data = {
            last24h: {
                synced: stats.success,
                failed: stats.errors,
                skipped: stats.denied,
            },
            byPlatform: stats.byPlatform,
        };
        // Cache result
        this.activityCache = {
            data,
            expiresAt: Date.now() + this.activityCacheTtlMs,
        };
        return data;
    }
    /**
     * Get job status emoji for display
     */
    getJobStatusEmoji(status) {
        const statusEmojis = {
            idle: '✅',
            running: '🔄',
            failed: '❌',
            disabled: '⏸️',
        };
        return statusEmojis[status] ?? '❓';
    }
    /**
     * Format time relative to now (e.g., "5m ago", "in 10m")
     */
    formatRelativeTime(isoTimestamp) {
        if (!isoTimestamp) {
            return 'never';
        }
        const timestamp = new Date(isoTimestamp).getTime();
        const now = Date.now();
        const diffMs = timestamp - now;
        const absDiffMs = Math.abs(diffMs);
        if (absDiffMs < 60 * 1000) {
            return diffMs < 0 ? 'just now' : 'soon';
        }
        const minutes = Math.floor(absDiffMs / (60 * 1000));
        if (minutes < 60) {
            return diffMs < 0 ? `${minutes}m ago` : `in ${minutes}m`;
        }
        const hours = Math.floor(minutes / 60);
        if (hours < 24) {
            return diffMs < 0 ? `${hours}h ago` : `in ${hours}h`;
        }
        const days = Math.floor(hours / 24);
        return diffMs < 0 ? `${days}d ago` : `in ${days}d`;
    }
    /**
     * Clear all caches
     */
    clearCache() {
        this.notificationCache = null;
        this.activityCache = null;
    }
}
//# sourceMappingURL=dashboard-data.js.map