import { IEventBus, DrizzleTransaction } from '../event-bus.protocol.js';
import { EventTypeName, PayloadOfType, EventOfType } from './types.js';
import '../../../types/drizzle.js';
import 'drizzle-orm/node-postgres';

/**
 * Typed facade over IEventBus.
 *
 * Stamps `pool`, `direction`, `tier`, and `version` into `event.metadata`
 * from the generated `eventRegistry` before delegating to
 * `IEventBus.publish()`. Downstream backends (DrizzleEventBus) read those
 * values to populate the explicit `domain_events` columns.
 *
 * Tier stamping (AUDIT-3): every event carries `metadata.tier`, sourced
 * from the registry. For `tier: 'audit'` events, the bus FORCES
 * `metadata.pool = null` and `metadata.direction = null` regardless of
 * any caller-supplied values in `opts.metadata` — audit routing is
 * bus-stamped, not caller-controlled. Caller overrides are silently
 * dropped with a debug-level log (callers should not be specifying these
 * for audit events; see ai-docs/specs/issue-242/plan.md §AUDIT-3).
 *
 * Validation gating (EVT-Q5): `CODEGEN_EVENT_VALIDATE` env flag, default on.
 * Uses `safeParse` + `console.warn` — never throws, so a bad publish does
 * not crash a hot path.
 *
 * Multi-tenancy (EVT-6): when the EventsModule is configured with
 * `multiTenant: true`, every publish must supply `opts.metadata.tenantId`
 * — otherwise `publish()` throws `MissingTenantIdError`. When `multiTenant`
 * is `false` (default), no tenantId is required. If a tenantId IS supplied,
 * it is preserved on `event.metadata` and the Drizzle backend writes it to
 * `domain_events.tenant_id` (EVT-4).
 */
declare class TypedEventBus {
    private readonly bus;
    private readonly multiTenant;
    constructor(bus: IEventBus, multiTenant: boolean);
    publish<T extends EventTypeName>(type: T, aggregateId: string, payload: PayloadOfType<T>, opts?: {
        tx?: DrizzleTransaction;
        metadata?: Record<string, unknown>;
    }): Promise<void>;
    subscribe<T extends EventTypeName>(type: T, handler: (event: EventOfType<T>) => Promise<void>): () => void;
}

export { TypedEventBus };
