const OrderForm = require("../../models/OrderForm");
const OrderFormDetails = require("../../models/OrderFormDetails");
const Products = require("../../models/Products");
const Voucher = require("../../models/Vouchers");
const ReturnOrderLog = require("../../models/ReturnOrderLog");
const { Op } = require("sequelize");

exports.returnOrder = async (req, res, next) => {
  try {
    const { order_reference_no, product_id, return_qty } = req.body;

    const orderDetails = await OrderForm.findOne({
      where: {
        reference_no: order_reference_no,
        payment_method: {
          [Op.notIn]: ["BUILDCREDIT INTEREST", "EOS ORDER"],
        },
      },
      attributes: ["id", "total_amount", "delivery_fee", "voucher_id_used", "total_qty"],
      include: [
        {
          model: OrderFormDetails,
          as: "order_form_details",
          attributes: ["product_id", "quantity", "price", "amount"],
          where: {
            product_id: product_id,
          },
          required: true,
        },
        {
          model: Voucher,
          as: "voucher_details",
        },
      ],
    });

    if (!orderDetails) return res.status(400).json({ success: false, message: "Invalid request." });

    const orderTotalAmount = parseFloat(orderDetails?.total_amount);

    const orderShippingFee = parseFloat(orderDetails?.delivery_fee);

    const orderTotalQty = parseFloat(orderDetails?.total_qty);

    const itemBoughtPrice = parseFloat(orderDetails?.order_form_details[0]?.price);

    const itemBoughtQuantity = parseFloat(orderDetails?.order_form_details[0]?.quantity);

    let itemPriceAfterVoucher = itemBoughtPrice;

    if (orderDetails.voucher_details) {
      let voucherAmount = 0;

      const voucherDetails = orderDetails.voucher_details;
      const { amount, amount_in_percent, in_percent } = voucherDetails;

      if (in_percent === "Yes") {
        const parsedAmountInPercent = parseFloat(amount_in_percent);
        voucherAmount = orderTotalAmount * parsedAmountInPercent;
      } else {
        voucherAmount = parseFloat(amount);
      }

      const voucherAmountPerProduct = voucherAmount / orderTotalQty;

      itemPriceAfterVoucher = itemBoughtPrice - voucherAmountPerProduct;
    }

    if (return_qty > itemBoughtQuantity)
      return res
        .status(401)
        .json({ success: false, message: "Invalid request. Return qty is greater than the original quantity." });

    const itemDetailTotalPrice = parseFloat(orderDetails?.order_form_details[0]?.amount);

    const returnQtyTotalAmount = itemPriceAfterVoucher * parseFloat(return_qty);

    let orderTotalAfterReturn = orderTotalAmount - returnQtyTotalAmount;

    orderTotalAfterReturn += orderShippingFee;

    const orderDetailTotalAfterReturn = parseFloat(itemDetailTotalPrice) - returnQtyTotalAmount;

    // UPDATING RECORDS

    // Products Stocks Updates
    const returnItemProduct = await Products.findByPk(product_id);
    returnItemProduct.stocks += parseFloat(return_qty);
    const returnItemProductPromise = returnItemProduct.save();

    // Order Form Detail Updates
    const returnItemOrderFormDetails = await OrderFormDetails.findOne({
      where: {
        order_form_id: orderDetails.id,
        product_id: product_id,
      },
    });
    returnItemOrderFormDetails.quantity -= parseFloat(return_qty);
    returnItemOrderFormDetails.amount = orderDetailTotalAfterReturn;
    const returnItemOrderDetailsPromise = returnItemOrderFormDetails.save();

    // Order Form Updates
    const orderForm = await OrderForm.findOne({
      where: {
        reference_no: order_reference_no,
      },
    });
    orderForm.total_amount = orderTotalAfterReturn;
    orderForm.total_qty -= parseFloat(return_qty);
    const orderFormPromise = orderForm.save();
    // UPDATING RECORDS

    // LOGS
    const returnLogPromise = ReturnOrderLog.create({
      order_id: order_reference_no,
      product_id: product_id,
      original_quantity: itemBoughtQuantity,
      return_quantity: return_qty,
      item_price: itemPriceAfterVoucher,
      order_orig_total: orderTotalAmount,
      order_new_total: orderTotalAfterReturn,
    });
    // LOGS

    await Promise.all([returnItemProductPromise, returnItemOrderDetailsPromise, orderFormPromise, returnLogPromise]);

    res.status(200).json({ success: true });
  } catch (err) {
    next(err);
  }
};
