"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.downloadInvoice = exports.handleGatewayWebhook = exports.handleGatewayCallback = exports.getPaymentStatus = exports.getPaymentById = exports.getPayments = exports.getPaymentHistory = exports.cancelPayment = exports.retryPayment = exports.refundPayment = exports.verifyPayment = exports.createPayment = void 0;
const payment_service_1 = require("../services/payment.service");
const response_utils_1 = require("../../../utils/response.utils");
const database_1 = __importDefault(require("../../../config/database"));
const logger_1 = require("../../../config/logger");
// 1. Create Payment Order / Checkout Session
const createPayment = async (req, res) => {
    try {
        const { orderId, gateway, method } = req.body;
        const userId = req.user?.userId;
        if (!userId)
            return (0, response_utils_1.sendError)(res, 'Unauthenticated', null, 401);
        const paymentDetails = await payment_service_1.PaymentService.initiatePayment(orderId, gateway, userId, method);
        return (0, response_utils_1.sendSuccess)(res, 'Payment checkout session created', paymentDetails);
    }
    catch (error) {
        logger_1.logger.error('Failed to initiate payment:', error);
        return (0, response_utils_1.sendError)(res, 'Payment initiation failed', error.message, 500);
    }
};
exports.createPayment = createPayment;
// 2. Verify Payment (Server-side check)
const verifyPayment = async (req, res) => {
    try {
        const { orderId, payload } = req.body;
        const verification = await payment_service_1.PaymentService.verifyPayment(orderId, payload);
        return (0, response_utils_1.sendSuccess)(res, 'Payment verification response', verification);
    }
    catch (error) {
        logger_1.logger.error('Payment verification failed:', error);
        return (0, response_utils_1.sendError)(res, 'Payment verification failed', error.message, 500);
    }
};
exports.verifyPayment = verifyPayment;
// 3. Process Refund (Admin)
const refundPayment = async (req, res) => {
    try {
        const { paymentId, amount, reason } = req.body;
        const result = await payment_service_1.PaymentService.processRefund(paymentId, amount, reason);
        return (0, response_utils_1.sendSuccess)(res, 'Refund processed successfully', result);
    }
    catch (error) {
        logger_1.logger.error('Refund processing failed:', error);
        return (0, response_utils_1.sendError)(res, 'Refund processing failed', error.message, 500);
    }
};
exports.refundPayment = refundPayment;
// 4. Retry Failed Payment
const retryPayment = async (req, res) => {
    try {
        const { orderId, gateway } = req.body;
        const userId = req.user?.userId;
        if (!userId)
            return (0, response_utils_1.sendError)(res, 'Unauthenticated', null, 401);
        const paymentDetails = await payment_service_1.PaymentService.initiatePayment(orderId, gateway, userId);
        return (0, response_utils_1.sendSuccess)(res, 'Payment retry order initiated', paymentDetails);
    }
    catch (error) {
        return (0, response_utils_1.sendError)(res, 'Payment retry failed', error.message, 500);
    }
};
exports.retryPayment = retryPayment;
// 5. Cancel Payment Session
const cancelPayment = async (req, res) => {
    try {
        const { paymentId } = req.body;
        await database_1.default.payment.update({
            where: { id: paymentId },
            data: { status: 'CANCELLED' },
        });
        return (0, response_utils_1.sendSuccess)(res, 'Payment session cancelled');
    }
    catch (error) {
        return (0, response_utils_1.sendError)(res, 'Cancellation failed', error.message, 500);
    }
};
exports.cancelPayment = cancelPayment;
// 6. Get Payment History (Current User)
const getPaymentHistory = async (req, res) => {
    try {
        const userId = req.user?.userId;
        const history = await database_1.default.payment.findMany({
            where: { userId },
            include: { order: true },
            orderBy: { createdAt: 'desc' },
        });
        return (0, response_utils_1.sendSuccess)(res, 'Payment history retrieved', { history });
    }
    catch (error) {
        return (0, response_utils_1.sendError)(res, 'Failed to fetch payment history', error.message, 500);
    }
};
exports.getPaymentHistory = getPaymentHistory;
// 7. Get All Payments Log (Admin)
const getPayments = async (req, res) => {
    try {
        const payments = await database_1.default.payment.findMany({
            include: {
                user: true,
                order: true,
            },
            orderBy: { createdAt: 'desc' },
            take: 100,
        });
        return (0, response_utils_1.sendSuccess)(res, 'All payments retrieved', { payments });
    }
    catch (error) {
        return (0, response_utils_1.sendError)(res, 'Failed to fetch payments log', error.message, 500);
    }
};
exports.getPayments = getPayments;
// 8. Get Single Payment Details
const getPaymentById = async (req, res) => {
    try {
        const { id } = req.params;
        const payment = await database_1.default.payment.findUnique({
            where: { id },
            include: {
                order: true,
                attempts: true,
                transactions: true,
                refunds: true,
                invoices: true,
            },
        });
        if (!payment)
            return (0, response_utils_1.sendError)(res, 'Payment not found', null, 404);
        return (0, response_utils_1.sendSuccess)(res, 'Payment details retrieved', { payment });
    }
    catch (error) {
        return (0, response_utils_1.sendError)(res, 'Failed to fetch payment details', error.message, 500);
    }
};
exports.getPaymentById = getPaymentById;
// 9. Check Payment Status
const getPaymentStatus = async (req, res) => {
    try {
        const { id } = req.params;
        const payment = await database_1.default.payment.findUnique({
            where: { id },
            select: { status: true, gatewayPaymentId: true, gatewayTransactionId: true },
        });
        if (!payment)
            return (0, response_utils_1.sendError)(res, 'Payment not found', null, 404);
        return (0, response_utils_1.sendSuccess)(res, 'Payment status checked', payment);
    }
    catch (error) {
        return (0, response_utils_1.sendError)(res, 'Status fetch failed', error.message, 500);
    }
};
exports.getPaymentStatus = getPaymentStatus;
// 10. Unified Gateway Callbacks
const handleGatewayCallback = async (req, res) => {
    try {
        const { gateway } = req.params;
        const payload = { ...req.query, ...req.body };
        logger_1.logger.info(`Received callback from gateway: ${gateway}`);
        // Respond with redirect to frontend payment success/failure page
        return res.redirect(`${process.env.FRONTEND_URL || 'http://localhost:3000'}/payment/status?gateway=${gateway}&status=success`);
    }
    catch (error) {
        logger_1.logger.error('Callback error:', error);
        return res.redirect(`${process.env.FRONTEND_URL || 'http://localhost:3000'}/payment/status?status=failed`);
    }
};
exports.handleGatewayCallback = handleGatewayCallback;
// 11. Unified Gateway Webhooks
const handleGatewayWebhook = async (req, res) => {
    try {
        const { gateway } = req.params;
        const signature = (req.headers['x-razorpay-signature'] ||
            req.headers['stripe-signature'] ||
            req.headers['x-verify']);
        const result = await payment_service_1.PaymentService.handleWebhook(gateway, req.body, signature);
        return res.status(200).json({ status: 'ok', result });
    }
    catch (error) {
        logger_1.logger.error(`Webhook handling failed for ${req.params.gateway}:`, error);
        return res.status(500).json({ status: 'error', message: error.message });
    }
};
exports.handleGatewayWebhook = handleGatewayWebhook;
// 12. Download Tax Invoice Receipt
const downloadInvoice = async (req, res) => {
    try {
        const { invoiceNumber } = req.params;
        const invoice = await database_1.default.invoice.findUnique({
            where: { invoiceNumber },
            include: { payment: { include: { order: { include: { user: true, shippingAddress: true, items: { include: { book: true } } } } } } },
        });
        if (!invoice)
            return (0, response_utils_1.sendError)(res, 'Invoice not found', null, 404);
        // Mock PDF buffer response representing the generated official PDF tax invoice
        res.setHeader('Content-Type', 'application/pdf');
        res.setHeader('Content-Disposition', `attachment; filename=invoice_${invoiceNumber}.pdf`);
        const mockPdfBuffer = Buffer.from('%PDF-1.4 Mock Tax Invoice PDF Content representing Indian Books Worldwide');
        return res.status(200).send(mockPdfBuffer);
    }
    catch (error) {
        return (0, response_utils_1.sendError)(res, 'Invoice download failed', error.message, 500);
    }
};
exports.downloadInvoice = downloadInvoice;
//# sourceMappingURL=payment.controller.js.map