const jwt = require('jsonwebtoken');

// WebSocket authentication middleware
const authenticateSocket = (socket, next) => {
  try {
    const token = socket.handshake.auth.token || socket.handshake.headers.authorization?.split(' ')[1];
    
    if (!token) {
      return next(new Error('Authentication token required'));
    }

    const jwtSecret = process.env.JWT_ACCESS_SECRET || process.env.JWT_SECRET;
    if (!jwtSecret) {
      console.error('WebSocket authentication failed: JWT secret not configured');
      return next(new Error('Authentication failed'));
    }

    const decoded = jwt.verify(token, jwtSecret);
    socket.user = decoded;
    socket.userId = decoded.id || decoded.userId;
    
    console.log(`✅ WebSocket authenticated: ${socket.user.email || socket.userId}`);
    next();
  } catch (error) {
    console.error('WebSocket authentication failed:', error.message);
    next(new Error('Authentication failed'));
  }
};

// WebSocket connection handler with authentication
const handleWebSocketConnections = (io) => {
  // Authentication middleware for all connections
  io.use(authenticateSocket);
  
  io.on('connection', (socket) => {
    console.log(`🔌 Client connected: ${socket.id} (User: ${socket.user.email || socket.userId})`);
    
    // Join user-specific room
    const userRoom = `user_${socket.userId}`;
    socket.join(userRoom);
    
    // Send connection confirmation
    socket.emit('connected', {
      message: 'Connected to CodeNuk API Gateway',
      timestamp: new Date().toISOString(),
      socketId: socket.id,
      user: {
        id: socket.userId,
        email: socket.user.email,
        role: socket.user.role
      }
    });

    // Handle service-specific events
    socket.on('subscribe_to_service', (data) => {
      const { service } = data;
      const serviceRoom = `service_${service}`;
      socket.join(serviceRoom);
      
      console.log(`📡 User ${socket.userId} subscribed to ${service} updates`);
      socket.emit('subscribed', { service, room: serviceRoom });
    });

    socket.on('unsubscribe_from_service', (data) => {
      const { service } = data;
      const serviceRoom = `service_${service}`;
      socket.leave(serviceRoom);
      
      console.log(`📡 User ${socket.userId} unsubscribed from ${service} updates`);
      socket.emit('unsubscribed', { service, room: serviceRoom });
    });

    // Handle project-specific events
    socket.on('join_project', (data) => {
      const { projectId } = data;
      const projectRoom = `project_${projectId}`;
      socket.join(projectRoom);
      
      console.log(`📁 User ${socket.userId} joined project ${projectId}`);
      socket.emit('joined_project', { projectId, room: projectRoom });
    });

    socket.on('leave_project', (data) => {
      const { projectId } = data;
      const projectRoom = `project_${projectId}`;
      socket.leave(projectRoom);
      
      console.log(`📁 User ${socket.userId} left project ${projectId}`);
      socket.emit('left_project', { projectId, room: projectRoom });
    });

    // Handle real-time notifications
    socket.on('send_notification', (data) => {
      const { targetUserId, message, type } = data;
      const targetRoom = `user_${targetUserId}`;
      
      io.to(targetRoom).emit('notification', {
        from: socket.userId,
        message,
        type,
        timestamp: new Date().toISOString()
      });
      
      console.log(`📢 Notification sent from ${socket.userId} to ${targetUserId}`);
    });

    // Handle disconnection
    socket.on('disconnect', (reason) => {
      console.log(`🔌 Client disconnected: ${socket.id} (User: ${socket.user.email || socket.userId}) - Reason: ${reason}`);
    });

    // Handle errors
    socket.on('error', (error) => {
      console.error(`❌ Socket error for ${socket.id}:`, error);
    });
  });

  // Broadcast service status updates
  const broadcastServiceUpdate = (serviceName, status) => {
    io.to(`service_${serviceName}`).emit('service_status_update', {
      service: serviceName,
      status,
      timestamp: new Date().toISOString()
    });
  };

  // Broadcast project updates
  const broadcastProjectUpdate = (projectId, update) => {
    io.to(`project_${projectId}`).emit('project_update', {
      projectId,
      update,
      timestamp: new Date().toISOString()
    });
  };

  return {
    broadcastServiceUpdate,
    broadcastProjectUpdate
  };
};

module.exports = handleWebSocketConnections;
