const express = require('express');
const { ok } = require('../src/utils/responses');

/**
 * Server-Sent Events route factory
 * Pushes real-time updates to connected dashboard clients
 * @param {Object} deps - Dependencies
 * @param {Object} deps.resourceMonitor - Container resource monitor
 * @param {Object} deps.healthChecker - Health checker
 * @param {Object} deps.updateManager - Update manager
 * @param {Function} deps.logError - Error logging function
 * @param {Object} deps.dependencyManager - Dependency manager for restart chain events
 * @param {Object} deps.autoRestartManager - Auto-restart manager
 * @param {Object} deps.driftDetector - Config drift detector
 * @param {Object} deps.sslMonitor - SSL cert expiration monitor
 * @param {Object} deps.dnsPropagationChecker - DNS propagation checker
 * @returns {express.Router}
 */
module.exports = function({ resourceMonitor, healthChecker, updateManager, logError, dependencyManager, autoRestartManager, driftDetector, sslMonitor, dnsPropagationChecker }) {
  const router = express.Router();
  const clients = new Set();

  function broadcast(event, data) {
    const msg = `event: ${event}\ndata: ${JSON.stringify(data)}\n\n`;
    for (const res of clients) {
      try { res.write(msg); } catch (_) { clients.delete(res); }
    }
  }

  // --- Wire up EventEmitter listeners ---

  // Resource monitor events
  if (resourceMonitor) {
    resourceMonitor.on('alert', (data) => {
      broadcast('resource-alert', data);
    });
    resourceMonitor.on('auto-restart', (data) => {
      broadcast('auto-restart', data);
    });
  }

  // Health checker events
  if (healthChecker) {
    healthChecker.on('status-check', (data) => {
      broadcast('status-change', {
        serviceId: data.serviceId,
        name: data.name,
        status: data.status,
        responseTime: data.responseTime,
        timestamp: data.timestamp
      });
    });
    healthChecker.on('incident-created', (data) => {
      broadcast('incident', { type: 'created', ...data });
    });
    healthChecker.on('incident-resolved', (data) => {
      broadcast('incident', { type: 'resolved', ...data });
    });
  }

  // Update manager events
  if (updateManager) {
    updateManager.on('update-available', (data) => {
      broadcast('update-available', data);
    });
    updateManager.on('update-start', (data) => {
      broadcast('update-start', data);
    });
    updateManager.on('update-complete', (data) => {
      broadcast('update-complete', data);
    });
    updateManager.on('update-failed', (data) => {
      broadcast('update-failed', data);
    });
    updateManager.on('auto-update-start', (data) => {
      broadcast('auto-update-start', data);
    });
    updateManager.on('auto-update-complete', (data) => {
      broadcast('auto-update-complete', data);
    });
  }

  // Dependency manager events
  if (dependencyManager) {
    dependencyManager.on('dependency-restart-start', (data) => {
      broadcast('dependency-restart-start', data);
    });
    dependencyManager.on('dependency-restart-progress', (data) => {
      broadcast('dependency-restart-progress', data);
    });
    dependencyManager.on('dependency-restart-complete', (data) => {
      broadcast('dependency-restart-complete', data);
    });
    dependencyManager.on('dependency-restart-failed', (data) => {
      broadcast('dependency-restart-failed', data);
    });
  }

  // Auto-restart manager events
  if (autoRestartManager) {
    autoRestartManager.on('auto-restart-attempt', (data) => broadcast('auto-restart-attempt', data));
    autoRestartManager.on('auto-restart-success', (data) => broadcast('auto-restart-success', data));
    autoRestartManager.on('auto-restart-failed', (data) => broadcast('auto-restart-failed', data));
    autoRestartManager.on('auto-restart-max-reached', (data) => broadcast('auto-restart-max-reached', data));
  }

  // Config drift detector events
  if (driftDetector) {
    driftDetector.on('drift-detected', (data) => broadcast('drift-detected', data));
  }

  // SSL monitor events
  if (sslMonitor) {
    sslMonitor.on('cert-expiring', (data) => broadcast('cert-expiring', data));
    sslMonitor.on('cert-critical', (data) => broadcast('cert-critical', data));
  }

  // DNS propagation checker events
  if (dnsPropagationChecker) {
    dnsPropagationChecker.on('propagation-check', (data) => broadcast('dns-propagation-check', data));
    dnsPropagationChecker.on('propagation-complete', (data) => broadcast('dns-propagation-complete', data));
    dnsPropagationChecker.on('propagation-timeout', (data) => broadcast('dns-propagation-timeout', data));
  }

  // SSE endpoint
  router.get('/stream', (req, res) => {
    res.writeHead(200, {
      'Content-Type': 'text/event-stream',
      'Cache-Control': 'no-cache',
      'Connection': 'keep-alive',
      'X-Accel-Buffering': 'no',
    });

    // Send initial connected event
    res.write(`event: connected\ndata: ${JSON.stringify({ clients: clients.size + 1 })}\n\n`);

    clients.add(res);

    // Heartbeat every 30s
    const heartbeat = setInterval(() => {
      try { res.write(': heartbeat\n\n'); } catch (_) { cleanup(); }
    }, 30000);

    function cleanup() {
      clearInterval(heartbeat);
      clients.delete(res);
    }

    req.on('close', cleanup);
    req.on('error', cleanup);
  });

  // Client count (useful for debugging)
  router.get('/clients', (req, res) => {
    ok(res, { count: clients.size });
  });

  return router;
};
