import { Server } from "socket.io";
import http from "node:http";
import { verifyToken } from "../auth/auth.service";
import { getStatusSnapshot } from "../status/status.service";
import { EVENTS } from "./events";
import { config, isDev } from "../config";
import { getWatcherItems, getWatcherSummary, listWatchers } from "../watcher/watcher.service";

const parseCookies = (cookieHeader?: string) => {
  const cookies: Record<string, string> = {};
  if (!cookieHeader) {
    return cookies;
  }
  cookieHeader.split(";").forEach((part) => {
    const [key, ...rest] = part.trim().split("=");
    cookies[key] = decodeURIComponent(rest.join("="));
  });
  return cookies;
};

export const createSocketServer = (server: http.Server) => {
  const io = new Server(server, {
    cors: isDev
      ? {
          origin: true,
          credentials: true,
        }
      : undefined,
  });

  io.use((socket, next) => {
    const authToken = socket.handshake.auth?.token as string | undefined;
    if (authToken) {
      try {
        verifyToken(authToken);
        return next();
      } catch (error) {
        return next(new Error("Unauthorized"));
      }
    }
    const cookies = parseCookies(socket.request.headers.cookie);
    const token = cookies["qbuffer_token"];
    if (!token) {
      return next(new Error("Unauthorized"));
    }
    try {
      verifyToken(token);
      return next();
    } catch (error) {
      return next(new Error("Unauthorized"));
    }
  });

  io.on("connection", async (socket) => {
    const snapshot = await getStatusSnapshot();
    socket.emit(EVENTS.STATUS_SNAPSHOT, snapshot);
    socket.emit(EVENTS.WATCHERS_LIST, await listWatchers());
    socket.emit(EVENTS.WATCHER_SUMMARY, await getWatcherSummary());
    socket.emit(EVENTS.WATCHER_ITEMS, await getWatcherItems());
  });

  return io;
};
