import { Injectable, Logger, HttpException, HttpStatus } from '@nestjs/common';
import { HttpService } from '@nestjs/axios';
import { ConfigService } from '@nestjs/config';
import { firstValueFrom } from 'rxjs';
import * as crypto from 'crypto';

@Injectable()
export class BinancePayService {
  private readonly logger = new Logger(BinancePayService.name);
  private readonly baseUrl = 'https://bpay.binanceapi.com/binancepay/openapi/v2';

  constructor(
    private readonly httpService: HttpService,
    private readonly configService: ConfigService,
  ) {}

  private generateSignature(payload: string, timestamp: number, nonce: string): string {
    const secretKey = this.configService.get<string>('binance.secretKey') || '';
    const signaturePayload = `${timestamp}\n${nonce}\n${payload}\n`;
    return crypto
      .createHmac('sha512', secretKey)
      .update(signaturePayload)
      .digest('hex')
      .toUpperCase();
  }

  verifySignature(payload: string, timestamp: string, nonce: string, signature: string): boolean {
    const calculatedSignature = this.generateSignature(payload, parseInt(timestamp), nonce);
    return calculatedSignature === signature;
  }

  async createOrder(params: {
    merchantTradeNo: string;
    orderAmount: number;
    currency: string;
    description: string;
  }) {
    const apiKey = this.configService.get<string>('binance.apiKey');
    const timestamp = Date.now();
    const nonce = crypto.randomBytes(16).toString('hex');
    const payload = JSON.stringify(params);

    const signature = this.generateSignature(payload, timestamp, nonce);

    try {
      const response = await firstValueFrom(
        this.httpService.post(`${this.baseUrl}/order`, payload, {
          headers: {
            'Content-Type': 'application/json',
            'BinancePay-Timestamp': timestamp,
            'BinancePay-Nonce': nonce,
            'BinancePay-Certificate-SN': apiKey,
            'BinancePay-Signature': signature,
          },
        })
      );
      return response.data.data;
    } catch (error) {
      this.logger.error('Binance Pay Order failed', error.response?.data || error.message);
      throw new HttpException('Binance Pay order creation failed', HttpStatus.BAD_GATEWAY);
    }
  }
}
