import type { z } from "zod";

/**
 * `userScoped` channels include a `{userId}` placeholder in the channel name.
 * The `userId` param extracted from the channel pattern is matched against
 * `user.userId` at subscribe time. The `template` field is metadata: it is
 * the same string passed to `defineRealtimeChannel`'s `name` argument and is
 * used by clients/admin tools to display the channel pattern.
 */
export type ChannelScope =
  | "public"
  | "authenticated"
  | { role: string }
  | { userScoped: true; template: string };

export type RealtimeChannelDescriptor<TName extends string, TSchema extends z.ZodType> = {
  readonly name: TName;
  readonly schema: TSchema;
  readonly scope: ChannelScope;
};

export function defineRealtimeChannel<TName extends string, TSchema extends z.ZodType>(
  name: TName,
  schema: TSchema,
  options: { scope: ChannelScope },
): RealtimeChannelDescriptor<TName, TSchema> {
  return { name, schema, scope: options.scope };
}
