const axios = require('axios');

const logger = require('../util/logger');

const { PAYMONGO_SECRET_KEY } = process.env;
const PAYMONGO_API_BASE_URL = process.env.PAYMONGO_API_BASE_URL || 'https://api.paymongo.com/v1';

// @ts-ignore
const paymongo = axios.create({
  baseURL: PAYMONGO_API_BASE_URL,
  headers: {
    Authorization: `Basic ${Buffer.from(`${PAYMONGO_SECRET_KEY}:`).toString('base64')}`,
    'Content-Type': 'application/json',
  },
});

const formatAmount = (amount) => Math.round(parseFloat(amount) * 100);

const parseAmount = (amount) => parseFloat(amount) / 100;

const checkoutSession = async ({
  amount,
  currency = 'PHP',
  description,
  bookingNo,
  successUrl,
  failUrl,
}) => {
  try {
    const amountInCentavos = formatAmount(amount);
    if (amountInCentavos < 2000) {
      throw new Error(`Minimum amount is ₱20.00. Provided amount: ₱${amount}`);
    }

    const checkoutRes = await paymongo.post('/checkout_sessions', {
      data: {
        attributes: {
          description,
          line_items: [
            {
              name: description || `Booking ${bookingNo}`,
              amount: amountInCentavos,
              currency: currency.toUpperCase(),
              quantity: 1,
            },
          ],
          payment_method_types: ['qrph', 'card', 'dob', 'gcash', 'grab_pay', 'billease', 'paymaya'],
          success_url: successUrl,
          cancel_url: failUrl,
          metadata: {
            booking_no: bookingNo,
          },
        },
      },
    });

    logger.info(`PayMongo checkout session created: ${JSON.stringify(checkoutRes.data, null, 2)}`);

    return {
      payment_url: checkoutRes.data.data.attributes.checkout_url,
      status: checkoutRes.data.data.attributes.status,
      payment_intent_id: checkoutRes.data.data.attributes.payment_intent.id,
    };
  } catch (error) {
    logger.error('PayMongo createBookingPayment error:', error);
    throw new Error(
      error.response?.data?.errors?.[0]?.detail || error.message || 'Failed to create payment',
    );
  }
};

async function getPaymentStatus(paymentIntentId) {
  try {
    const res = await paymongo.get(`/payment_intents/${paymentIntentId}`);
    return res.data.data;
  } catch (error) {
    logger.error('PayMongo getPaymentStatus error:', error);
    throw new Error(
      error.response?.data?.errors?.[0]?.detail || error.message || 'Failed to get payment status',
    );
  }
}

async function refundPayment(paymongoPaymentId, amount, notes, paymongoFee = 0) {
  try {
    const amountInCentavos = formatAmount(amount);
    const feeInCentavos = formatAmount(paymongoFee || 0);

    const amountToRefund = amountInCentavos - feeInCentavos;
    if (amountInCentavos < 100) {
      throw new Error('Minimum refund amount is ₱1.00');
    }

    const res = await paymongo.post('/refunds', {
      data: {
        attributes: {
          amount: amountToRefund,
          payment_id: paymongoPaymentId,
          reason: 'requested_by_customer',
          notes: notes || 'Refund',
        },
      },
    });

    return res.data.data;
  } catch (error) {
    logger.error(
      `PayMongo refundPayment error: ${JSON.stringify(
        {
          error: error.response?.data || error.message,
          stack: error.stack,
        },
        null,
        2,
      )}`,
    );

    return { error };
  }
}

module.exports = {
  checkoutSession,
  formatAmount,
  getPaymentStatus,
  parseAmount,
  refundPayment,
};
