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");
const { voucherService } = require("../helpers/voucher.service");
const { isBase64 } = require("../helpers/common");

// 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;

  let decodedKeyword = voucherCode;
  if (voucherCode && isBase64(voucherCode)) {
    try {
      decodedKeyword = decodeURIComponent(
        Buffer.from(voucherCode, "base64").toString("utf-8"),
      );
    } catch {
      decodedKeyword = voucherCode;
    }
  }

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

    const voucherPromise = Vouchers.findOne({
      where: {
        voucher_code: decodedKeyword,
      },
    });

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

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

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

    const productSellerId = productDetail.seller_id;

    const isValidVoucher = await voucherService(
      customerId,
      decodedKeyword,
      productSellerId,
      userCart[0].menu_id,
      parseFloat(t),
    );
    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" });
  }
};
