// Monitoring Page Module

class MonitoringPage {
    constructor() {
        this.isPaused = false;
        this.requestStream = [];
        this.systemLogs = [];
        this.init();
    }

    async init() {
        // Load initial data
        await this.loadSystemMetrics();
        await this.loadCharts();
        
        // Setup event listeners
        this.setupEventListeners();
        
        // Setup WebSocket subscriptions
        this.setupWebSocketSubscriptions();
        
        // Start simulated updates for demo
        this.startDemoUpdates();
    }

    async loadSystemMetrics() {
        const container = document.getElementById('system-metrics');
        if (!container) return;

        try {
            const data = await window.api.get('/system/metrics');
            const metrics = [
                { label: 'CPU Usage', value: `${data.cpu.usage_percent}%`, trend: data.cpu.usage_percent > 80 ? 'up' : data.cpu.usage_percent < 30 ? 'down' : 'stable' },
                { label: 'Memory', value: `${(data.memory.used_mb / 1024).toFixed(1)} / ${(data.memory.total_mb / 1024).toFixed(1)} GB`, trend: data.memory.usage_percent > 80 ? 'up' : 'stable' },
                { label: 'Disk', value: `${data.disk.used_gb.toFixed(1)} / ${data.disk.total_gb.toFixed(1)} GB`, trend: data.disk.usage_percent > 80 ? 'up' : 'stable' },
                { label: 'Process RSS', value: `${data.memory.process_rss_mb} MB`, trend: 'stable' },
                { label: 'Load Average', value: data.cpu.load_average.map(v => v.toFixed(2)).join(' / '), trend: data.cpu.load_average[0] > 2 ? 'up' : 'down' },
                { label: 'Connections', value: `${data.connections.db_active} DB, ${data.connections.websocket_listeners} WS`, trend: 'stable' },
            ];

            container.innerHTML = metrics.map(metric => `
                <div class="metric-item">
                    <div class="metric-label">${metric.label}</div>
                    <div class="metric-value">${metric.value}</div>
                    <div class="metric-trend ${metric.trend}">
                        <i class="fas fa-arrow-${metric.trend === 'up' ? 'up' : metric.trend === 'down' ? 'down' : 'minus'}"></i>
                    </div>
                </div>
            `).join('');
        } catch (error) {
            console.error('Error loading system metrics:', error);
            container.innerHTML = '<div class="metric-item"><div class="metric-label" style="color: var(--danger);">Failed to load metrics</div></div>';
        }

        // Add CSS for metrics
        this.addMetricStyles();
    }

    addMetricStyles() {
        // Avoid injecting duplicate styles
        if (document.getElementById('monitoring-metric-styles')) return;
        const style = document.createElement('style');
        style.id = 'monitoring-metric-styles';
        style.textContent = `
            .metric-item {
                display: flex;
                align-items: center;
                justify-content: space-between;
                padding: 0.75rem;
                border-bottom: 1px solid var(--border-color);
            }
            
            .metric-item:last-child {
                border-bottom: none;
            }
            
            .metric-label {
                font-size: 0.875rem;
                color: var(--text-secondary);
            }
            
            .metric-value {
                font-weight: 600;
                color: var(--text-primary);
            }
            
            .metric-trend {
                width: 24px;
                height: 24px;
                border-radius: 50%;
                display: flex;
                align-items: center;
                justify-content: center;
                font-size: 0.75rem;
            }
            
            .metric-trend.up {
                background-color: rgba(239, 68, 68, 0.1);
                color: var(--danger);
            }
            
            .metric-trend.down {
                background-color: rgba(16, 185, 129, 0.1);
                color: var(--success);
            }
            
            .metric-trend.stable {
                background-color: rgba(100, 116, 139, 0.1);
                color: var(--text-secondary);
            }
            
            .stream-entry {
                display: flex;
                align-items: center;
                gap: 0.75rem;
                padding: 0.5rem;
                border-bottom: 1px solid var(--border-color);
                transition: background-color 0.2s ease;
            }
            
            .stream-entry:last-child {
                border-bottom: none;
            }
            
            .stream-entry.highlight {
                background-color: rgba(37, 99, 235, 0.05);
            }
            
            .stream-entry-time {
                font-size: 0.75rem;
                color: var(--text-light);
                min-width: 60px;
            }
            
            .stream-entry-icon {
                font-size: 0.875rem;
                width: 24px;
                text-align: center;
            }
            
            .stream-entry-content {
                flex: 1;
                font-size: 0.875rem;
            }
            
            .stream-entry-details {
                font-size: 0.75rem;
                color: var(--text-secondary);
                margin-top: 0.125rem;
            }
        `;
        document.head.appendChild(style);
    }

    async loadCharts() {
        // Ensure chartManager is available
        const cm = window.chartManager || await window.waitForChartManager();
        if (!cm) {
            console.warn('chartManager unavailable, skipping monitoring charts');
            return;
        }

        // Fetch recent logs for chart data
        try {
            const logs = await window.api.get('/system/logs');
            this.recentLogs = Array.isArray(logs) ? logs : [];
        } catch (error) {
            console.error('Error loading logs for charts:', error);
            this.recentLogs = [];
        }
        await this.loadResponseTimeChart();
        await this.loadErrorRateChart();
        await this.loadRateLimitChart();
    }

    async loadResponseTimeChart() {
        try {
            const cm = window.chartManager;
            if (!cm) return;
            // Bucket recent logs by minute for latency chart
            const buckets = this.bucketByMinute(this.recentLogs, 20);
            const labels = buckets.map(b => b.label);
            const values = buckets.map(b => {
                if (b.items.length === 0) return 0;
                const total = b.items.reduce((sum, r) => sum + (r.duration || 0), 0);
                return Math.round(total / b.items.length);
            });

            const data = {
                labels,
                datasets: [{
                    label: 'Avg Response Time (ms)',
                    data: values,
                    color: '#83a598',
                    fill: true
                }]
            };

            cm.createLineChart('response-time-chart', data, {
                scales: {
                    y: {
                        title: { display: true, text: 'Milliseconds' },
                        beginAtZero: true
                    }
                }
            });
        } catch (error) {
            console.error('Error loading response time chart:', error);
        }
    }

    async loadErrorRateChart() {
        try {
            const cm = window.chartManager;
            if (!cm) return;
            const buckets = this.bucketByMinute(this.recentLogs, 20);
            const labels = buckets.map(b => b.label);
            const values = buckets.map(b => {
                if (b.items.length === 0) return 0;
                const errors = b.items.filter(r => r.status === 'error').length;
                return parseFloat((errors / b.items.length * 100).toFixed(1));
            });

            const data = {
                labels,
                datasets: [{
                    label: 'Error Rate (%)',
                    data: values,
                    color: '#fb4934',
                    fill: true
                }]
            };

            cm.createLineChart('error-rate-chart', data, {
                scales: {
                    y: {
                        title: { display: true, text: 'Percentage' },
                        beginAtZero: true,
                        ticks: {
                            callback: function(value) { return value + '%'; }
                        }
                    }
                }
            });
        } catch (error) {
            console.error('Error loading error rate chart:', error);
        }
    }

    async loadRateLimitChart() {
        try {
            const cm = window.chartManager;
            if (!cm) return;
            // Show requests-per-client from recent logs
            const clientCounts = {};
            for (const log of this.recentLogs) {
                const client = log.client_id || 'unknown';
                clientCounts[client] = (clientCounts[client] || 0) + 1;
            }
            const sorted = Object.entries(clientCounts).sort((a, b) => b[1] - a[1]).slice(0, 8);
            const labels = sorted.map(([c]) => c.length > 16 ? c.substring(0, 14) + '...' : c);
            const values = sorted.map(([, v]) => v);

            const data = {
                labels: labels.length > 0 ? labels : ['No data'],
                datasets: [{
                    label: 'Requests by Client',
                    data: values.length > 0 ? values : [0],
                    color: '#8ec07c'
                }]
            };

            cm.createBarChart('rate-limit-chart', data, {
                scales: {
                    y: {
                        title: { display: true, text: 'Request Count' },
                        beginAtZero: true
                    }
                }
            });
        } catch (error) {
            console.error('Error loading rate limit chart:', error);
        }
    }

    /** Bucket log entries into N-minute-wide bins ending at now. */
    bucketByMinute(logs, count) {
        const now = Date.now();
        const buckets = Array.from({ length: count }, (_, i) => {
            const minutesAgo = count - 1 - i;
            return { label: minutesAgo === 0 ? 'now' : `${minutesAgo}m`, items: [], start: now - (minutesAgo + 1) * 60000, end: now - minutesAgo * 60000 };
        });
        for (const log of logs) {
            const ts = new Date(log.timestamp).getTime();
            for (const bucket of buckets) {
                if (ts >= bucket.start && ts < bucket.end) {
                    bucket.items.push(log);
                    break;
                }
            }
        }
        return buckets;
    }

    setupEventListeners() {
        // Pause/resume monitoring button
        const pauseBtn = document.getElementById('pause-monitoring');
        if (pauseBtn) {
            pauseBtn.addEventListener('click', () => {
                this.togglePause();
            });
        }
    }

    setupWebSocketSubscriptions() {
        if (!window.wsManager) return;
        
        // Subscribe to request updates
        window.wsManager.subscribe('requests', (request) => {
            if (!this.isPaused) {
                this.addToRequestStream(request);
            }
        });
        
        // Subscribe to log updates
        window.wsManager.subscribe('logs', (log) => {
            if (!this.isPaused) {
                this.addToLogStream(log);
            }
        });
        
        // Subscribe to metric updates
        window.wsManager.subscribe('metrics', (metric) => {
            if (!this.isPaused) {
                this.updateCharts(metric);
            }
        });
    }

    togglePause() {
        this.isPaused = !this.isPaused;
        const pauseBtn = document.getElementById('pause-monitoring');
        
        if (pauseBtn) {
            if (this.isPaused) {
                pauseBtn.innerHTML = '<i class="fas fa-play"></i> Resume';
                pauseBtn.classList.remove('btn-secondary');
                pauseBtn.classList.add('btn-success');
                
                if (window.authManager) {
                    window.authManager.showToast('Monitoring paused', 'warning');
                }
            } else {
                pauseBtn.innerHTML = '<i class="fas fa-pause"></i> Pause';
                pauseBtn.classList.remove('btn-success');
                pauseBtn.classList.add('btn-secondary');
                
                if (window.authManager) {
                    window.authManager.showToast('Monitoring resumed', 'success');
                }
            }
        }
    }

    addToRequestStream(request) {
        const streamElement = document.getElementById('request-stream');
        if (!streamElement) return;
        
        // Create entry
        const entry = document.createElement('div');
        entry.className = 'stream-entry';
        
        // Format time
        const time = new Date().toLocaleTimeString();
        
        // Determine icon based on status
        let icon = 'question-circle';
        let color = 'var(--text-secondary)';
        
        if (request.status === 'success') {
            icon = 'check-circle';
            color = 'var(--success)';
        } else if (request.status === 'error') {
            icon = 'exclamation-circle';
            color = 'var(--danger)';
        }
        
        entry.innerHTML = `
            <div class="stream-entry-time">${time}</div>
            <div class="stream-entry-icon" style="color: ${color}">
                <i class="fas fa-${icon}"></i>
            </div>
            <div class="stream-entry-content">
                <strong>${request.client_id || 'Unknown'}</strong> → 
                ${request.provider || 'Unknown'} (${request.model || 'Unknown'})
                <div class="stream-entry-details">
                    ${request.total_tokens || request.tokens || 0} tokens • ${request.duration_ms || request.duration || 0}ms
                </div>
            </div>
        `;
        
        // Add to top of stream
        streamElement.insertBefore(entry, streamElement.firstChild);
        
        // Store in memory (limit to 100)
        this.requestStream.unshift({
            time,
            request,
            element: entry
        });
        
        if (this.requestStream.length > 100) {
            const oldEntry = this.requestStream.pop();
            if (oldEntry.element.parentNode) {
                oldEntry.element.remove();
            }
        }
        
        // Add highlight animation
        entry.classList.add('highlight');
        setTimeout(() => entry.classList.remove('highlight'), 1000);
    }

    addToLogStream(log) {
        const logElement = document.getElementById('system-logs');
        if (!logElement) return;
        
        // Create entry
        const entry = document.createElement('div');
        entry.className = `log-entry log-${log.level || 'info'}`;
        
        // Format time
        const time = new Date().toLocaleTimeString();
        
        // Determine icon based on level
        let icon = 'info-circle';
        if (log.level === 'error') icon = 'exclamation-circle';
        if (log.level === 'warn') icon = 'exclamation-triangle';
        if (log.level === 'debug') icon = 'bug';
        
        entry.innerHTML = `
            <div class="log-time">${time}</div>
            <div class="log-level">
                <i class="fas fa-${icon}"></i>
            </div>
            <div class="log-message">${log.message || ''}</div>
        `;
        
        // Add to top of stream
        logElement.insertBefore(entry, logElement.firstChild);
        
        // Store in memory (limit to 100)
        this.systemLogs.unshift({
            time,
            log,
            element: entry
        });
        
        if (this.systemLogs.length > 100) {
            const oldEntry = this.systemLogs.pop();
            if (oldEntry.element.parentNode) {
                oldEntry.element.remove();
            }
        }
    }

    updateCharts(metric) {
        const cm = window.chartManager;
        if (!cm) return;
        // Update charts with new metric data
        if (metric.type === 'response_time' && cm.charts.has('response-time-chart')) {
            this.updateResponseTimeChart(metric.value);
        }
        
        if (metric.type === 'error_rate' && cm.charts.has('error-rate-chart')) {
            this.updateErrorRateChart(metric.value);
        }
    }

    updateResponseTimeChart(value) {
        if (window.chartManager) window.chartManager.addDataPoint('response-time-chart', value);
    }

    updateErrorRateChart(value) {
        if (window.chartManager) window.chartManager.addDataPoint('error-rate-chart', value);
    }

    startDemoUpdates() {
        // Demo updates disabled — real data comes via WebSocket subscriptions
    }

    simulateRequest() {
        const clients = ['client-1', 'client-2', 'client-3', 'client-4', 'client-5'];
        const providers = ['OpenAI', 'Gemini', 'DeepSeek', 'Grok'];
        const models = ['gpt-4o', 'gpt-4o-mini', 'gemini-2.0-flash', 'deepseek-chat', 'grok-4-1-fast-non-reasoning'];
        const statuses = ['success', 'success', 'success', 'error', 'warning']; // Mostly success
        
        const request = {
            client_id: clients[Math.floor(Math.random() * clients.length)],
            provider: providers[Math.floor(Math.random() * providers.length)],
            model: models[Math.floor(Math.random() * models.length)],
            tokens: Math.floor(Math.random() * 2000) + 100,
            duration: Math.floor(Math.random() * 1000) + 100,
            status: statuses[Math.floor(Math.random() * statuses.length)],
            timestamp: Date.now()
        };
        
        this.addToRequestStream(request);
    }

    simulateLog() {
        const levels = ['info', 'info', 'info', 'warn', 'error'];
        const messages = [
            'Request processed successfully',
            'Cache hit for model gpt-4',
            'Rate limit check passed',
            'High latency detected for DeepSeek provider',
            'API key validation failed',
            'Database connection pool healthy',
            'New client registered: client-7',
            'Backup completed successfully',
            'Memory usage above 80% threshold',
            'Provider Grok is offline'
        ];
        
        const log = {
            level: levels[Math.floor(Math.random() * levels.length)],
            message: messages[Math.floor(Math.random() * messages.length)],
            timestamp: Date.now()
        };
        
        this.addToLogStream(log);
    }

    simulateMetric() {
        const metricTypes = ['response_time', 'error_rate'];
        const type = metricTypes[Math.floor(Math.random() * metricTypes.length)];
        
        let value;
        if (type === 'response_time') {
            value = Math.floor(Math.random() * 200) + 300; // 300-500ms
        } else {
            value = Math.random() * 5; // 0-5%
        }
        
        this.updateCharts({ type, value });
    }

    clearStreams() {
        const streamElement = document.getElementById('request-stream');
        const logElement = document.getElementById('system-logs');
        
        if (streamElement) {
            streamElement.innerHTML = '';
            this.requestStream = [];
        }
        
        if (logElement) {
            logElement.innerHTML = '';
            this.systemLogs = [];
        }
    }

    refresh() {
        this.loadSystemMetrics();
        this.loadCharts();
        this.clearStreams();
        
        if (window.authManager) {
            window.authManager.showToast('Monitoring refreshed', 'success');
        }
    }
}

// Initialize monitoring page when needed
window.initMonitoring = async () => {
    window.monitoringPage = new MonitoringPage();
};

// Export for use in other modules
if (typeof module !== 'undefined' && module.exports) {
    module.exports = MonitoringPage;
}