import { Controller, Post, Body, Query, Logger, HttpStatus, Res, HttpException, Headers } from '@nestjs/common';
import { ApiTags, ApiOperation } from '@nestjs/swagger';
import { ConfigService } from '@nestjs/config';
import { PaymobService } from '../services/paymob.service.js';
import { BinancePayService } from '../services/binance-pay.service.js';
import { InitiatePaymentDto } from '../dto/initiate-payment.dto.js';
import { UsersService } from '../../users/services/users.service.js';

@ApiTags('payments')
@Controller('payments')
export class PaymentsController {
  private readonly logger = new Logger(PaymentsController.name);

  constructor(
    private readonly paymobService: PaymobService,
    private readonly binancePayService: BinancePayService,
    private readonly usersService: UsersService,
    private readonly configService: ConfigService,
  ) {}

  @Post('initiate')
  @ApiOperation({ summary: 'Initiate a payment session | بدء جلسة دفع' })
  async initiate(@Body() dto: InitiatePaymentDto) {
    if (dto.gateway === 'paymob') {
      const token = await this.paymobService.authenticate();
      const orderId = await this.paymobService.registerOrder(token, dto.amount * 100, dto.currency);
      
      const cardId = this.configService.get<number>('paymob.cardIntegrationId') || 0;
      const walletId = this.configService.get<number>('paymob.walletIntegrationId') || 0;
      const integrationId = dto.method === 'wallet' ? walletId : cardId;

      const paymentKey = await this.paymobService.generatePaymentKey(
        token,
        orderId,
        dto.amount * 100,
        dto.currency,
        {
          email: dto.email || 'guest@example.com',
          first_name: dto.firstName || 'Guest',
          last_name: dto.lastName || 'User',
          phone_number: dto.phoneNumber || '01000000000',
          city: 'Cairo',
          country: 'EG',
          street: 'N/A',
          building: 'N/A',
          floor: 'N/A',
          apartment: 'N/A',
        },
        integrationId,
      );
      return { 
        gateway: 'paymob',
        paymentUrl: `https://accept.paymob.com/api/acceptance/iframes/your_iframe_id?payment_token=${paymentKey}` 
      };
    } else if (dto.gateway === 'binance') {
      const result = await this.binancePayService.createOrder({
        merchantTradeNo: `ORDER_${Date.now()}`,
        orderAmount: dto.amount,
        currency: dto.currency,
        description: 'SaaS Subscription - Pro Tier',
      });
      return {
        gateway: 'binance',
        paymentUrl: result.checkoutUrl,
        qrCode: result.qrContent,
      };
    }
  }

  @Post('paymob/callback')
  @ApiOperation({ summary: 'Paymob Webhook Callback' })
  async paymobCallback(@Body() body: any, @Query('hmac') hmac: string) {
    this.logger.log('Received Paymob callback');
    
    if (!this.paymobService.verifyHmac(body.obj, hmac)) {
      this.logger.warn('Invalid Paymob HMAC signature');
      throw new HttpException('Invalid signature', HttpStatus.FORBIDDEN);
    }

    const transaction = body.obj;
    if (transaction.success && transaction.is_auth === false) {
      const orderId = transaction.order.id;
      this.logger.log(`Payment successful for Order: ${orderId}`);
      // In a real app, find user by orderId. Demo:
      await this.usersService.updateSubscription('64b134ab-bf6b-486b-8556-1000f2c93942', 'pro', 30);
    }
    return { status: 'received' };
  }

  @Post('binance/callback')
  @ApiOperation({ summary: 'Binance Pay Webhook Callback' })
  async binanceCallback(
    @Body() body: any,
    @Headers('binancepay-signature') signature: string,
    @Headers('binancepay-timestamp') timestamp: string,
    @Headers('binancepay-nonce') nonce: string,
  ) {
    this.logger.log('Received Binance Pay callback');
    
    const payload = JSON.stringify(body);
    if (!this.binancePayService.verifySignature(payload, timestamp, nonce, signature)) {
      this.logger.warn('Invalid Binance Pay signature');
      throw new HttpException('Invalid signature', HttpStatus.FORBIDDEN);
    }

    if (body.bizStatus === 'PAY_SUCCESS') {
      this.logger.log(`Binance Payment successful for: ${body.bizId}`);
      await this.usersService.updateSubscription('64b134ab-bf6b-486b-8556-1000f2c93942', 'pro', 30);
    }
    return { returnCode: 'SUCCESS', returnMsg: 'OK' };
  }
}
