const { Op } = require('sequelize');
const { Bookings, Listings, ListingImages, Users, BookingAddOns } = require('../../models');
const { paginate } = require('../../util/pagination');

exports.hostCalendar = async (req, res, next) => {
	const { startDate, endDate, listingId } = req.query;

	try {
		if (!startDate || !endDate) {
			return res.status(400).json({ success: false, message: 'Start date and end date are required' });
		}

		const filter = {
			[Op.or]: {
				check_in: {
					[Op.between]: [startDate, endDate],
				},
				check_out: {
					[Op.between]: [startDate, endDate],
				},
			},
		};

		if (listingId) {
			filter.listing_id = listingId;
		}

		const data = await Bookings.findAll({
			where: {
				...filter,
			},
			attributes: [
				'id',
				'check_in',
				'check_out',
				'status',
				'pax',
				'createdAt',
				'payment_option',
				'payment_method',
				'payment_status',
				'listing_id',
				'amount_paid',
				'balance',
				'total_amount',
				'phone_no',
			],
			include: [
				{
					model: Listings,
					as: 'listing',
					attributes: ['id', 'name', 'address_city', 'address_country', 'price'],
					include: [
						{
							model: ListingImages,
							as: 'listingImages',
							attributes: ['image'],
						},
					],
				},
				{
					model: Users,
					as: 'customers',
					attributes: ['id', 'firstname', 'lastname', 'image', 'address_city', 'address_country'],
				},
				{
					model: BookingAddOns,
					as: 'addOns',
					attributes: ['id', 'add_on_name', 'quantity', 'price', 'total_amount'],
				},
			],
		});

		const mappedData = data?.map((booking) => {
			const bookingData = booking;
			const listing = bookingData?.listing ?? {};
			const customer = bookingData?.customers ?? {};

			const mapData = {
				id: bookingData.id,
				checkIn: bookingData.check_in,
				checkOut: bookingData.check_out,
				status: bookingData.status,
				pax: bookingData.pax,
				createdAt: bookingData.createdAt,
				paymentMethod: bookingData.payment_method,
				paymentStatus: bookingData.payment_status,
				price: listing.price,
				amountPaid: bookingData.amount_paid,
				balance: bookingData.balance,
				totalAmount: bookingData.total_amount,
				phoneNo: customer.phone_no,
			};

			const listingData = listing?.id
				? {
						id: listing.id,
						name: listing.name,
						address:
							listing.address_city && listing.address_country
								? `${listing.address_city}, ${listing.address_country}`
								: null,
						price: listing.price,
						image: listing?.listingImages?.[0]?.image
							? `${process.env.BASE_URL}/public/host-uploads/${listing.listingImages[0].image}`
							: null,
					}
				: null;

			const customerData = customer?.id
				? {
						fullname: `${customer.firstname} ${customer.lastname}`,
						image: customer.image ? `${process.env.BASE_URL}/public/user-uploads/${customer.image}` : null,
						address:
							customer.address_city && customer.address_country
								? `${customer.address_city}, ${customer.address_country}`
								: null,
					}
				: null;

			const addOns =
				bookingData?.addOns?.length > 0
					? bookingData?.addOns?.map((addOn) => ({
							id: addOn.id,
							name: addOn.add_on_name,
							price: addOn.price,
							quantity: addOn.quantity,
							totalAmount: addOn.total_amount,
						}))
					: null;

			return {
				...mapData,
				listing: listingData,
				customer: customerData,
				addOns,
			};
		});

		const paginated = paginate(mappedData, req.query?.page, req.query?.limit);

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