// Local type aliases mirroring @repo/core-realtime's contracts. Kept inline to
// avoid a build-graph cycle between core-testing (tooling) and core-realtime (core).
// Same pattern recording-event-bus + recording-job-queue use.
import type { z } from "zod";

type RealtimeChannelDescriptor<TName extends string, TSchema extends z.ZodType> = {
  readonly name: TName;
  readonly schema: TSchema;
  readonly scope: string | { role: string } | { userScoped: true; template: string };
};

interface IRealtimeBroadcaster {
  broadcast<T>(
    descriptor: RealtimeChannelDescriptor<string, z.ZodType<T>>,
    payload: T,
  ): Promise<void>;
}

export class RecordingRealtimeBroadcaster implements IRealtimeBroadcaster {
  readonly broadcasts: { channel: string; payload: unknown }[] = [];

  async broadcast<T>(
    descriptor: RealtimeChannelDescriptor<string, z.ZodType<T>>,
    payload: T,
  ): Promise<void> {
    descriptor.schema.parse(payload);
    this.broadcasts.push({ channel: descriptor.name, payload });
  }
}
