const Payments = require('../models/paymentsModel');
const Email = require('../models/email');
const axios = require('axios');
require('dotenv').config();

const PaymentsController = {

    //get all donations
    getAllDonations: async (req, res, next) => {
        try {
            const donations = await Payments.getAllDonations();

            res.status(200).json({
                success: true,
                statusCode: 200,
                message: "Donations retrieved successfully",
                data: donations
            });
        } catch (error) {
            next(error);
        }
    },

    //get all donations for a  specific user
    getMyDonations: async (req, res, next) => {
        try {
            const userId = req.userId;
            const donations = await Payments.getMyDonations(userId);

            res.status(200).json({
                success: true,
                statusCode: 200,
                message: "User donations retrieved successfully",
                data: donations
            });
        } catch (error) {
            next(error);
        }
    },

    //create donation record
    createDonation: async (req, res, next) => {
        try {
            const {
                payment_method,
                amount,
                transaction_id
            } = req.body;
            const user_id = req.userId;

            // Validate required fields
            if (!payment_method || !amount || !transaction_id) {
                return res.status(400).json({
                    success: false,
                    statusCode: 400,
                    message: "Missing required fields: payment_method, amount, or transaction_id"
                });
            }

            // Create the donation record
            const result = await Payments.createDonation(
                user_id,
                payment_method,
                amount,
                transaction_id
            );

            res.status(201).json({
                success: true,
                statusCode: 201,
                message: "Donation created successfully",
                data: {
                    paymentId: result.paymentId,
                    amount: amount,
                    transaction_id: transaction_id,
                    status: 'pending'
                }
            });
        } catch (error) {
            // Handle duplicate transaction_id error
            if (error.code === 'ER_DUP_ENTRY') {
                return res.status(409).json({
                    success: false,
                    statusCode: 409,
                    message: "Transaction ID already exists"
                });
            }
            next(error);
        }
    },


    updatePaymentStatus: async (req, res, next) => {
        try {
            const {
                transaction_id
            } = req.params;
            const {
                status
            } = req.body;

            // Validate status input
            if (!['pending', 'completed', 'failed'].includes(status)) {
                return res.status(400).json({
                    success: false,
                    statusCode: 400,
                    message: "Invalid status. Must be one of: pending, completed, failed"
                });
            }

            // Call model method to update status
            const result = await Payments.updatePaymentStatus(transaction_id, status);

            if (result.affectedRows === 0) {
                return res.status(404).json({
                    success: false,
                    statusCode: 404,
                    message: "Transaction not found"
                });
            }

            res.status(200).json({
                success: true,
                statusCode: 200,
                message: "Payment status updated successfully",
                data: {
                    transaction_id: result.transaction_id,
                    new_status: result.new_status
                }
            });
        } catch (error) {
            next(error);
        }
    },

    paychanguWebhook: async (req, res, next) => {
        try {
            const {
                charge_id,
                status,
                amount,
                reference
            } = req.body;

            // Validate required fields
            if (!charge_id || !status) {
                throw new Error("verificationError")
            }


            const PAYCHANGU_KEY = process.env.PAYCHANGU_KEY;
            // First verify the transaction with Paychangu API
            let verificationData;
            try {
                const response = await axios.get(
                    `https://api.paychangu.com/mobile-money/payments/${charge_id}/verify`, {
                        headers: {
                            'Accept': 'application/json',
                            'Authorization': `Bearer ${PAYCHANGU_KEY}`
                        }
                    }
                );
                verificationData = response.data;
            } catch (verificationError) {
                if (verificationError.response && verificationError.response.status === 400) {
                    // If it's a 400 error, we still want to get the response data
                    verificationData = verificationError.response.data;
                } else {
                    // For other errors, throw as before
                    throw new Error(verificationError);
                }
            }

            // Verify the status matches between webhook and API verification
            const verifiedStatus = verificationData.data?.status;
            if (!verifiedStatus || verifiedStatus.toLowerCase() !== status.toLowerCase()) {
                throw new Error("soo=ry")
            }

            // Get payment record and user email
            const paymentRecord = await Payments.getPaymentByTransactionId(charge_id);

            if (!paymentRecord) {
                throw new Error("not available")
            }

            // Process the webhook since verification matches
            const result = await Payments.handlePaychanguWebhook(
                charge_id,
                status,
                amount || verificationData.data?.amount,
                reference || verificationData.data?.ref_id
            );

            // Send appropriate email based on status
            try {
                const paymentAmount = amount || verificationData.data?.amount || paymentRecord.amount;
                if (status.toLowerCase() === 'success') {
                    await Email.sendPaymentSuccessEmail(paymentRecord.email, paymentAmount);
                } else {
                    await Email.sendPaymentFailedEmail(paymentRecord.email, paymentAmount);
                }
            } catch (emailError) {
                console.error('Error sending payment status email:', emailError);
                throw new Error("newwwww")
            }

            res.status(200).json({
                success: true,
                statusCode: 200,
                message: `Payment status verified and updated to ${status}`,
                data: {
                    verification: verificationData,
                    payment: result
                }
            });

        } catch (error) {
            throw new Error(error)

            // Handle specific error cases
            if (error.message === "Invalid status received from Paychangu") {
                return res.status(400).json({
                    success: false,
                    statusCode: 400,
                    message: error.message
                });
            }

            if (error.message === "Failed to update payment status") {
                return res.status(500).json({
                    success: false,
                    statusCode: 500,
                    message: error.message
                });
            }

            next(error);
        }
    }

};

module.exports = PaymentsController;