const LogisticPayment = require("../models/LogisticPayment");
const jwt = require("jsonwebtoken");
const errorHandler = require("../util/errorHandler");
const multer = require('multer');
const OrderForm = require("../models/OrderForm");
const { Sequelize } = require("sequelize");

exports.createLogisticPayment = (req, res, next) => {
    const { data } = req.body;
    const {
        customer_id,
        logistics_fee,
        remaining_balance,
        amount_paid,
        EWT
    } = data;

    const reference_no = "RPEF" + Math.random().toString(36).substring(2, 10).toUpperCase();
    const cheque_ref_no = "CHEQUEP" + Math.random().toString(36).substring(2, 10).toUpperCase();
    const order_id = "ORD" + Math.random().toString(36).substring(2, 10).toUpperCase();

    if (!req.files || !req.files.logisticpaymentPhoto) {
        return errorHandler("LogisticPaymentHead photo is missing from the request.", 500); 
    }

    const { logisticpaymentPhoto } = req.files;

    LogisticPayment.findOne({
        where: {
            reference_no: reference_no,
        },
    })
    .then((logisticPayment) => {
        if(logisticPayment) {
            return errorHandler("LogisticPaymentHead ID already exists!", 401);
        }
        return new LogisticPayment({
            reference_no: reference_no,
            cheque_ref_no: cheque_ref_no,
            customer_id: customer_id,
            order_id: order_id,
            logistics_fee: logistics_fee,
            remaining_balance: remaining_balance,
            amount_paid: amount_paid,
            file_attach: logisticpaymentPhoto[0].filename || null,
            EWT: EWT
        }).save();
    })
    .then(() => {
        res.status(201).json({ success: true });
    })
    .catch((err) => {
        next(err);
    });
};

exports.createLogisticMultiplePayments = (req, res, next) => {
    const data = req.body.data;
    const orders = data.orders;
    const logisticpaymentPhoto = req.files;

    if (!req.files || !req.files.logisticpaymentPhoto) {
        return errorHandler("LogisticPaymentHead photo is missing from the request.", 500);
    }

    const cheque_ref_no = "CHEQUEP" + Math.random().toString(36).substring(2, 10).toUpperCase();

    try {
        for(order of orders) {
            const {
                order_id,
                logistics_fee,
                remaining_balance,
                amount_paid,
            } = order;

            const reference_no = "RPEF" + Math.random().toString(36).substring(2, 10).toUpperCase();

            LogisticPayment.create({
                reference_no: reference_no,
                cheque_ref_no: cheque_ref_no,
                customer_id: data.customer_id,
                order_id: order_id,
                logistics_fee: logistics_fee,
                remaining_balance: remaining_balance,
                amount_paid: amount_paid
            });
        };

        res.status(201).json({ success: true, orders });
    }catch(error) {
        console.error(error);
        res.status(500).json({ error: "internal Server Error "});
    };
};

exports.getLogisticPaymentByCustomerId = async (req, res, next) => {
    const { customerId } = req.params;
    
    try{
        // Query Order Form
        const orderForm = await OrderForm.findAll({
            where: {
                customer_id: customerId,
            }
        });

        let remainingBalance = 0;
        let logisticPayments = [];

        for(let orderFormInfo of orderForm) {
            // Query Logistic Payment
            const logisticPayment =  await LogisticPayment.findAll({
                where:{
                    customer_id: customerId,
                    order_id: orderFormInfo.reference_no,
                },
                attributes: [
                    [Sequelize.fn('SUM', Sequelize.col('amount_paid')), 'sum_amount_paid'],
                ],
                raw: true,
            });

            const invoiceAmount = orderFormInfo.total_amount;
            console.log(`The Invoice Amount is: ${invoiceAmount}`);

            const totalAmountPaid = logisticPayment[0].sum_amount_paid;
            console.log(`The total AMount Paid is: ${totalAmountPaid}`);

            remainingBalance = invoiceAmount - totalAmountPaid;
            console.log(`The REMAINING BALANCE is: ${remainingBalance}`);

            const logisticPaymentArray = logisticPayment.map(
                ({
                    id,
                }) => ({
                    id: id,
                    order_id: orderFormInfo.reference_no,
                    invoiceAmount: parseFloat(invoiceAmount),
                    remaining_balance: remainingBalance,
                })
            );

            logisticPayments.push(logisticPaymentArray);
        }

        res.status(201).json({ success: true, logisticPayments });
    }catch(error){
        console.error(error);
        res.status(500).json({ error: "Internal Server Error" });
    }
};

exports.getLogisticPaymentById = async (req, res, next) => {
    const { logisticPaymentId } = req.params;
    
    try{
        const logisticPayment = await LogisticPayment.findByPk(logisticPaymentId);
        
        if(!logisticPayment) {
            return res.status(400).json({ error: "Logistic Payment ID not found" });
        }

        res.status(200).json({logisticPayment});
    }catch(error) {
        console.error(error);
        res.status(500).json({ error: "Internal Server Error"});
    }
};

exports.getAllLogisticPayment = async (req, res, next) => {
    try{
        const logisticPayment = await LogisticPayment.findAll();

        const logisticPaymentResponse = logisticPayment.map(logisticP =({
            reference_no,
            cheque_ref_no,
            customer_id,
            order_id,
            logistics_fee,
            amount_paid,
            remaining_balance,
            file_attach,
            EWT
        }) => ({
            reference_no: reference_no,
            cheque_ref_no: cheque_ref_no,
            customer_id: customer_id,
            order_id: order_id,
            logistics_fee: logistics_fee,
            amount_paid: amount_paid,
            remaining_balance: remaining_balance,
            file_attach: file_attach,
            EWT: EWT
        })

        );
        res.status(200).json(logisticPaymentResponse);
    }catch(error) {
        console.error(error);
        res.status(500).json({ error: "Internal Server Error" });
    }
};

exports.updateLogisticPayment = (req, res, next) => {
    const { logisticPaymentId } = req.params;
    const { data } = req.body;
    const {
        cheque_ref_no,
        customer_id,
        logistics_fee,
        remaining_balance,
        amount_paid,
    } = data;

    const { logisticpaymentPhoto } = req.files;

    LogisticPayment.findOne({
        where: {
            id: logisticPaymentId,
        },
    })
    .then((logisticPayment) => {
        if(!logisticPayment) {
            return errorHandler("Logistic Payment Head ID does not exist.", 404);
        }

        if(logisticpaymentPhoto && logisticpaymentPhoto.length > 0) {
            logisticPayment.file_attach = logisticpaymentPhoto[0].filename;
        }
        else {
            logisticPayment.file_attach = null;
        }

        logisticPayment.cheque_ref_no = cheque_ref_no,
        logisticPayment.customer_id = customer_id,
        logisticPayment.logistics_fee = logistics_fee,
        logisticPayment.amount_paid = amount_paid,
        logisticPayment.remaining_balance = remaining_balance

        return logisticPayment.save();
    })
    .then(() => {
        res.status(200).json({ success: true });
    })
    .catch((error) => {
        res.status(500).json({ error: "Internal Server Error", error });
    });
};

exports.deleteLogisticPayment = (req, res, next) => {
    const { logisticPaymentId } = req.params;
    try {
        const deletedRowCount = LogisticPayment.destroy({
            where: {
                id: logisticPaymentId,
            }
        })
        if(deletedRowCount === 0) {
            return res.status(404).json({ error: "Logistic Payment Not Found" })
        }

        res.status(204).send();
    }catch(error) {
        console.error(error);
        res.status(500).json({ error: "Internal Server Error"});
    }
};