/**
 * Cross-namespace emit helpers.
 *
 * Customers and agents live in separate namespaces, so "tell everyone in this
 * conversation" is two emits. Centralising that here means no handler can
 * accidentally deliver an agent-only payload (a note, enrichment data) to a
 * customer socket.
 */
import type { Namespace, Server } from 'socket.io';
import { NS, ROOM, S2C } from './events.js';

let ioRef: Server | null = null;

export function registerIo(io: Server) {
  ioRef = io;
}

export function io(): Server {
  if (!ioRef) throw new Error('Socket.IO server has not been initialised yet');
  return ioRef;
}

export const customerNs = (): Namespace => io().of(NS.customer);
export const agentNs = (): Namespace => io().of(NS.agent);

/** Emit to both sides of a conversation. */
export function toConversation(conversationId: string, event: string, payload: unknown) {
  const room = ROOM.conversation(conversationId);
  customerNs().to(room).emit(event, payload);
  agentNs().to(room).emit(event, payload);
}

/** Emit only to the customer side of a conversation. */
export function toCustomer(conversationId: string, event: string, payload: unknown) {
  customerNs().to(ROOM.conversation(conversationId)).emit(event, payload);
}

/** Emit only to agents watching a conversation. */
export function toConversationAgents(conversationId: string, event: string, payload: unknown) {
  agentNs().to(ROOM.conversation(conversationId)).emit(event, payload);
}

/** Emit to every signed-in agent (queue + presence fan-out). */
export function toAgentLobby(event: string, payload: unknown) {
  agentNs().to(ROOM.agentLobby).emit(event, payload);
}

/** Emit to every socket belonging to one agent (all their open tabs). */
export function toAgent(agentId: string, event: string, payload: unknown) {
  agentNs().to(ROOM.agent(agentId)).emit(event, payload);
}

export { S2C };
