import { Injectable, Logger, OnModuleInit } from '@nestjs/common';
import { AddressDerivationService } from '../services/address-derivation.service';
import { MpcEventConsumerService, KeygenCompletedPayload } from '@/infrastructure/kafka/mpc-event-consumer.service';

/**
 * MPC 密钥生成完成事件处理器
 *
 * 监听 mpc.KeygenCompleted 事件，从公钥派生多链钱包地址，
 * 并发布 blockchain.WalletAddressCreated 事件通知 identity-service
 */
@Injectable()
export class MpcKeygenCompletedHandler implements OnModuleInit {
  private readonly logger = new Logger(MpcKeygenCompletedHandler.name);

  constructor(
    private readonly addressDerivationService: AddressDerivationService,
    private readonly mpcEventConsumer: MpcEventConsumerService,
  ) {}

  onModuleInit() {
    // Register handler for keygen completed events
    this.mpcEventConsumer.onKeygenCompleted(this.handleKeygenCompleted.bind(this));
    this.logger.log(`[INIT] MpcKeygenCompletedHandler registered with MpcEventConsumer`);
  }

  /**
   * 处理 MPC 密钥生成完成事件
   * 从 mpc-service 的 KeygenCompleted 事件中提取 publicKey、userId 和 accountSequence
   */
  private async handleKeygenCompleted(payload: KeygenCompletedPayload): Promise<void> {
    this.logger.log(`[HANDLE] Received KeygenCompleted event`);
    this.logger.log(`[HANDLE] sessionId: ${payload.sessionId}`);
    this.logger.log(`[HANDLE] publicKey: ${payload.publicKey?.substring(0, 30)}...`);
    this.logger.log(`[HANDLE] extraPayload: ${JSON.stringify(payload.extraPayload)}`);

    // Extract userId and accountSequence from extraPayload
    const userId = payload.extraPayload?.userId;
    const accountSequence = payload.extraPayload?.accountSequence;

    if (!userId) {
      this.logger.error(`[ERROR] Missing userId in extraPayload, cannot derive addresses`);
      return;
    }

    if (!accountSequence) {
      this.logger.error(`[ERROR] Missing accountSequence in extraPayload, cannot derive addresses`);
      return;
    }

    const publicKey = payload.publicKey;
    if (!publicKey) {
      this.logger.error(`[ERROR] Missing publicKey in payload, cannot derive addresses`);
      return;
    }

    try {
      this.logger.log(`[DERIVE] Starting address derivation for user: ${userId}, account: ${accountSequence}`);

      const result = await this.addressDerivationService.deriveAndRegister({
        userId: BigInt(userId),
        accountSequence: accountSequence,
        publicKey,
      });

      this.logger.log(`[DERIVE] Successfully derived ${result.addresses.length} addresses for account ${accountSequence}`);
      result.addresses.forEach((addr) => {
        this.logger.log(`[DERIVE] - ${addr.chainType}: ${addr.address}`);
      });
    } catch (error) {
      this.logger.error(`[ERROR] Failed to derive addresses for account ${accountSequence}:`, error);
      throw error;
    }
  }
}
