import { Server } from "socket.io";
import type { Server as HttpServer } from "http";
import { allowedOrigins } from "../pkg/utils/corsController.js";
import { setupScheduler } from "./channels/scheduler.js";

export const setupIoServer = async (server: HttpServer, basePath: string) => {
    const io = new Server(server, {
        path: `${basePath}/api/ws`,
        cors: {
            // origin: ["http://localhost:5500"],
            origin: (origin, callback) => {
                // Allow non-browser clients (Postman, direct websocket, etc.)
                if (!origin) return callback(null, true);

                try {
                    // Check if origin matches any allowed string or regex
                    const allowed = allowedOrigins.some((o) => {
                        if (typeof o === "string") return o === origin;
                        if (o instanceof RegExp) return o.test(origin);
                        return false;
                    });

                    if (allowed) {
                        return callback(null, true);
                    }
                } catch (err) {
                    console.error("Invalid Origin header:", origin);
                }

                // Deny all others
                return callback(new Error("Not allowed by CORS: " + origin));
            },
            // methods: ["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"],
            credentials: true,
        },
        pingInterval: 25_000, // send ping every 25s (default 25s)
        pingTimeout: 60_000, // wait 60s before disconnecting (default 60s)
    });

    io.on("connection", (socket) => {
        console.log("🟢 User connected:", socket.id);

        // Join a room
        socket.on("joinRoom", (room: string) => {
            socket.join(room);
            console.log(`Socket ${socket.id} joined room ${room}`);
        });

        // Leave a room
        socket.on("leaveRoom", (room: string) => {
            socket.leave(room);
            console.log(`Socket ${socket.id} left room ${room}`);
        });

        // Example: broadcast a message to a room
        socket.on("message", ({ room, payload }) => {
            io.to(room).emit("message", payload);
        });

        socket.on("disconnect", (reason) => {
            console.log("🔴 User disconnected:", socket.id, reason);
        });

        setupScheduler(io, socket);
    });
};
