import express from 'express';
import { createServer } from 'http';
import { Server as SocketIOServer } from 'socket.io';
import cors from 'cors';
import path from 'path';
import { fileURLToPath } from 'url';
import { setupMetricsAPI } from './api/metrics.js';
import { setupAgileAPI } from './api/agile.js';
import { setupSecurityAPI } from './api/security.js';
import { setupErrorsAPI } from './api/errors.js';
import { setupWebSocketHandlers } from './utils/websocket.js';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
export class DashboardServer {
    performanceMonitor;
    securityManager;
    errorHandler;
    agileManager;
    app;
    server;
    io;
    config;
    isRunning = false;
    constructor(config, performanceMonitor, securityManager, errorHandler, agileManager) {
        this.performanceMonitor = performanceMonitor;
        this.securityManager = securityManager;
        this.errorHandler = errorHandler;
        this.agileManager = agileManager;
        this.config = config;
        this.app = express();
        this.server = createServer(this.app);
        this.io = new SocketIOServer(this.server, {
            cors: {
                origin: `http://${config.host}:${config.port}`,
                methods: ['GET', 'POST']
            }
        });
        this.setupMiddleware();
        this.setupRoutes();
        this.setupStaticFiles();
        this.setupWebSocket();
    }
    setupMiddleware() {
        this.app.use(cors());
        this.app.use(express.json());
        this.app.use(express.urlencoded({ extended: true }));
        // Request logging middleware - only log errors
        this.app.use((req, res, next) => {
            // Store the original res.json to intercept responses
            const originalJson = res.json;
            res.json = function (data) {
                // Only log if there's an error or non-2xx status
                if (res.statusCode >= 400 || (data && data.error)) {
                    console.error(`📊 Dashboard API Error: ${req.method} ${req.path} - Status: ${res.statusCode}`);
                }
                return originalJson.call(this, data);
            };
            next();
        });
    }
    setupStaticFiles() {
        // Serve static files from public directory
        const publicPath = path.join(__dirname, 'public');
        this.app.use(express.static(publicPath));
        // Serve main dashboard page
        this.app.get('/', (req, res) => {
            res.sendFile(path.join(publicPath, 'index.html'));
        });
    }
    setupRoutes() {
        // API Routes
        if (this.config.features.performance) {
            setupMetricsAPI(this.app, this.performanceMonitor, this.config.exportEnabled);
        }
        if (this.config.features.agile && this.agileManager) {
            setupAgileAPI(this.app, this.agileManager);
        }
        if (this.config.features.security) {
            setupSecurityAPI(this.app, this.securityManager);
        }
        if (this.config.features.errors) {
            setupErrorsAPI(this.app, this.errorHandler);
        }
        // Health check endpoint
        this.app.get('/api/health', (req, res) => {
            res.json({
                status: 'healthy',
                timestamp: new Date().toISOString(),
                features: this.config.features,
                version: process.env.npm_package_version || '1.0.0'
            });
        });
        // 404 handler for API routes
        this.app.use('/api/*', (req, res) => {
            res.status(404).json({
                error: 'API endpoint not found',
                path: req.path,
                method: req.method
            });
        });
    }
    setupWebSocket() {
        if (this.config.realTimeUpdates) {
            setupWebSocketHandlers(this.io, this.performanceMonitor, this.securityManager, this.errorHandler, this.agileManager);
        }
    }
    async start() {
        if (this.isRunning) {
            console.error('📊 Dashboard server is already running');
            return;
        }
        return new Promise((resolve, reject) => {
            this.server.listen(this.config.port, this.config.host, () => {
                this.isRunning = true;
                const url = `http://${this.config.host}:${this.config.port}`;
                console.error(`📊 Atlas Dashboard available at ${url}`);
                if (this.config.realTimeUpdates) {
                    console.error('📡 Real-time updates enabled via WebSocket');
                }
                // Start real-time data collection
                this.startDataCollection();
                resolve();
            });
            this.server.on('error', (error) => {
                if (error.code === 'EADDRINUSE') {
                    console.error(`❌ Dashboard port ${this.config.port} is already in use`);
                    console.error(`💡 Try changing the port in your Atlas configuration`);
                }
                else {
                    console.error(`❌ Dashboard server error:`, error.message);
                }
                reject(error);
            });
        });
    }
    async stop() {
        if (!this.isRunning) {
            return;
        }
        return new Promise((resolve) => {
            this.stopDataCollection();
            // Close all socket.io connections first
            this.io.close(() => {
                // Then close the HTTP server
                this.server.close(() => {
                    this.isRunning = false;
                    console.error('📊 Dashboard server stopped');
                    resolve();
                });
            });
            // Force close any remaining connections after a timeout
            setTimeout(() => {
                this.server.closeAllConnections?.();
                resolve();
            }, 1000);
        });
    }
    dataCollectionInterval;
    startDataCollection() {
        if (!this.config.realTimeUpdates) {
            return;
        }
        // Collect and broadcast data every 5 seconds
        this.dataCollectionInterval = setInterval(async () => {
            try {
                // Broadcast performance metrics
                if (this.config.features.performance) {
                    const metrics = await this.performanceMonitor.getSystemMetrics();
                    this.io.emit('performance_update', {
                        timestamp: new Date().toISOString(),
                        metrics
                    });
                }
                // Broadcast security status
                if (this.config.features.security) {
                    const securityStatus = await this.securityManager.getSecurityStatus();
                    this.io.emit('security_update', {
                        timestamp: new Date().toISOString(),
                        status: securityStatus
                    });
                }
                // Broadcast error patterns (less frequent - every 30 seconds)
                if (this.config.features.errors && Math.random() < 0.16) { // ~1/6 chance = every 30s
                    const errorPatterns = await this.errorHandler.analyzeErrorPatterns({
                        timeRange: '1h',
                        minOccurrences: 1,
                        groupBy: 'type'
                    });
                    this.io.emit('errors_update', {
                        timestamp: new Date().toISOString(),
                        patterns: errorPatterns
                    });
                }
            }
            catch (error) {
                console.error('📊 Dashboard data collection error:', error);
            }
        }, 5000);
    }
    stopDataCollection() {
        if (this.dataCollectionInterval) {
            clearInterval(this.dataCollectionInterval);
            this.dataCollectionInterval = undefined;
        }
    }
    getUrl() {
        return `http://${this.config.host}:${this.config.port}`;
    }
    isHealthy() {
        return this.isRunning;
    }
    getConfig() {
        return { ...this.config };
    }
}
//# sourceMappingURL=server.js.map