import { Injectable, Logger, OnModuleInit } from '@nestjs/common';
import {
  WithdrawalEventConsumerService,
  SystemWithdrawalRequestedPayload,
} from '@/infrastructure/kafka/withdrawal-event-consumer.service';
import { EventPublisherService } from '@/infrastructure/kafka/event-publisher.service';
import { Erc20TransferService } from '@/domain/services/erc20-transfer.service';
import { ChainTypeEnum } from '@/domain/enums';

/**
 * System Withdrawal Requested Event Handler
 *
 * Handles system account withdrawal requests from wallet-service.
 * Executes ERC20 USDT transfers from hot wallet to user's address.
 */
@Injectable()
export class SystemWithdrawalRequestedHandler implements OnModuleInit {
  private readonly logger = new Logger(SystemWithdrawalRequestedHandler.name);

  constructor(
    private readonly withdrawalEventConsumer: WithdrawalEventConsumerService,
    private readonly eventPublisher: EventPublisherService,
    private readonly transferService: Erc20TransferService,
  ) {}

  onModuleInit() {
    this.withdrawalEventConsumer.onSystemWithdrawalRequested(
      this.handleSystemWithdrawalRequested.bind(this),
    );
    this.logger.log(`[INIT] SystemWithdrawalRequestedHandler registered`);
  }

  /**
   * Handle system withdrawal requested event from wallet-service
   *
   * Flow:
   * 1. Receive system withdrawal request
   * 2. Execute ERC20 transfer from hot wallet
   * 3. Publish final status (CONFIRMED or FAILED)
   */
  private async handleSystemWithdrawalRequested(
    payload: SystemWithdrawalRequestedPayload,
  ): Promise<void> {
    this.logger.log(`[HANDLE] ========== System Withdrawal Request ==========`);
    this.logger.log(`[HANDLE] orderNo: ${payload.orderNo}`);
    this.logger.log(`[HANDLE] fromAccountSequence: ${payload.fromAccountSequence}`);
    this.logger.log(`[HANDLE] fromAccountName: ${payload.fromAccountName}`);
    this.logger.log(`[HANDLE] toAccountSequence: ${payload.toAccountSequence}`);
    this.logger.log(`[HANDLE] toAddress: ${payload.toAddress}`);
    this.logger.log(`[HANDLE] amount: ${payload.amount}`);
    this.logger.log(`[HANDLE] chainType: ${payload.chainType}`);

    try {
      // Step 1: 验证链类型
      const chainType = this.parseChainType(payload.chainType);
      if (!chainType) {
        throw new Error(`Unsupported chain type: ${payload.chainType}`);
      }

      // Step 2: 检查转账服务是否配置
      if (!this.transferService.isConfigured(chainType)) {
        throw new Error(`Hot wallet not configured for chain: ${chainType}`);
      }

      // Step 3: 执行 ERC20 转账
      this.logger.log(`[PROCESS] Executing ERC20 transfer for system withdrawal...`);
      const result = await this.transferService.transferUsdt(
        chainType,
        payload.toAddress,
        payload.amount,
      );

      if (result.success && result.txHash) {
        // Step 4a: 转账成功，发布确认状态
        this.logger.log(`[SUCCESS] System withdrawal ${payload.orderNo} confirmed!`);
        this.logger.log(`[SUCCESS] TxHash: ${result.txHash}`);
        this.logger.log(`[SUCCESS] Block: ${result.blockNumber}`);

        await this.eventPublisher.publish({
          eventType: 'blockchain.system-withdrawal.confirmed',
          toPayload: () => ({
            orderNo: payload.orderNo,
            fromAccountSequence: payload.fromAccountSequence,
            fromAccountName: payload.fromAccountName,
            toAccountSequence: payload.toAccountSequence,
            status: 'CONFIRMED',
            txHash: result.txHash,
            blockNumber: result.blockNumber,
            chainType: payload.chainType,
            toAddress: payload.toAddress,
            amount: payload.amount,
          }),
          eventId: `sys-wd-confirmed-${payload.orderNo}-${Date.now()}`,
          occurredAt: new Date(),
        });

        this.logger.log(`[COMPLETE] System withdrawal ${payload.orderNo} completed successfully`);
      } else {
        // Step 4b: 转账失败
        throw new Error(result.error || 'Transfer failed');
      }

    } catch (error) {
      this.logger.error(
        `[ERROR] Failed to process system withdrawal ${payload.orderNo}`,
        error,
      );

      // 发布失败事件
      await this.eventPublisher.publish({
        eventType: 'blockchain.system-withdrawal.failed',
        toPayload: () => ({
          orderNo: payload.orderNo,
          fromAccountSequence: payload.fromAccountSequence,
          fromAccountName: payload.fromAccountName,
          toAccountSequence: payload.toAccountSequence,
          status: 'FAILED',
          error: error instanceof Error ? error.message : 'Unknown error',
          chainType: payload.chainType,
          toAddress: payload.toAddress,
          amount: payload.amount,
        }),
        eventId: `sys-wd-failed-${payload.orderNo}-${Date.now()}`,
        occurredAt: new Date(),
      });

      throw error;
    }
  }

  /**
   * 解析链类型字符串
   */
  private parseChainType(chainType: string): ChainTypeEnum | null {
    const normalized = chainType.toUpperCase();
    if (normalized === 'KAVA') return ChainTypeEnum.KAVA;
    if (normalized === 'BSC') return ChainTypeEnum.BSC;
    return null;
  }
}
