import { Server } from "socket.io";

let io: Server;

export function initWebSocket() {
  if (io) return;

  io = new Server({ cors: { origin: "*" }, path: "/api/v1/org-socket" });

  io.use(async (socket, next) => {
    const token = socket.handshake.auth.token;

    const res = await fetch(`${process.env.AUTH_REALM_URL}/protocol/openid-connect/userinfo`, {
      headers: { authorization: `Bearer ${token}` },
    }).catch((e) => console.error(e));

    if (res?.ok) {
      socket.data.user = await res.json();
    }

    next();
  });

  io.on("connection", (ws) => {
    // console.log("✅ Client connected to WebSocket");

    ws.on("close", () => {
      console.log("❌ Client disconnected");
    });

    ws.on("error", (error: any) => {
      console.error("WebSocket error:", error);
    });
  });

  io.listen(13002);
}

export async function sendWebSocket(
  event: string,
  data: any,
  opts?: {
    roles?: string | string[];
    userId?: string | string[];
  },
) {
  if (!io) initWebSocket();
  // console.log( `🔔 <Message>:`,data.message);

  for (let [id, session] of io.of("/").sockets) {
    const user: {
      sub: string;
      name: string;
      given_name: string;
      family_name: string;
      preferred_username: string;
      email: string;
      role: string[];
    } = session.data.user;

    if (!user) continue;

    if (typeof opts?.roles === "string") opts.roles = [opts.roles];
    if (typeof opts?.userId === "string") opts.userId = [opts.userId];

    if (
      user.role?.some((v) => opts?.roles?.includes(v)) ||
      opts?.userId?.some((v) => user.sub === v)
    ) {
      io.to(id).emit(event, JSON.stringify(data));
    }
  }
}
