import type { Server } from "socket.io";
import { createLogger } from "../logger/logger.controller.js";
import {
	FLUSH_INTERVAL,
	MAX_HISTORY,
	roomBuffers,
	roomFlushTimers,
	roomHistory,
} from "./roomCache.socket.js";
import { roomDefinition } from "./roomDefinitions.socket.js";
import type { RoomId } from "./types.socket.js";

// get the db data if not exiting already
const log = createLogger({ module: "socket.io", subModule: "roomService" });

export const preseedRoom = async (roomId: RoomId) => {
	if (roomHistory.has(roomId)) {
		return roomHistory.get(roomId);
	}

	const roomDef = roomDefinition[roomId];

	if (!roomDef) {
		log.error({}, `Room ${roomId} is not defined`);
	}

	const latestData = await roomDef.seed(MAX_HISTORY);

	roomHistory.set(roomId, latestData);

	return latestData;
};

export const createRoomEmitter = (io: Server) => {
	const addDataToRoom = <T>(roomId: RoomId, payload: T) => {
		if (!roomHistory.has(roomId)) {
			roomHistory.set(roomId, []);
		}

		const history = roomHistory.get(roomId)!;
		history?.push(payload);

		if (history?.length > MAX_HISTORY) {
			history?.shift();
		}

		if (!roomBuffers.has(roomId)) {
			roomBuffers.set(roomId, []);
		}

		roomBuffers.get(roomId)!.push(payload);

		if (!roomFlushTimers.has(roomId)) {
			const timer = setTimeout(() => {
				const buffered = roomBuffers.get(roomId) || [];

				if (buffered.length > 0) {
					io.to(roomId).emit("room-update", {
						roomId,
						payloads: buffered, // ✅ array now
					});
				}

				roomBuffers.set(roomId, []);
				roomFlushTimers.delete(roomId);
			}, FLUSH_INTERVAL);

			roomFlushTimers.set(roomId, timer);
		}
	};

	return { addDataToRoom };
};
