import { Injectable, Logger } from '@nestjs/common';
import { HttpService } from '@nestjs/axios';
import { ConfigService } from '@nestjs/config';
import { firstValueFrom } from 'rxjs';
import { AxiosResponse } from 'axios';

export interface TransferResult {
  success: boolean;
  txHash?: string;
  error?: string;
  gasUsed?: string;
  blockNumber?: number;
}

export interface BalanceResult {
  address: string;
  balance: string;
  chain: string;
}

export interface StatusResult {
  configured: boolean;
  hotWalletAddress: string | null;
}

/**
 * 区块链客户端
 * 用于调用 mining-blockchain-service 进行 dUSDT 转账
 */
@Injectable()
export class BlockchainClient {
  private readonly logger = new Logger(BlockchainClient.name);
  private readonly baseUrl: string;

  constructor(
    private readonly httpService: HttpService,
    private readonly configService: ConfigService,
  ) {
    this.baseUrl = this.configService.get<string>(
      'MINING_BLOCKCHAIN_SERVICE_URL',
      'http://localhost:3020',
    );
    this.logger.log(`[INIT] BlockchainClient initialized with URL: ${this.baseUrl}`);
  }

  /**
   * 转账 dUSDT 到指定地址
   * @param toAddress 接收地址
   * @param amount 金额（人类可读格式）
   */
  async transferDusdt(toAddress: string, amount: string): Promise<TransferResult> {
    this.logger.log(`[TRANSFER] Calling mining-blockchain-service: to=${toAddress}, amount=${amount}`);

    try {
      const response: AxiosResponse<TransferResult> = await firstValueFrom(
        this.httpService.post<TransferResult>(`${this.baseUrl}/api/v1/transfer/dusdt`, {
          toAddress,
          amount,
        }),
      );

      this.logger.log(`[TRANSFER] Response: ${JSON.stringify(response.data)}`);
      return response.data;
    } catch (error: any) {
      const errorMessage = error.response?.data?.message || error.message || 'Unknown error';
      this.logger.error(`[TRANSFER] Failed: ${errorMessage}`);
      return {
        success: false,
        error: errorMessage,
      };
    }
  }

  /**
   * 查询热钱包 dUSDT 余额
   */
  async getHotWalletBalance(): Promise<BalanceResult | null> {
    try {
      const response: AxiosResponse<BalanceResult> = await firstValueFrom(
        this.httpService.get<BalanceResult>(`${this.baseUrl}/api/v1/transfer/dusdt/balance`),
      );
      return response.data;
    } catch (error: any) {
      this.logger.error(`[BALANCE] Failed to get balance: ${error.message}`);
      return null;
    }
  }

  /**
   * 检查转账服务状态
   */
  async getStatus(): Promise<StatusResult | null> {
    try {
      const response: AxiosResponse<StatusResult> = await firstValueFrom(
        this.httpService.get<StatusResult>(`${this.baseUrl}/api/v1/transfer/status`),
      );
      return response.data;
    } catch (error: any) {
      this.logger.error(`[STATUS] Failed to get status: ${error.message}`);
      return null;
    }
  }

  /**
   * 检查服务是否可用
   */
  async isAvailable(): Promise<boolean> {
    const status = await this.getStatus();
    return status?.configured ?? false;
  }

  // ============ eUSDT (积分股) 接口 ============

  /**
   * 转账 eUSDT（积分股）到指定地址
   * @param toAddress 接收地址
   * @param amount 金额（人类可读格式）
   */
  async transferEusdt(toAddress: string, amount: string): Promise<TransferResult> {
    this.logger.log(`[TRANSFER-EUSDT] Calling mining-blockchain-service: to=${toAddress}, amount=${amount}`);

    try {
      const response: AxiosResponse<TransferResult> = await firstValueFrom(
        this.httpService.post<TransferResult>(`${this.baseUrl}/api/v1/transfer/eusdt`, {
          toAddress,
          amount,
        }),
      );

      this.logger.log(`[TRANSFER-EUSDT] Response: ${JSON.stringify(response.data)}`);
      return response.data;
    } catch (error: any) {
      const errorMessage = error.response?.data?.message || error.message || 'Unknown error';
      this.logger.error(`[TRANSFER-EUSDT] Failed: ${errorMessage}`);
      return {
        success: false,
        error: errorMessage,
      };
    }
  }

  /**
   * 查询热钱包 eUSDT（积分股）余额
   */
  async getEusdtBalance(): Promise<BalanceResult | null> {
    try {
      const response: AxiosResponse<BalanceResult> = await firstValueFrom(
        this.httpService.get<BalanceResult>(`${this.baseUrl}/api/v1/transfer/eusdt/balance`),
      );
      return response.data;
    } catch (error: any) {
      this.logger.error(`[BALANCE-EUSDT] Failed to get balance: ${error.message}`);
      return null;
    }
  }

  // ============ fUSDT (积分值) 接口 ============

  /**
   * 转账 fUSDT（积分值）到指定地址
   * @param toAddress 接收地址
   * @param amount 金额（人类可读格式）
   */
  async transferFusdt(toAddress: string, amount: string): Promise<TransferResult> {
    this.logger.log(`[TRANSFER-FUSDT] Calling mining-blockchain-service: to=${toAddress}, amount=${amount}`);

    try {
      const response: AxiosResponse<TransferResult> = await firstValueFrom(
        this.httpService.post<TransferResult>(`${this.baseUrl}/api/v1/transfer/fusdt`, {
          toAddress,
          amount,
        }),
      );

      this.logger.log(`[TRANSFER-FUSDT] Response: ${JSON.stringify(response.data)}`);
      return response.data;
    } catch (error: any) {
      const errorMessage = error.response?.data?.message || error.message || 'Unknown error';
      this.logger.error(`[TRANSFER-FUSDT] Failed: ${errorMessage}`);
      return {
        success: false,
        error: errorMessage,
      };
    }
  }

  /**
   * 查询热钱包 fUSDT（积分值）余额
   */
  async getFusdtBalance(): Promise<BalanceResult | null> {
    try {
      const response: AxiosResponse<BalanceResult> = await firstValueFrom(
        this.httpService.get<BalanceResult>(`${this.baseUrl}/api/v1/transfer/fusdt/balance`),
      );
      return response.data;
    } catch (error: any) {
      this.logger.error(`[BALANCE-FUSDT] Failed to get balance: ${error.message}`);
      return null;
    }
  }
}
