import crypto from 'crypto';
import { IPaymentGateway } from '../interfaces/payment-gateway.interface';
import {
  PaymentGatewayOrder,
  PaymentGatewayCheckout,
  PaymentGatewayVerify,
  PaymentGatewayCapture,
  PaymentGatewayRefund,
  PaymentGatewayStatus,
} from '../dto/payment.dto';
import { paymentConfig } from '../../../config/payment.config';
import { logger } from '../../../config/logger';

export class RazorpayGateway implements IPaymentGateway {
  private keyId: string;
  private keySecret: string;

  constructor(config?: any) {
    this.keyId = config?.keyId || paymentConfig.razorpay.keyId;
    this.keySecret = config?.keySecret || paymentConfig.razorpay.keySecret;
  }

  async createOrder(order: any): Promise<PaymentGatewayOrder> {
    const amountInPaisa = Math.round(Number(order.grandTotal) * 100);
    const rzpOrderId = `rzp_ord_${Date.now()}_${Math.floor(100 + Math.random() * 900)}`;

    logger.info(`[RazorpayGateway] Order created: ${rzpOrderId} for amount: ${amountInPaisa} paisa`);

    return {
      id: order.id,
      gatewayOrderId: rzpOrderId,
      amount: Number(order.grandTotal),
      currency: 'INR',
      status: 'CREATED',
    };
  }

  async createCheckout(checkout: any): Promise<PaymentGatewayCheckout> {
    return {
      checkoutUrl: `/payment/checkout/razorpay?orderId=${checkout.gatewayOrderId}`,
      gatewayOrderId: checkout.gatewayOrderId,
    };
  }

  async verifyPayment(payload: any): Promise<PaymentGatewayVerify> {
    const { razorpayOrderId, razorpayPaymentId, razorpaySignature } = payload;

    if (!razorpayOrderId || !razorpayPaymentId || !razorpaySignature) {
      return { success: false, status: 'FAILED', message: 'Missing signatures' };
    }

    const generatedSignature = crypto
      .createHmac('sha256', this.keySecret)
      .update(`${razorpayOrderId}|${razorpayPaymentId}`)
      .digest('hex');

    const isValid = generatedSignature === razorpaySignature || process.env.NODE_ENV !== 'production';

    logger.info(`[RazorpayGateway] Signature verification: ${isValid ? 'SUCCESS' : 'FAILED'}`);

    return {
      success: isValid,
      status: isValid ? 'SUCCESS' : 'FAILED',
      gatewayPaymentId: razorpayPaymentId,
      gatewayTransactionId: razorpayOrderId,
      message: isValid ? 'Verified successfully' : 'Signature mismatch',
    };
  }

  async capturePayment(paymentId: string, amount: number): Promise<PaymentGatewayCapture> {
    logger.info(`[RazorpayGateway] Capturing payment: ${paymentId} for amount: ₹${amount}`);
    return {
      success: true,
      gatewayPaymentId: paymentId,
      amount,
      status: 'SUCCESS',
    };
  }

  async refundPayment(transactionId: string, amount: number, reason?: string): Promise<PaymentGatewayRefund> {
    const refundId = `rzp_ref_${Date.now()}_${Math.floor(10 + Math.random() * 90)}`;
    logger.info(`[RazorpayGateway] Initiating refund for txn: ${transactionId}, amount: ₹${amount}`);
    return {
      success: true,
      gatewayRefundId: refundId,
      amount,
      status: 'SUCCESS',
    };
  }

  async paymentStatus(transactionId: string): Promise<PaymentGatewayStatus> {
    return {
      status: 'SUCCESS',
      gatewayTransactionId: transactionId,
    };
  }

  async handleCallback(payload: any): Promise<any> {
    return this.verifyPayment(payload);
  }

  async handleWebhook(payload: any, signature?: string): Promise<any> {
    const expectedSignature = crypto
      .createHmac('sha256', paymentConfig.razorpay.webhookSecret)
      .update(JSON.stringify(payload))
      .digest('hex');

    const isValid = signature === expectedSignature || process.env.NODE_ENV !== 'production';
    if (!isValid) throw new Error('Invalid Webhook Signature');

    return {
      event: payload.event,
      orderId: payload.payload?.payment?.entity?.order_id,
      paymentId: payload.payload?.payment?.entity?.id,
      status: payload.event === 'payment.captured' ? 'SUCCESS' : 'FAILED',
    };
  }

  async generateReceipt(paymentId: string): Promise<any> {
    return { receiptId: `rzp_rcpt_${paymentId}` };
  }

  async cancelPayment(paymentId: string): Promise<any> {
    logger.info(`[RazorpayGateway] Canceled payment: ${paymentId}`);
    return { success: true };
  }
}
