import { gameConfigurations } from "@/server/db/schema";
import { createTRPCRouter, protectedProcedure, publicProcedure } from "../trpc";
import { z } from "zod";
import { gameConfigPatchSchema } from "@/lib/validations/game";
import { eq } from "drizzle-orm";
import { ee } from "@/server/sse";
import { tracked } from "@trpc/server";
import type { EventArgs } from "@/server/sse/events";

export const gameConfigRouter = createTRPCRouter({
  // game configurator
  update: protectedProcedure
    .input(
      z.object({
        lobbyId: z.string(),
        config: gameConfigPatchSchema,
      }),
    )
    .mutation(async ({ ctx, input }) => {
      console.log("Check if user is admin");

      const [config] = await ctx.db
        .update(gameConfigurations)
        .set({ config: input.config })
        .where(eq(gameConfigurations.lobbyId, input.lobbyId))
        .returning({
          config: gameConfigurations.config,
        });
      if (config?.config)
        ee.emit("game:config:update", {
          lobbyId: input.lobbyId,
          config: config.config,
        });

      return config;
    }),

  // subscriptions
  onUpdate: publicProcedure
    .input(z.object({ lobbyId: z.string() }))
    .subscription(async function* (opts) {
      const iterable = ee.toIterable("game:config:update", {
        signal: opts.signal,
      });

      function* maybeYield([
        { config, lobbyId },
      ]: EventArgs["game:config:update"]) {
        if (lobbyId !== opts.input.lobbyId) {
          return;
        }
        yield tracked(lobbyId, config);
      }

      for await (const args of iterable) {
        yield* maybeYield(args);
      }
    }),
});
