/**
 * Socket.io Integration for Express Server
 * Initializes Socket.io with real-time handlers for activity feed and revenue forecasting
 */

import { Server as HTTPServer } from 'http';
import { Server as SocketIOServer, Socket } from 'socket.io';

let io: SocketIOServer | null = null;

/**
 * Register Socket.io handlers for activity feed and forecasting
 */
function registerSocketIOHandlers(ioServer: SocketIOServer) {
  // Activity Feed Namespace
  const activityNamespace = ioServer.of('/activity-feed');

  activityNamespace.on('connection', (socket: Socket) => {
    console.log(`[Socket.io] Activity feed client connected: ${socket.id}`);

    socket.on('subscribe', (data: { campaignId?: string; userId?: string }) => {
      if (data.campaignId) {
        socket.join(`campaign-${data.campaignId}`);
        console.log(`[Socket.io] Client ${socket.id} subscribed to campaign ${data.campaignId}`);
      }
      if (data.userId) {
        socket.join(`user-${data.userId}`);
        console.log(`[Socket.io] Client ${socket.id} subscribed to user ${data.userId}`);
      }
      socket.emit('subscribed', { success: true });
    });

    socket.on('unsubscribe', (data: { campaignId?: string; userId?: string }) => {
      if (data.campaignId) {
        socket.leave(`campaign-${data.campaignId}`);
      }
      if (data.userId) {
        socket.leave(`user-${data.userId}`);
      }
      socket.emit('unsubscribed', { success: true });
    });

    socket.on('disconnect', () => {
      console.log(`[Socket.io] Activity feed client disconnected: ${socket.id}`);
    });
  });

  // Revenue Forecast Namespace
  const forecastNamespace = ioServer.of('/revenue-forecast');

  forecastNamespace.on('connection', (socket: Socket) => {
    console.log(`[Socket.io] Revenue forecast client connected: ${socket.id}`);

    socket.on('subscribe', (data: { metricType?: string; timeRange?: string }) => {
      if (data.metricType) {
        socket.join(`metric-${data.metricType}`);
        console.log(`[Socket.io] Client ${socket.id} subscribed to metric ${data.metricType}`);
      }
      socket.emit('subscribed', { success: true });
    });

    socket.on('unsubscribe', (data: { metricType?: string }) => {
      if (data.metricType) {
        socket.leave(`metric-${data.metricType}`);
      }
      socket.emit('unsubscribed', { success: true });
    });

    socket.on('disconnect', () => {
      console.log(`[Socket.io] Revenue forecast client disconnected: ${socket.id}`);
    });
  });

  console.log('[Socket.io] Handlers registered for activity-feed and revenue-forecast namespaces');
}

/**
 * Initialize Socket.io server with Express HTTP server
 */
export function initializeSocketIO(httpServer: HTTPServer): SocketIOServer {
  io = new SocketIOServer(httpServer, {
    cors: {
      origin: process.env.VITE_OAUTH_PORTAL_URL || '*',
      methods: ['GET', 'POST'],
      credentials: true,
    },
    transports: ['websocket', 'polling'],
    pingInterval: 25000,
    pingTimeout: 60000,
  });

  // Register all Socket.io event handlers
  registerSocketIOHandlers(io);

  console.log('[Socket.io] Server initialized successfully');
  return io;
}

/**
 * Get Socket.io server instance
 */
export function getSocketIOInstance(): SocketIOServer | null {
  return io;
}

/**
 * Disconnect all Socket.io clients (for graceful shutdown)
 */
export function disconnectAllSocketIOClients() {
  if (!io) return;

  io.of('/activity-feed').disconnectSockets();
  io.of('/revenue-forecast').disconnectSockets();

  console.log('[Socket.io] All clients disconnected');
}

/**
 * Get Socket.io connection statistics
 */
export function getSocketIOStats() {
  if (!io) {
    return {
      activityFeedConnections: 0,
      revenueForecastConnections: 0,
      totalConnections: 0,
    };
  }

  const activityFeedConnections = io.of('/activity-feed').sockets.size;
  const revenueForecastConnections = io.of('/revenue-forecast').sockets.size;

  return {
    activityFeedConnections,
    revenueForecastConnections,
    totalConnections: activityFeedConnections + revenueForecastConnections,
  };
}
