import { Router } from 'express';
import { checkSocialEnabled } from './social.middleware';
import { requireRole } from '../../middleware/rbac.middleware';
import { SOCIAL_ROLES } from '../../utils/roles';
import { sseService } from './sse.service';
import { presenceService } from './presence.service';

const MAX_SSE_CONNECTIONS_PER_USER = 5;

const router = Router();

router.use(checkSocialEnabled);

/** GET /api/social/sse — establish SSE connection */
router.get('/', (req, res) => {
  const userId = req.user!.id;

  // Enforce per-user connection limit to prevent resource exhaustion
  const existingCount = sseService.getConnectionCountForUser?.(userId) ?? 0;
  if (existingCount >= MAX_SSE_CONNECTIONS_PER_USER) {
    res.status(429).json({ error: { message: 'Too many SSE connections', code: 'TOO_MANY_CONNECTIONS' } });
    return;
  }

  // Set SSE headers
  res.writeHead(200, {
    'Content-Type': 'text/event-stream',
    'Cache-Control': 'no-cache',
    'Connection': 'keep-alive',
    'X-Accel-Buffering': 'no', // Disable nginx buffering
  });

  // Send initial connection event
  res.write(`event: connected\ndata: ${JSON.stringify({ userId })}\n\n`);

  // Register client
  const connectionId = sseService.addClient(userId, res);

  // Set user as online
  presenceService.setOnline(userId).catch(() => {});

  // Handle client disconnect
  req.on('close', () => {
    sseService.removeClient(connectionId);
    // Only set offline if no more connections for this user
    if (!sseService.isConnected(userId)) {
      presenceService.setOffline(userId).catch(() => {});
    }
  });
});

/** GET /api/social/sse/online-friends — get currently online friends */
router.get('/online-friends', async (req, res, next) => {
  try {
    const friends = await presenceService.getOnlineFriends(req.user!.id);
    res.json({ friends });
  } catch (err) {
    next(err);
  }
});

/** GET /api/social/sse/status — SSE service status (admin only) */
router.get('/status', requireRole(...SOCIAL_ROLES), (_req, res) => {
  res.json({
    connections: sseService.getConnectionCount(),
    connectedUsers: sseService.getConnectedUserIds().length,
  });
});

export const sseRouter = router;
