/**
 * Identity Event Consumer Service for Wallet Service
 *
 * [2026-01-08] 新增：监听 identity-service 的用户注册事件
 * 在用户注册时自动创建钱包，确保内部转账时接收方钱包一定存在
 *
 * 消费的事件:
 * - identity.UserAccountCreated: 用户账户创建事件
 * - identity.UserAccountAutoCreated: 自动创建账户事件
 *
 * 回滚方式: 删除此文件，并从 kafka.module.ts 中移除引用
 */

import { Injectable, Logger, OnModuleInit, OnModuleDestroy } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { Kafka, Consumer, logLevel, EachMessagePayload } from 'kafkajs';

// identity-service 发布的用户事件 Topic
export const IDENTITY_TOPICS = {
  USER_ACCOUNT_CREATED: 'identity.UserAccountCreated',
  USER_ACCOUNT_AUTO_CREATED: 'identity.UserAccountAutoCreated',
} as const;

// 用户账户创建事件的 payload 结构
export interface UserAccountCreatedPayload {
  userId: string;
  accountSequence: string;
  phoneNumber?: string;
  nickname?: string;
  referralCode?: string;
  inviterUserId?: string;
  createdAt: string;
}

export type UserAccountCreatedHandler = (payload: UserAccountCreatedPayload) => Promise<void>;

@Injectable()
export class IdentityEventConsumerService implements OnModuleInit, OnModuleDestroy {
  private readonly logger = new Logger(IdentityEventConsumerService.name);
  private kafka: Kafka;
  private consumer: Consumer;
  private isConnected = false;

  private userAccountCreatedHandler?: UserAccountCreatedHandler;

  constructor(private readonly configService: ConfigService) {}

  async onModuleInit() {
    const brokers = this.configService.get<string>('KAFKA_BROKERS')?.split(',') || ['localhost:9092'];
    const clientId = this.configService.get<string>('KAFKA_CLIENT_ID') || 'wallet-service';
    const groupId = 'wallet-service-identity-events';

    this.logger.log(`[INIT] Identity Event Consumer initializing...`);
    this.logger.log(`[INIT] ClientId: ${clientId}`);
    this.logger.log(`[INIT] GroupId: ${groupId}`);
    this.logger.log(`[INIT] Brokers: ${brokers.join(', ')}`);
    this.logger.log(`[INIT] Topics: ${Object.values(IDENTITY_TOPICS).join(', ')}`);

    // 企业级重试配置
    this.kafka = new Kafka({
      clientId,
      brokers,
      logLevel: logLevel.WARN,
      retry: {
        initialRetryTime: 1000,        // 1 秒
        maxRetryTime: 300000,          // 最大 5 分钟
        retries: 15,                   // 最多 15 次
        multiplier: 2,                 // 指数退避因子
        restartOnFailure: async () => true,
      },
    });

    this.consumer = this.kafka.consumer({
      groupId,
      sessionTimeout: 30000,
      heartbeatInterval: 3000,
    });

    try {
      this.logger.log(`[CONNECT] Connecting Identity Event consumer...`);
      await this.consumer.connect();
      this.isConnected = true;
      this.logger.log(`[CONNECT] Identity Event consumer connected successfully`);

      await this.consumer.subscribe({
        topics: Object.values(IDENTITY_TOPICS),
        fromBeginning: false,
      });
      this.logger.log(`[SUBSCRIBE] Subscribed to identity topics`);

      await this.startConsuming();
    } catch (error) {
      this.logger.error(`[ERROR] Failed to connect Identity Event consumer`, error);
    }
  }

  async onModuleDestroy() {
    if (this.isConnected) {
      await this.consumer.disconnect();
      this.logger.log('Identity Event consumer disconnected');
    }
  }

  /**
   * 注册用户账户创建事件处理器
   */
  onUserAccountCreated(handler: UserAccountCreatedHandler): void {
    this.userAccountCreatedHandler = handler;
    this.logger.log('[HANDLER] User account created handler registered');
  }

  private async startConsuming(): Promise<void> {
    this.logger.log(`[CONSUME] Starting to consume identity events...`);

    await this.consumer.run({
      eachMessage: async (messagePayload: EachMessagePayload) => {
        const { topic, partition, message } = messagePayload;

        try {
          if (!message.value) {
            this.logger.warn(`[SKIP] Empty message from ${topic}`);
            return;
          }

          const rawValue = message.value.toString();
          this.logger.debug(`[RAW] Topic: ${topic}, Partition: ${partition}, Value: ${rawValue}`);

          const eventMessage = JSON.parse(rawValue);
          const payload = eventMessage.payload || eventMessage;

          this.logger.log(`[RECEIVED] Event from ${topic}: userId=${payload.userId}, accountSequence=${payload.accountSequence}`);

          // 处理用户账户创建事件
          if (
            topic === IDENTITY_TOPICS.USER_ACCOUNT_CREATED ||
            topic === IDENTITY_TOPICS.USER_ACCOUNT_AUTO_CREATED
          ) {
            if (this.userAccountCreatedHandler) {
              await this.userAccountCreatedHandler(payload as UserAccountCreatedPayload);
              this.logger.log(`[SUCCESS] Processed user account created event: ${payload.accountSequence}`);
            } else {
              this.logger.warn(`[SKIP] No handler registered for user account created event`);
            }
          } else {
            this.logger.warn(`[SKIP] Unknown topic: ${topic}`);
          }
        } catch (error) {
          this.logger.error(`[ERROR] Error processing identity event from ${topic}`, error);
          // 重新抛出异常以触发 Kafka 重试机制
          throw error;
        }
      },
    });
  }
}
