import { randomUUID } from "node:crypto";

/**
 * Outbox 事件构建器
 *
 * 所有事件 payload 必须包含（events.proto 仲裁 §2.1）：
 *   - event_id: UUID（幂等消费）
 *   - occurred_at: 业务时间戳（ms epoch）
 *   - schema_version: 默认 "v1"
 *   - metadata: { traceId, userId }
 */

export interface EventMetadata {
  schema_version: string;
  trace_id: string;
  user_id: string;
}

export interface OutboxEvent<T = Record<string, unknown>> {
  event_id: string;
  aggregate_id: string;
  event_type: string;
  occurred_at: number;
  payload: T;
  metadata: EventMetadata;
}

export interface BuildEventInput {
  aggregateId: string;
  eventType: string;
  payload: Record<string, unknown>;
  userId?: string;
  traceId?: string;
  schemaVersion?: string;
}

/**
 * 构建标准 Outbox 事件（含 event_id / occurred_at / schema_version / metadata）。
 * 返回的对象可直接 JSON.stringify 作为 outbox.payload 存储。
 */
export function buildEvent(input: BuildEventInput): OutboxEvent {
  return {
    event_id: randomUUID(),
    aggregate_id: input.aggregateId,
    event_type: input.eventType,
    occurred_at: Date.now(),
    payload: input.payload,
    metadata: {
      schema_version: input.schemaVersion ?? "v1",
      trace_id: input.traceId ?? "unknown",
      user_id: input.userId ?? "system",
    },
  };
}

/**
 * 将 OutboxEvent 序列化为 JSON 字符串（用于 outbox.payload 列）。
 */
export function serializeEvent(event: OutboxEvent): string {
  return JSON.stringify(event);
}
