import { z } from "zod";
import { defineRealtimeChannel } from "./realtime-channel";
import type { IRealtimeBroadcaster } from "./realtime-broadcaster.interface";
import type { IInboundDescriptor, RealtimeContext } from "./realtime-handler.interface";

const pingSchema = z.object({ at: z.string().datetime() }).strict();
const pongSchema = z.object({ at: z.string().datetime(), echo: z.string() }).strict();

export type PingPayload = z.infer<typeof pingSchema>;
export type PongPayload = z.infer<typeof pongSchema>;

export const realtimePingChannel = defineRealtimeChannel(
  "realtime.ping",
  pingSchema,
  { scope: "authenticated" },
);

export const realtimePongChannel = defineRealtimeChannel(
  "realtime.pong",
  pongSchema,
  { scope: "authenticated" },
);

export function realtimePingInboundDescriptor(
  broadcaster: IRealtimeBroadcaster,
): IInboundDescriptor<"realtime.ping", z.ZodType<PingPayload>> {
  return {
    descriptor: realtimePingChannel,
    handler: async (input: PingPayload, ctx: RealtimeContext): Promise<void> => {
      await broadcaster.broadcast(realtimePongChannel, {
        at: input.at,
        echo: ctx.userId ?? "anonymous",
      });
    },
  };
}
