const { Op } = require('sequelize');

const { parseJsonSafe } = require('../../helpers/jsonResponseParser');
const { HostReviews, Listings, sequelize, Users } = require('../../models');
const { formatTimestamp } = require('../../util');

const getHostProfile = async (req, res, next) => {
  try {
    const { hostId } = req.params;

    let host = await Users.findOne({
      where: { id: hostId, is_host: true },
      attributes: [
        'id',
        'firstname',
        'lastname',
        'image',
        'hosting_date',
        'address_city',
        'address_country',
        'work',
        'languages',
        'about_me',
        'music',
        'pets',
        'hangouts',
        'likes',
        'interests',
        'is_phone_verified',
        'is_email_verified',
        [
          sequelize.literal(
            '(SELECT ROUND(AVG(rating),2) FROM host_reviews WHERE host_reviews.host_id = Users.id)',
          ),
          'averageRating',
        ],
        [
          sequelize.literal(
            '(SELECT COUNT(*) FROM host_reviews WHERE host_reviews.host_id = Users.id)',
          ),
          'reviewsCount',
        ],
      ],
      include: [
        {
          model: HostReviews,
          as: 'hostReviews',
          attributes: ['id', 'content', 'createdAt'],
          include: [
            {
              model: Users,
              attributes: ['id', 'firstName', 'lastName', 'image'],
            },
          ],
        },
        {
          model: Listings,
          where: {
            [Op.or]: [{ status: 'Approved' }, { status: 'Active' }],
            is_deleted: false,
          },
          required: false,
          as: 'listings',
          attributes: [
            'id',
            'name',
            'description',
            'price',
            'address_city',
            'address_country',
            'location',
            [
              sequelize.literal(
                '(SELECT COALESCE(ROUND(AVG(rating),2),0) FROM listing_reviews lr WHERE lr.listing_id = `listings`.`id`)',
              ),
              'averageRating',
            ],
            [
              sequelize.literal(
                '(SELECT image FROM listing_images li WHERE li.listing_id = `listings`.`id` LIMIT 1)',
              ),
              'image',
            ],
          ],
        },
      ],
    });

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

    host = host.get({ plain: true });

    const data = {
      id: host.id,
      image: host?.image ? `${process.env.BASE_URL}/public/user-uploads/${host.image}` : null,
      fullname: `${host.firstname} ${host.lastname}`,
      hostingDate: host?.hosting_date,
      reviewsCount: host?.reviewsCount,
      averageRating: host?.averageRating,
      verified: !!(host.is_phone_verified || host.is_email_verified),
      aboutMe: host?.about_me ?? null,
      work: host?.work ?? null,
      address:
        host?.address_city && host?.address_country
          ? `${host.address_city}, ${host.address_country}`
          : null,
      hobbies: {
        music: host?.music,
        pets: host?.pets,
        hangouts: host?.hangouts,
        likes: host?.likes,
        interests: host?.interests ? parseJsonSafe(host.interests) : [],
      },
      languages: host?.languages ? parseJsonSafe(host.languages) : [],
      listings: host?.listings?.map((listing) => ({
        id: listing.id,
        name: listing.name,
        description: listing.description,
        price: listing.price,
        location: listing.location,
        addressCity: listing.address_city,
        addressCountry: listing.address_country,
        averageRating: listing?.averageRating,
        image: listing?.image
          ? `${process.env.BASE_URL}/public/host-uploads/${listing?.image}`
          : null,
      })),
      reviews: host?.hostReviews?.map((review) => {
        const user = review.User;

        return {
          id: review.id,
          content: review.content,
          createdAt: formatTimestamp(review.createdAt),
          userId: user?.id,
          fullname: user ? `${user.firstName} ${user.lastName}` : 'Unknown/Deleted User',
          image: user?.image ? `${process.env.BASE_URL}/public/user-uploads/${user.image}` : null,
        };
      }),
    };

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

module.exports = getHostProfile;
