// socket.js
const { Server } = require("socket.io");

let io;

const NOTIFICATION_ROLES = ["admin", "manager", "Head"];

const initSocket = (server) => {
  if (!server) {
    console.error("❌ No server provided to initSocket");
    return;
  }

  io = new Server(server, {
    cors: { 
      origin: process.env.CLIENT_URL || "http://localhost:5173",
      credentials: true,
      methods: ["GET", "POST"],
    },
    allowEIO3: true,
    transports: ["polling", "websocket"],
  });

  io.use(async (socket, next) => {
    const { userId, role, orgId, userName } = socket.handshake.auth;
    
    console.log("🔐 Socket auth attempt:", { userId, role, orgId, userName });
    
    if (!userId) {
      console.warn("⚠️ Socket connection rejected: No userId");
      return next(new Error("Authentication error"));
    }
    
    socket.userId = userId;
    socket.role = role;
    socket.orgId = orgId;
    socket.userName = userName || `User-${userId}`;
    socket.joinTime = new Date().toISOString();
    next();
  });

  io.on("connection", (socket) => {
    console.log(`\n🔌 User connected: ${socket.userName} (${socket.role}) - ID: ${socket.id}`);
    console.log(`📊 Auth Data:`, {
      userId: socket.userId,
      role: socket.role,
      orgId: socket.orgId,
      userName: socket.userName,
      joinTime: socket.joinTime
    });
    
    // Join role-specific room
    if (socket.role) {
      socket.join(`role:${socket.role}`);
      console.log(`📢 User joined role:${socket.role} room`);
    }
    
    // Join organization room
    if (socket.orgId) {
      socket.join(`org:${socket.orgId}`);
      console.log(`🏢 User joined org:${socket.orgId} room`);
    }
    
    // Join PR approval recipients room if role matches
    const roleMatches = NOTIFICATION_ROLES.includes(socket.role);
    console.log(`🎯 Role ${socket.role} matches notification roles: ${roleMatches}`);
    
    if (roleMatches) {
      socket.join("pr-approval-recipients");
      const roomSize = io.sockets.adapter.rooms.get("pr-approval-recipients")?.size || 0;
      console.log(`✅ ${socket.userName} (${socket.role}) added to PR approval notifications room`);
      console.log(`📊 PR approval room size: ${roomSize}`);
      
      // Log all members in the room for debugging
      const roomMembers = io.sockets.adapter.rooms.get("pr-approval-recipients");
      if (roomMembers) {
        console.log(`👥 Current PR room members:`, Array.from(roomMembers));
      }
    } else {
      console.log(`❌ ${socket.role} NOT added to PR notifications`);
      console.log(`   Allowed roles: ${NOTIFICATION_ROLES.join(", ")}`);
    }
    
    // Debug endpoint - client can request room info
    socket.on("debug-room", () => {
      const prRoom = io.sockets.adapter.rooms.get("pr-approval-recipients");
      const roleRoom = socket.role ? io.sockets.adapter.rooms.get(`role:${socket.role}`) : null;
      
      socket.emit("debug-room-info", {
        isInPRRoom: socket.rooms.has("pr-approval-recipients"),
        prRoomSize: prRoom?.size || 0,
        roleRoomSize: roleRoom?.size || 0,
        role: socket.role,
        userId: socket.userId,
        socketId: socket.id,
        allRooms: Array.from(socket.rooms),
        notificationRoles: NOTIFICATION_ROLES
      });
    });
    
    // Test notification endpoint
    socket.on("test-notification", (data) => {
      console.log("🧪 Test notification requested:", data);
      const testData = {
        id: Date.now(),
        type: "TEST_NOTIFICATION",
        title: "🧪 Test Notification",
        message: `This is a test notification for ${socket.userName}`,
        pr_number: "TEST-001",
        pr_id: 999,
        requested_by: socket.userName,
        timestamp: new Date().toISOString()
      };
      socket.emit("pr_approved", testData);
      console.log("✅ Test notification sent to client");
    });
    
    socket.on("disconnect", (reason) => {
      console.log(`🔌 User disconnected: ${socket.userName} (${socket.userId}) - Reason: ${reason}`);
    });
    
    socket.on("error", (err) => {
      console.error(`❌ Socket error for ${socket.userName}:`, err);
    });
  });

  console.log("✅ Socket.io initialized successfully");
  return io;
};

const emitPRApproval = (requisition, approvedBy) => {
  if (!io) {
    console.warn("⚠️ Socket.io not initialized, notification not sent");
    return;
  }
  
  console.log(`\n📤 Attempting to send PR approval notification for: ${requisition.pr_number}`);
  console.log(`👤 Approved by: ${approvedBy}`);
  
  const notificationData = {
    id: Date.now(),
    type: "PR_APPROVED",
    title: "✅ Purchase Requisition Approved",
    message: `PR ${requisition.pr_number} has been approved for Purchase Order`,
    pr_number: requisition.pr_number,
    pr_id: requisition.id,
    requested_by: requisition.requested_by_name || requisition.requested_by,
    department: requisition.department || "Production",
    total_items: requisition.items?.length || 0,
    approved_by: approvedBy,
    timestamp: new Date().toISOString(),
    action_url: "/purchase-orders",
    action_tab: "waiting",
    priority: "high"
  };
  
  const prRoom = io.sockets.adapter.rooms.get("pr-approval-recipients");
  const roomSize = prRoom?.size || 0;
  
  console.log(`📊 PR approval room size: ${roomSize}`);
  
  if (roomSize === 0) {
    console.warn(`⚠️ No users in pr-approval-recipients room!`);
    console.log(`💡 Tip: Make sure a manager/admin is logged in with socket connected`);
  } else {
    console.log(`👥 Sending to room members:`, Array.from(prRoom));
  }
  
  // Emit to the room
  io.to("pr-approval-recipients").emit("pr_approved", notificationData);
  console.log(`📢 PR approval notification sent for ${requisition.pr_number} to ${roomSize} recipients`);
  
  // Also emit to role-specific rooms for redundancy
  for (const role of NOTIFICATION_ROLES) {
    io.to(`role:${role}`).emit("pr_approved", notificationData);
    console.log(`📢 Also sent to role:${role} room`);
  }
  
  return notificationData;
};

const getIO = () => {
  if (!io) {
    throw new Error("Socket.io not initialized");
  }
  return io;
};

// Helper function to get room stats
const getRoomStats = () => {
  if (!io) return null;
  
  const stats = {
    prApprovalRoom: {
      size: io.sockets.adapter.rooms.get("pr-approval-recipients")?.size || 0,
      members: Array.from(io.sockets.adapter.rooms.get("pr-approval-recipients") || [])
    },
    rooms: {}
  };
  
  for (const role of NOTIFICATION_ROLES) {
    const roleRoom = io.sockets.adapter.rooms.get(`role:${role}`);
    stats.rooms[`role:${role}`] = {
      size: roleRoom?.size || 0,
      members: Array.from(roleRoom || [])
    };
  }
  
  return stats;
};

module.exports = { initSocket, getIO, emitPRApproval, NOTIFICATION_ROLES, getRoomStats };