const { Op } = require('sequelize');
const { calculateNights } = require('../../helpers');
const { checkManagerAccess } = require('../../helpers/managers');
const { Users, Listings, Bookings } = require('../../models');
const {
  getMonthlyOccupancyRate,
  getTotalEarnings,
  getTotalBookings,
  getYearToDateSummary,
  getDailyTraffic,
  getMonthlyTraffic,
  getBookingConversionRate,
  getEarningsByMonth,
} = require('../../services');
const { formatImage } = require('../../util/formatter');

exports.getPerformanceData = async (req, res, next) => {
  try {
    let userId = req.userId;
    if (req.query.hostId) {
      userId = (await checkManagerAccess(req)).hostId;
    }
    const { filter, date, month, year } = req.query; // filter can be 'date', 'month', 'last_6_months', or 'year'

    const currentDate = new Date();
    const currentMonth = currentDate.getMonth() + 1; // Months are 0-indexed
    const currentYear = currentDate.getFullYear();
    const currentYYYYMM = `${currentYear}-${currentMonth.toString().padStart(2, '0')}`;

    Promise.all([
      getTotalEarnings(userId, filter, date, month, year),
      getMonthlyOccupancyRate(userId),
      getTotalBookings(userId, filter, date, month, year),
      getYearToDateSummary(userId),
      getDailyTraffic(userId),
      getMonthlyTraffic(userId),
      getBookingConversionRate(userId),
      getEarningsByMonth(currentYYYYMM, userId),
    ])
      .then(
        async ([
          totalEarnings,
          monthlyOccupancyRates,
          totalBookings,
          yearToDateSummary,
          dailyTraffic,
          monthlyTraffic,
          bookingConversionRate,
          earningsThisMonth,
        ]) => {
          let upcomingBookings = await Bookings.findAll({
            where: {
              host_id: userId,
              status: {
                [Op.in]: ['Upcoming', 'Ongoing'],
              },
            },
            order: [['createdAt', 'DESC']],
            limit: 5,
            include: [
              {
                model: Users,
                as: 'customers',
              },
              {
                model: Listings,
                as: 'listing',
              },
            ],
          });

          upcomingBookings = upcomingBookings.map((booking) => {
            const numberOfNights = calculateNights(booking.check_in, booking.check_out);

            return {
              id: booking.id,
              customerName: booking.customers
                ? `${booking.customers.firstname || ''} ${booking.customers.lastname || ''}`.trim()
                : 'N/A',
              listingName: booking.listing ? booking.listing.name : 'N/A',
              pax: booking.pax,
              totalAmount: booking.total_amount,
              numberOfNights,
              status: booking.status,
              image: booking?.customers?.image
                ? formatImage(booking.customers.image, 'user-uploads')
                : null,
            };
          });

          res.status(200).json({
            success: true,
            totalEarnings,
            totalBookings,
            yearToDateSummary,
            dailyTraffic,
            monthlyTraffic,
            monthlyOccupancyRates,
            upcomingBookings,
            bookingConversionRate,
            earningsThisMonth,
          });
        },
      )
      .catch((err) => {
        next(err);
      });
  } catch (error) {
    next(error);
  }
};
