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

// Get all products
exports.getAllRpafPayment = async (req, res) => {
  try {
    const rpafp = await RpafPayment.findAll();

    const rpafPresponse = rpafp.map(
      (rpafP = ({
        reference_no,
        cheque_no,
        customer_id,
        order_id,
        amount_paid,
        remainBalance,
        file_attach,
        status,
      }) => ({
        reference_no: reference_no,
        cheque_no: cheque_no,
        customer_id: customer_id,
        order_id: order_id,
        amount_paid: amount_paid,
        remainBalance: remainBalance,
        file_attach: file_attach,
        status: status,
      }))
    );
    res.status(200).json(rpafPresponse);
  } catch (error) {
    console.error(error);
    res.status(500).json({ error: "Internal Server Error" });
  }
};

// Get a specific product by ID
exports.getrpafPId = async (req, res) => {
  const { rpafPID } = req.params;

  try {
    const rpafP = await RpafPayment.findByPk(rpafPID);

    if (!rpafP) {
      return res.status(404).json({ error: "RpafPayment ID not found" });
    }

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

// Delete a product by ID
exports.deleterpafP = (req, res) => {
  const { rpafPID } = req.params;

  try {
    const deletedRowCount = RpafPayment.destroy({
      where: {
        id: rpafPID,
      },
    });

    if (deletedRowCount === 0) {
      return res.status(404).json({ error: "Rpaf-Payment not found" });
    }

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

exports.createRpafPayment = (req, res, next) => {
  // Log the request body
  const { data } = req.body;
  const {
    cheque_no = null,
    order_id,
    customer_id,
    amount_paid,
    remainBalance,
    status,
  } = data;

  // Generate a random reference number with the letters "REFNO"
  const reference_no =
    "RPREF" + Math.random().toString(36).substring(2, 10).toUpperCase();

  if (status !== "Verified" && status !== "Denied") {
    return errorHandler('status must be "Verified", "Denied"', 404);
  }

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

  const { rpafpaymentPhoto } = req.files;

  RpafPayment.findOne({
    where: {
      reference_no: reference_no,
    },
  })
    .then((rpafP) => {
      if (rpafP) {
        return errorHandler("RpafPaymentHead ID already exists!", 401);
      }

      return new RpafPayment({
        reference_no: reference_no,
        cheque_no: cheque_no,
        customer_id: customer_id,
        order_id: order_id,
        amount_paid: amount_paid,
        remainBalance: remainBalance,
        file_attach: rpafpaymentPhoto[0].filename || null,
        status: status,
      }).save();
    })
    .then(() => {
      res.status(201).json({ success: true });
    })
    .catch((err) => {
      next(err);
    });
};

// Update a product by ID
exports.updaterpafP = (req, res) => {
  const { rpafPID } = req.params; // id
  const { data } = req.body;
  const { cheque_no, customer_id, amount_paid, remainBalance, status } = data;

  const { rpafpaymentPhoto } = req.files;

  RpafPayment.findOne({
    where: {
      id: rpafPID,
    },
  })
    .then((rpafp) => {
      if (!rpafp) {
        return errorHandler("Rpaf Payment Head ID does not exists!", 404);
      }

      if (status !== "Verified" && status !== "Denied") {
        return errorHandler('status must be "Verified", "Denied"', 404);
      }

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

      (rpafp.cheque_no = cheque_no),
        (rpafp.customer_id = customer_id),
        (rpafp.amount_paid = amount_paid);
      rpafp.remainBalance = remainBalance;
      rpafp.status = status;

      return rpafp.save();
    })
    .then(() => {
      res.status(200).json({ success: true });
    });
};

exports.getRpafPaymentByCustomerId = async (req, res, next) => {
  const { customerId } = req.params;

  try {
    // Query Order Form
    const orderForm = await OrderForm.findAll({
      where: {
        customer_id: customerId,
        payment_method: { [Op.or]: ["RPAF", "Split"] },
        status: { [Op.ne]: "Not pending" },
      },
    });

    let remainingBalance = 0;
    let rpafPayments = [];

    for (let orderFormInfo of orderForm) {
      // Query Rpaf Payment
      const rpafP = await RpafPayment.findAll({
        where: {
          customer_id: customerId,
          order_id: orderFormInfo.reference_no,
          status: "Verified",
        },
        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 = rpafP[0].sum_amount_paid;
      console.log(`The Total Amount Paid is: ${totalAmountPaid}`);

      // remainBalance = total_amount (invoice amount) - amount_paid^i
      remainingBalance = invoiceAmount - totalAmountPaid;
      console.log(`The REMAINING BALANCE is: ${remainingBalance}`);

      const rpafPaymentArray = rpafP.map(({ id }) => ({
        id: id,
        order_id: orderFormInfo.reference_no,
        invoiceAmount: parseFloat(invoiceAmount),
        remainBalance: remainingBalance,
      }));

      rpafPayments.push(rpafPaymentArray);
    }

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

exports.createRpafMultiplePayments = async (req, res, next) => {
  const data = req.body.data;
  const orders = data.orders;
  const { rpafpaymentPhoto } = req.files;

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

  // Generate cheque number
  const cheque_no =
    "CHEQUEP" + Math.random().toString(36).substring(2, 10).toUpperCase();

  try {
    for (order of orders) {
      const { order_id, remaining_balance, amount, status } = order;

      // Generate reference number
      const reference_no =
        "RPREF" + Math.random().toString(36).substring(2, 10).toUpperCase();

      RpafPayment.create({
        reference_no: reference_no,
        cheque_no: cheque_no,
        customer_id: data.customerId,
        order_id: order_id,
        amount_paid: amount,
        remainBalance: remaining_balance,
        file_attach: rpafpaymentPhoto[0].filename || null,
        status: status,
      });
    }

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