import type { z } from "zod";
import type { EventBusProtocol } from "@repo/core-shared/di/bind-protocols";
import type { EventDescriptor } from "./event-descriptor";

export type EventHandler<T> = (event: T) => Promise<void>;

export interface IEventBus extends EventBusProtocol {
  publish<T>(
    descriptor: EventDescriptor<string, z.ZodType<T>>,
    payload: T,
  ): Promise<void>;

  /**
   * Subscribe a handler. `consumerFeature` is the kebab-case name of the
   * subscribing feature (e.g., "marketing-pages"). It is unused by
   * InMemoryEventBus; PayloadJobsEventBus uses it to name the fan-out task
   * slug deterministically (`__events.<event>.<consumerFeature>`).
   */
  subscribe<T>(
    descriptor: EventDescriptor<string, z.ZodType<T>>,
    consumerFeature: string,
    handler: EventHandler<T>,
  ): void;
}
