import { Injectable } from '@nestjs/common';
import { PrismaService } from '@/infrastructure/persistence/prisma/prisma.service';
import { UserRegisteredEvent, UserKycVerifiedEvent, LegacyUserMigratedEvent } from '@/domain';

type DomainEvent = UserRegisteredEvent | UserKycVerifiedEvent | LegacyUserMigratedEvent;

/**
 * Outbox 服务 - 用于发布领域事件
 * 实现发件箱模式，确保事件可靠发布
 */
@Injectable()
export class OutboxService {
  constructor(private readonly prisma: PrismaService) {}

  /**
   * 发布领域事件到 Outbox
   */
  async publish(event: DomainEvent): Promise<void> {
    const eventType = this.getEventType(event);
    const topic = this.getTopicForEvent(event);
    const payload = event.toPayload();

    await this.prisma.outboxEvent.create({
      data: {
        aggregateType: 'User',
        aggregateId: this.getAggregateId(event),
        eventType,
        payload: payload as any,
        topic,
        key: this.getAggregateId(event),
        status: 'PENDING',
      },
    });
  }

  private getEventType(event: DomainEvent): string {
    if (event instanceof UserRegisteredEvent) {
      return UserRegisteredEvent.EVENT_TYPE;
    }
    if (event instanceof UserKycVerifiedEvent) {
      return UserKycVerifiedEvent.EVENT_TYPE;
    }
    if (event instanceof LegacyUserMigratedEvent) {
      return LegacyUserMigratedEvent.EVENT_TYPE;
    }
    throw new Error('Unknown event type');
  }

  private getTopicForEvent(event: DomainEvent): string {
    // 所有用户相关事件发到同一个 topic
    return 'mining-admin.auth.users';
  }

  private getAggregateId(event: DomainEvent): string {
    return event.accountSequence;
  }
}
