const Vouchers = require("../models/Vouchers");
const jwt = require("jsonwebtoken");
const errorHandler = require("../util/errorHandler");
const { Op } = require("sequelize");
const UserCart = require("../models/UserCart");
const Products = require("../models/Products");
const SellersCompany = require("../models/SellersCompany");

// Create a new Voucher
exports.createVoucher = async (req, res, next) => {
  try {
    const { voucher_code, amount, amount_in_percent, status, valid_until } =
      req.body;

    Vouchers.create({
      voucher_code: voucher_code,
      amount: amount,
      amount_in_percent: amount_in_percent,
      status: status,
      valid_until: valid_until,
    });

    res.status(201).json({ success: "Voucher successfully created!" });
  } catch (err) {
    next(err);
  }
};

// Get all voucher
exports.getAllVoucher = async (req, res) => {
  try {
    const currentDate = new Date();

    const vouchers = await Vouchers.findAll({
      where: {
        status: true,
        valid_until: {
          [Op.gte]: currentDate,
        },
      },
    });

    const voucherResponse = vouchers.map(
      (voucher = ({
        voucher_code,
        amount,
        amount_in_percent,
        agent,
        status,
        valid_until,
        in_percent,
        seller_voucher,
      }) => ({
        voucher_code: voucher_code,
        amount: amount,
        amount_in_percent: amount_in_percent,
        agent: agent,
        status: status,
        valid_until: valid_until,
        in_percent: in_percent,
        seller_voucher: seller_voucher,
      }))
    );

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

// Get Voucher by Id
exports.getVoucherId = async (req, res) => {
  const { VoucherId } = req.params;

  try {
    const voucher = await Vouchers.findByPk(VoucherId);

    if (!voucher) {
      return res.status(404).json({ error: "Voucher not found" });
    }

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

exports.getVoucherByVoucherCode = async (req, res) => {
  const { voucherCode } = req.params;
  const { t } = req.query;
  const { customerId } = req;

  try {
    const userCartPromise = UserCart.findAll({
      where: {
        user_id: customerId,
      },
    });

    const startOfToday = new Date();
    startOfToday.setHours(0, 0, 0, 0);

    const voucherPromise = Vouchers.findOne({
      where: {
        voucher_code: voucherCode,
        status: true,
        valid_until: {
          [Op.gte]: startOfToday,
        },
      },
    });

    const [userCart, voucher] = await Promise.all([
      userCartPromise,
      voucherPromise,
    ]);

    if (!userCart || !userCart.length > 0)
      return res.status(400).json({ success: false, error: "Empty cart" });
    if (!voucher) return res.status(404).json({ error: "Voucher not found" });

    const productDetail = await Products.findByPk(userCart[0].menu_id);

    const productSellerId = productDetail.seller_id;

    const sellerDetail = await SellersCompany.findOne({
      where: {
        id: productSellerId,
      },
    });

    const voucherSellerId = voucher.seller_voucher;

    const voucherParentCompanyId = voucher.parent_company_id;
    const voucherIsAvailableToChild = voucher.available_to_child;

    const isVoucherHasSellerId =
      voucherSellerId !== null && voucherSellerId !== "";
    const isVoucherHasParentCompanyId =
      voucherParentCompanyId !== null && voucherParentCompanyId !== "";

    let isValidVoucher = true;
    if (isVoucherHasSellerId) {
      if (productSellerId !== voucherSellerId) isValidVoucher = false;
    }

    if (isVoucherHasParentCompanyId) {
      if (voucherParentCompanyId !== productSellerId) isValidVoucher = false;

      if (voucherIsAvailableToChild) {
        const sellerParentCompanyId = sellerDetail.parent_company;
        if (sellerParentCompanyId === voucherParentCompanyId) {
          isValidVoucher = true;
        } else {
          isValidVoucher = false;
        }
      }
    }

    if (voucher && voucher.min_amount_requirement != null) {
      const parsedMinAmount = parseFloat(voucher.min_amount_requirement);
      const parsedTotal = parseFloat(t);

      if (
        !isNaN(parsedMinAmount) &&
        !isNaN(parsedTotal) &&
        parsedTotal < parsedMinAmount
      ) {
        isValidVoucher = false;
      }
    }

    if (
      voucher &&
      (voucher.amount == null || voucher.amount === "") &&
      (voucher.amount_in_percent == null || voucher.amount_in_percent === "")
    ) {
      isValidVoucher = false;
    }
    if (isValidVoucher) {
      res.status(200).json(voucher);
    } else {
      res.status(404).json({ error: "Voucher not found" });
    }
  } catch (error) {
    console.error(error);
    res.status(500).json({ error: "Internal Server Error" });
  }
};

// Delete Voucher
exports.deleteVoucherId = async (req, res) => {
  const { VoucherId } = req.params;

  try {
    const voucher = await Vouchers.findByPk(VoucherId);

    if (!voucher) {
      return res.status(404).json({ error: "Voucher not found" });
    }

    await voucher.destroy();

    res.status(201).json({ success: "The Voucher successfully Deleted" });
  } catch (error) {
    console.error(error);
    res.status(500).json({ error: "Internal Server Error" });
  }
};

// Update Voucher by ID
exports.updateVoucher = async (req, res) => {
  const { VoucherId } = req.params;
  try {
    const voucher = await Vouchers.findByPk(VoucherId);

    if (!voucher) {
      return res.status(404).json({ error: "Voucher not found" });
    }

    const { voucher_code, amount, amount_in_percent, status, valid_until } =
      req.body;

    await voucher.update({
      voucher_code,
      amount,
      amount_in_percent,
      status,
      valid_until,
    });

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