/**
 * Socket.io Real-time Handlers
 * Provides Socket.io event handlers for activity feed and revenue forecast streaming
 */

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

/**
 * Register Socket.io handlers for activity feed and forecasting
 */
export function registerSocketIOHandlers(io: SocketIOServer) {
  // Activity Feed Namespace
  const activityNamespace = io.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 = io.of('/revenue-forecast');

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

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

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

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

/**
 * Broadcast activity event to subscribed clients
 */
export function broadcastActivityEvent(
  io: SocketIOServer,
  data: {
    userId?: number;
    campaignId?: string;
    eventType: string;
    timestamp: Date;
    details: any;
  }
) {
  const activity = {
    ...data,
    timestamp: data.timestamp.toISOString(),
  };

  const activityNamespace = io.of('/activity-feed');

  // Broadcast to specific user
  if (data.userId) {
    activityNamespace.to(`user-${data.userId}`).emit('activity', activity);
  }

  // Broadcast to specific campaign
  if (data.campaignId) {
    activityNamespace.to(`campaign-${data.campaignId}`).emit('activity', activity);
  }

  // Broadcast to all connected clients
  activityNamespace.emit('activity', activity);
}

/**
 * Broadcast activity metrics update
 */
export function broadcastActivityMetrics(
  io: SocketIOServer,
  metrics: {
    timestamp: Date;
    logins: number;
    deposits: number;
    withdrawals: number;
    wins: number;
    gamePlays: number;
    totalRevenue: number;
  }
) {
  io.of('/activity-feed').emit('metrics-update', {
    ...metrics,
    timestamp: metrics.timestamp.toISOString(),
  });
}

/**
 * Broadcast revenue forecast update
 */
export function broadcastForecastUpdate(
  io: SocketIOServer,
  data: {
    modelType: string;
    forecastDate: Date;
    forecastedRevenue: number;
    confidenceHigh: number;
    confidenceLow: number;
    trend: string;
    accuracy: number;
  }
) {
  const forecast = {
    ...data,
    forecastDate: data.forecastDate.toISOString(),
  };

  const forecastNamespace = io.of('/revenue-forecast');

  // Broadcast to specific model type
  forecastNamespace.to(`forecast-${data.modelType}`).emit('forecast-update', forecast);

  // Broadcast to all forecast subscribers
  forecastNamespace.emit('forecast-update', forecast);
}

/**
 * Broadcast revenue metrics update
 */
export function broadcastRevenueMetrics(
  io: SocketIOServer,
  metrics: {
    source: string;
    revenue: number;
    percentage: number;
    forecast: number;
  }
) {
  io.of('/revenue-forecast').emit('revenue-metrics', metrics);
}

/**
 * Broadcast campaign status change
 */
export function broadcastCampaignStatusChange(
  io: SocketIOServer,
  data: {
    campaignId: number;
    status: string;
    message?: string;
  }
) {
  io.of('/activity-feed')
    .to(`campaign-${data.campaignId}`)
    .emit('campaign-status-change', data);
}

/**
 * Broadcast campaign performance update
 */
export function broadcastCampaignPerformance(
  io: SocketIOServer,
  data: {
    campaignId: number;
    channel: string;
    sent: number;
    opened: number;
    clicked: number;
    converted: number;
    revenue: number;
  }
) {
  io.of('/activity-feed')
    .to(`campaign-${data.campaignId}`)
    .emit('campaign-performance', data);
}

/**
 * Broadcast forecast insights
 */
export function broadcastForecastInsights(
  io: SocketIOServer,
  insights: Array<{
    insightType: string;
    title: string;
    description: string;
    recommendation: string;
    priority: string;
  }>
) {
  io.of('/revenue-forecast').emit('forecast-insights', insights);
}

/**
 * Broadcast model retraining status
 */
export function broadcastModelRetrainingStatus(
  io: SocketIOServer,
  data: {
    modelType: string;
    status: 'started' | 'in_progress' | 'completed' | 'failed';
    progress?: number;
    message?: string;
  }
) {
  io.of('/revenue-forecast').emit('model-retraining', data);
}
