/**
 * Room Management for Socket.io
 *
 * Manages room subscriptions for targeted event delivery.
 */

import type { RoomType, TransparencyEventType } from './types';
import { EventCategory, getEventCategory } from './events';

/**
 * Parse a room type to extract its components
 */
export function parseRoom(room: RoomType): { type: string; id?: string } {
  if (room.includes(':')) {
    const [type, id] = room.split(':');
    return { type, id };
  }
  return { type: room };
}

/**
 * Create a room name for a specific entity
 */
export function createRoom(type: 'plant' | 'farm' | 'user', id: string): RoomType {
  return `${type}:${id}` as RoomType;
}

/**
 * Get the default rooms for a user based on their role
 */
export function getDefaultRooms(userId?: string): RoomType[] {
  const rooms: RoomType[] = ['global'];
  if (userId) {
    rooms.push(`user:${userId}` as RoomType);
  }
  return rooms;
}

/**
 * Get category-based room for an event type
 */
export function getCategoryRoom(type: TransparencyEventType): RoomType {
  const category = getEventCategory(type);

  switch (category) {
    case EventCategory.PLANT:
      return 'plants';
    case EventCategory.TRANSPORT:
      return 'transport';
    case EventCategory.FARM:
      return 'farms';
    case EventCategory.DEMAND:
      return 'demand';
    case EventCategory.SYSTEM:
    case EventCategory.AGENT:
    case EventCategory.BLOCKCHAIN:
    case EventCategory.AUDIT:
      return 'system';
    default:
      return 'global';
  }
}

/**
 * Determine which rooms should receive an event
 */
export function getEventRooms(
  type: TransparencyEventType,
  data: Record<string, unknown>
): RoomType[] {
  const rooms: RoomType[] = ['global'];

  // Add category room
  const categoryRoom = getCategoryRoom(type);
  if (categoryRoom !== 'global') {
    rooms.push(categoryRoom);
  }

  // Add entity-specific rooms
  if (data.plantId && typeof data.plantId === 'string') {
    rooms.push(`plant:${data.plantId}` as RoomType);
  }
  if (data.farmId && typeof data.farmId === 'string') {
    rooms.push(`farm:${data.farmId}` as RoomType);
  }
  if (data.userId && typeof data.userId === 'string') {
    rooms.push(`user:${data.userId}` as RoomType);
  }

  return rooms;
}

/**
 * Check if a room is valid
 */
export function isValidRoom(room: string): room is RoomType {
  const validPrefixes = ['global', 'plants', 'transport', 'farms', 'demand', 'system'];
  const validEntityPrefixes = ['plant:', 'farm:', 'user:'];

  if (validPrefixes.includes(room)) {
    return true;
  }

  return validEntityPrefixes.some((prefix) => room.startsWith(prefix));
}

/**
 * Room subscription limits per connection
 */
export const ROOM_LIMITS = {
  maxRooms: 50,
  maxEntityRooms: 20,
  maxGlobalRooms: 10,
};

/**
 * Check if a connection can join another room
 */
export function canJoinRoom(currentRooms: RoomType[], newRoom: RoomType): boolean {
  if (currentRooms.length >= ROOM_LIMITS.maxRooms) {
    return false;
  }

  const parsed = parseRoom(newRoom);
  const entityRooms = currentRooms.filter((r) => r.includes(':')).length;
  const globalRooms = currentRooms.filter((r) => !r.includes(':')).length;

  if (parsed.id && entityRooms >= ROOM_LIMITS.maxEntityRooms) {
    return false;
  }

  if (!parsed.id && globalRooms >= ROOM_LIMITS.maxGlobalRooms) {
    return false;
  }

  return true;
}
