/**
 * Payment Controller
 * Handles payment operations for multiple payment gateways
 */

const { catchAsyncErrors } = require('../middlewares/catchAsyncErrors');
const ErrorHandler = require('../utils/ErrorHandler');
const paymentService = require('../services/payment.service');

/**
 * POST /payment/create-order
 * Create payment order using the active gateway
 */
exports.createPaymentOrder = catchAsyncErrors(async (req, res, next) => {
    const { bookingId, amount, paymentType } = req.body;

    if (!bookingId) {
        return next(new ErrorHandler('Booking ID is required', 400));
    }

    const order = await paymentService.createPaymentOrder(bookingId, amount, paymentType);

    res.status(200).json({
        success: true,
        data: order
    });
});

/**
 * POST /payment/verify
 * Verify payment after completion (supports both Razorpay and Stripe)
 * Razorpay sends: { razorpay_order_id, razorpay_payment_id, razorpay_signature }
 * Stripe sends: { session_id }
 */
exports.verifyPayment = catchAsyncErrors(async (req, res, next) => {
    const { razorpay_order_id, razorpay_payment_id, razorpay_signature, session_id } = req.body;

    // Validate: must have either Razorpay or Stripe verification data
    const hasRazorpayData = razorpay_order_id && razorpay_payment_id && razorpay_signature;
    const hasStripeData = !!session_id;

    if (!hasRazorpayData && !hasStripeData) {
        return next(new ErrorHandler('Missing payment verification data', 400));
    }

    const result = await paymentService.verifyPayment(req.body);

    res.status(200).json({
        success: true,
        data: result
    });
});

/**
 * POST /payment/webhook
 * Handle Razorpay webhook events (no auth - verified by signature)
 */
exports.handleWebhook = catchAsyncErrors(async (req, res, next) => {
    const signature = req.headers['x-razorpay-signature'];

    const result = await paymentService.handleRazorpayWebhook(req.body, signature);

    res.status(200).json({
        success: true,
        data: result
    });
});

/**
 * POST /payment/webhook/stripe
 * Handle Stripe webhook events (no auth - verified by signature)
 * Requires raw body (not parsed JSON)
 */
exports.handleStripeWebhook = catchAsyncErrors(async (req, res, next) => {
    const signature = req.headers['stripe-signature'];

    if (!signature) {
        return next(new ErrorHandler('Missing Stripe signature header', 400));
    }

    // req.body is raw Buffer here (set up in app.js)
    const result = await paymentService.handleStripeWebhook(req.body, signature);

    res.status(200).json({
        success: true,
        data: result
    });
});

/**
 * GET /payment/status/:bookingId
 * Get payment status for a booking
 */
exports.getPaymentStatus = catchAsyncErrors(async (req, res, next) => {
    const status = await paymentService.getPaymentStatus(req.params.bookingId);

    res.status(200).json({
        success: true,
        data: status
    });
});

/**
 * POST /payment/refund
 * Initiate refund for a booking (Admin only)
 */
exports.initiateRefund = catchAsyncErrors(async (req, res, next) => {
    const { bookingId, amount, reason } = req.body;

    if (!bookingId) {
        return next(new ErrorHandler('Booking ID is required', 400));
    }

    const result = await paymentService.initiateRefund(bookingId, amount, reason);

    res.status(200).json({
        success: true,
        data: result
    });
});