import { Controller, Logger } from '@nestjs/common';
import {
  MessagePattern,
  Payload,
  Ctx,
  KafkaContext,
} from '@nestjs/microservices';
import { IDENTITY_TOPICS, DomainEventMessage } from './event-publisher.service';

@Controller()
export class EventConsumerController {
  private readonly logger = new Logger(EventConsumerController.name);

  @MessagePattern(IDENTITY_TOPICS.USER_ACCOUNT_CREATED)
  async handleUserAccountCreated(
    @Payload() message: DomainEventMessage,
    @Ctx() context: KafkaContext,
  ): Promise<void> {
    const { offset } = context.getMessage();
    const partition = context.getPartition();

    this.logger.log(
      `Received UserAccountCreated event: ${message.eventId}, partition: ${partition}, offset: ${offset}`,
    );

    try {
      await this.processUserAccountCreated(message.payload);
      this.logger.log(
        `Successfully processed UserAccountCreated: ${message.eventId}`,
      );
    } catch (error) {
      this.logger.error(
        `Failed to process UserAccountCreated: ${message.eventId}`,
        error,
      );
      throw error;
    }
  }

  @MessagePattern(IDENTITY_TOPICS.DEVICE_ADDED)
  async handleDeviceAdded(
    @Payload() message: DomainEventMessage,
    @Ctx() context: KafkaContext,
  ): Promise<void> {
    const { offset } = context.getMessage();
    const partition = context.getPartition();

    this.logger.log(
      `Received DeviceAdded event: ${message.eventId}, partition: ${partition}, offset: ${offset}`,
    );

    try {
      await this.processDeviceAdded(message.payload);
      this.logger.log(`Successfully processed DeviceAdded: ${message.eventId}`);
    } catch (error) {
      this.logger.error(
        `Failed to process DeviceAdded: ${message.eventId}`,
        error,
      );
      throw error;
    }
  }

  @MessagePattern(IDENTITY_TOPICS.PHONE_BOUND)
  async handlePhoneBound(
    @Payload() message: DomainEventMessage,
    @Ctx() context: KafkaContext,
  ): Promise<void> {
    const { offset } = context.getMessage();
    const partition = context.getPartition();

    this.logger.log(
      `Received PhoneBound event: ${message.eventId}, partition: ${partition}, offset: ${offset}`,
    );

    try {
      await this.processPhoneBound(message.payload);
      this.logger.log(`Successfully processed PhoneBound: ${message.eventId}`);
    } catch (error) {
      this.logger.error(
        `Failed to process PhoneBound: ${message.eventId}`,
        error,
      );
      throw error;
    }
  }

  @MessagePattern(IDENTITY_TOPICS.KYC_SUBMITTED)
  async handleKYCSubmitted(
    @Payload() message: DomainEventMessage,
    @Ctx() context: KafkaContext,
  ): Promise<void> {
    this.logger.log(`Received KYCSubmitted event: ${message.eventId}`);

    try {
      await this.processKYCSubmitted(message.payload);
      this.logger.log(
        `Successfully processed KYCSubmitted: ${message.eventId}`,
      );
    } catch (error) {
      this.logger.error(
        `Failed to process KYCSubmitted: ${message.eventId}`,
        error,
      );
      throw error;
    }
  }

  @MessagePattern(IDENTITY_TOPICS.KYC_APPROVED)
  async handleKYCApproved(
    @Payload() message: DomainEventMessage,
    @Ctx() context: KafkaContext,
  ): Promise<void> {
    this.logger.log(`Received KYCApproved event: ${message.eventId}`);

    try {
      await this.processKYCApproved(message.payload);
      this.logger.log(`Successfully processed KYCApproved: ${message.eventId}`);
    } catch (error) {
      this.logger.error(
        `Failed to process KYCApproved: ${message.eventId}`,
        error,
      );
      throw error;
    }
  }

  @MessagePattern(IDENTITY_TOPICS.KYC_REJECTED)
  async handleKYCRejected(
    @Payload() message: DomainEventMessage,
    @Ctx() context: KafkaContext,
  ): Promise<void> {
    this.logger.log(`Received KYCRejected event: ${message.eventId}`);

    try {
      await this.processKYCRejected(message.payload);
      this.logger.log(`Successfully processed KYCRejected: ${message.eventId}`);
    } catch (error) {
      this.logger.error(
        `Failed to process KYCRejected: ${message.eventId}`,
        error,
      );
      throw error;
    }
  }

  @MessagePattern(IDENTITY_TOPICS.ACCOUNT_FROZEN)
  async handleAccountFrozen(
    @Payload() message: DomainEventMessage,
    @Ctx() context: KafkaContext,
  ): Promise<void> {
    this.logger.log(`Received AccountFrozen event: ${message.eventId}`);

    try {
      await this.processAccountFrozen(message.payload);
      this.logger.log(
        `Successfully processed AccountFrozen: ${message.eventId}`,
      );
    } catch (error) {
      this.logger.error(
        `Failed to process AccountFrozen: ${message.eventId}`,
        error,
      );
      throw error;
    }
  }

  @MessagePattern(IDENTITY_TOPICS.WALLET_BOUND)
  async handleWalletBound(
    @Payload() message: DomainEventMessage,
    @Ctx() context: KafkaContext,
  ): Promise<void> {
    this.logger.log(`Received WalletBound event: ${message.eventId}`);

    try {
      await this.processWalletBound(message.payload);
      this.logger.log(`Successfully processed WalletBound: ${message.eventId}`);
    } catch (error) {
      this.logger.error(
        `Failed to process WalletBound: ${message.eventId}`,
        error,
      );
      throw error;
    }
  }

  // 业务处理方法
  private async processUserAccountCreated(payload: any): Promise<void> {
    this.logger.debug(
      `Processing UserAccountCreated: userId=${payload.userId}`,
    );
    // 发送欢迎通知
    // 初始化用户积分
    // 记录邀请关系
  }

  private async processDeviceAdded(payload: any): Promise<void> {
    this.logger.debug(
      `Processing DeviceAdded: userId=${payload.userId}, deviceId=${payload.deviceId}`,
    );
    // 发送新设备登录通知
    // 安全审计记录
  }

  private async processPhoneBound(payload: any): Promise<void> {
    this.logger.debug(`Processing PhoneBound: userId=${payload.userId}`);
    // 发送绑定成功短信
  }

  private async processKYCSubmitted(payload: any): Promise<void> {
    this.logger.debug(`Processing KYCSubmitted: userId=${payload.userId}`);
    // 触发KYC审核流程
    // 通知审核人员
  }

  private async processKYCApproved(payload: any): Promise<void> {
    this.logger.debug(`Processing KYCApproved: userId=${payload.userId}`);
    // 发送审核通过通知
    // 解锁高级功能
  }

  private async processKYCRejected(payload: any): Promise<void> {
    this.logger.debug(`Processing KYCRejected: userId=${payload.userId}`);
    // 发送审核失败通知
  }

  private async processAccountFrozen(payload: any): Promise<void> {
    this.logger.debug(`Processing AccountFrozen: userId=${payload.userId}`);
    // 发送账户冻结通知
    // 清除用户会话
  }

  private async processWalletBound(payload: any): Promise<void> {
    this.logger.debug(
      `Processing WalletBound: userId=${payload.userId}, chain=${payload.chainType}`,
    );
    // 同步钱包余额
  }
}
