const { Op } = require('sequelize');
const { Transactions, Bookings, Listings, ListingImages, Users } = require('../../../models');
const { formatModelData, formatImage } = require('../../../util/formatter');
const { errorHandler } = require('../../../util');

exports.getUserTransactions = async (req, res, next) => {
  try {
    const { userId } = req;

    let transactions = await Transactions.findAll({
      where: {
        [Op.or]: [{ customer_id: userId }, { host_id: userId }],
      },
      attributes: {
        exclude: ['customer_id', 'host_id', 'booking_id'],
      },
      include: [
        {
          model: Bookings,
          as: 'booking',
          attributes: ['check_in', 'check_out'],
          include: [
            {
              model: Listings,
              as: 'listing',
              attributes: ['id'],
              include: [
                {
                  model: ListingImages,
                  as: 'listingImages',
                  attributes: ['image'],
                  limit: 1,
                },
              ],
            },
          ],
        },
        // {
        // 	model: Users,
        // 	as: 'customer',
        // 	attributes: ['id', 'firstname', 'lastname'],
        // },
        // {
        // 	model: Users,
        // 	as: 'host',
        // 	attributes: ['id', 'firstname', 'lastname'],
        // },
      ],
      order: [['createdAt', 'DESC']],
    });

    transactions = formatModelData(transactions);

    transactions = transactions.map((transaction) => {
      transaction.checkIn = transaction.booking?.checkIn;
      transaction.checkOut = transaction.booking?.checkOut;
      transaction.listingImage = formatImage(transaction.booking?.listing?.listingImages[0]?.image);
      delete transaction.booking;

      return transaction;
    });

    return res.status(200).json({
      success: true,
      data: transactions,
    });
  } catch (error) {
    next(error);
  }
};

exports.getTransactions = async (req, res, next) => {
  try {
    let transactions = await Transactions.findAll();

    if (!transactions) {
      return res.status(404).json({
        success: false,
        message: 'Transaction not found',
      });
    }

    transactions = formatModelData(transactions);

    return res.status(200).json({
      success: true,
      data: transactions,
    });
  } catch (error) {
    next(error);
  }
};

exports.updateTransaction = async (req, res, next) => {
  try {
    const { userId } = req;
    const { id } = req.params;
    const { status, method, amount } = req.body;

    let transaction = await Transactions.findOne({
      where: {
        customer_id: userId,
        id,
      },
    });

    if (!transaction) {
      return res.status(404).json({
        success: false,
        message: 'Transaction not found',
      });
    }

    if (transaction.type === 'Refund') {
      if (amount) {
        if (Number(amount) > Number(transaction.amount)) {
          errorHandler(
            'Refund amount must be greater than or equal to the transaction amount',
            400,
          );
        }
      }
    }

    transaction.status = status ?? transaction.status;
    transaction.method = method ?? transaction.method;

    await transaction.save();

    transaction = formatModelData(transaction);

    return res.status(200).json({
      success: true,
      data: transaction,
    });
  } catch (error) {
    next(error);
  }
};
