const { QueryTypes } = require('sequelize');
const { CustomerReviews, Users, sequelize, Bookings } = require('../../models');
const { paginate } = require('../../util/pagination');
const { formatTimestamp } = require('../../util');

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

		const host = await Users.findByPk(userId);

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

		if (!host.is_host) {
			return res.status(403).json({
				success: false,
				message: 'You are not authorized to review this customer',
			});
		}

		const hasValidBooking = await sequelize.query(
			`SELECT 
    			COUNT(*) as count
			FROM 
    			bookings 
			WHERE 
    			host_id = ?
    		AND customer_id = ?
    		AND status IN ('Done', 'Cancelled')`,
			{
				type: QueryTypes.SELECT,
				replacements: [userId, customerId],
			},
		);

		if (!hasValidBooking[0].count) {
			return res.status(403).json({
				success: false,
				message: 'You are not authorized to review this customer, no valid booking found',
			});
		}

		await CustomerReviews.create({
			content: req.body.content,
			rating: req.body.rating,
			host_id: userId,
			user_id: customerId,
		});

		return res.status(201).json({
			success: true,
			message: 'Review created successfully',
		});
	} catch (error) {
		next(error);
	}
};

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

		const review = await CustomerReviews.findOne({
			where: { id: reviewId },
		});

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

		if (review.host_id !== userId) {
			return res.status(403).json({
				success: false,
				message: 'You are not authorized to update this review',
			});
		}

		for (const key of ['rating', 'content']) {
			if (key in req.body) {
				review[key] = req.body[key];
			}
		}

		await review.save();

		return res.status(200).json({
			success: true,
			message: 'Review updated successfully',
		});
	} catch (error) {
		next(error);
	}
};

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

		const review = await CustomerReviews.findOne({
			where: { id: reviewId },
		});

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

		if (review.host_id !== userId) {
			return res.status(403).json({
				success: false,
				message: 'You are not authorized to delete this review',
			});
		}

		await review.destroy();

		return res.status(200).json({
			success: true,
			message: 'Review deleted successfully',
		});
	} catch (error) {
		next(error);
	}
};

exports.getReviews = async (req, res, next) => {
	try {
		const { customerId } = req.params;

		if (!customerId) {
			return res.status(400).json({
				success: false,
				message: 'Please provide a listing id',
			});
		}

		const reviews = await sequelize.query(
			`
			SELECT
				cr.id,
				cr.rating,
				cr.content,
				cr.createdAt,
				u.id AS userId,
				u.firstName,
				u.lastName,
				u.image,
				u.id as user_id
			FROM customer_reviews cr
			LEFT JOIN users u ON cr.host_id = u.id
			WHERE cr.user_id = ?
			`,
			{
				type: QueryTypes.SELECT,
				replacements: [customerId],
			},
		);

		const cleanReviews = reviews.map((review) => {
			return {
				id: review.id,
				rating: review.rating,
				content: review.content,
				createdAt: formatTimestamp(review.createdAt),
				host: {
					fullname: `${review.firstName || ''} ${review.lastName || ''}`.trim() || 'Deleted User',
					image: review.image ? `${process.env.BASE_URL}/public/user-uploads/${review.image}` : null,
					id: review.userId,
				},
			};
		});

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

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