GIF89a php
Current File : /home/viralhoga/app_viralhoga/src/modules/homeApi/home.controller.js
import AsyncHandler from "../../utils/AsyncHandler.js";
import Content from "../../models/content.model.js";
import ApiResponse from "../../utils/ApiRespinseHandler.js";
import User from "../../models/user.model.js";
import { roleContaints, contentStatus } from "../../validators/constaints.js";
import YoutubeVideoModel from '../../models/youtube.url.model.js';
import YoutubeModel from "../../models/youtube.model.js";

export const getHomeData = AsyncHandler(async (req, res) => {
    const limit = 10;

    // Helper functions to fetch data
    const fetchByFlag = async (flag) => {
        // Handle potential case difference in flags (IsNew vs isNew, isRecommended vs IsRecommended)
        const flagLower = flag.charAt(0).toLowerCase() + flag.slice(1);
        const flagUpper = flag.charAt(0).toUpperCase() + flag.slice(1);

        return await Content.find({
            $and: [
                {
                    $or: [
                        { [flagUpper]: true },
                        { [flagLower]: true }
                    ]
                },
                {
                    $or: [
                        { status: { $regex: new RegExp(`^${contentStatus.active}$`, "i") } },
                        { status: { $exists: false } },
                        { status: null }
                    ]
                }
            ]
        })
            .populate({ path: "catId", select: "catName" })
            .populate({ path: "contentOf", select: "fullName avatar role" })
            .limit(limit)
            .sort({ createdAt: -1 });
    };

    const fetchByRole = async (role, extraUserQuery = {}, returnUsers = false) => {
        // Handle potential array of roles or single role
        const roleQuery = Array.isArray(role)
            ? { $in: role.map(r => new RegExp(`^${r}$`, "i")) }
            : { $regex: new RegExp(`^${role}$`, "i") };

        const users = await User.find({
            role: roleQuery,
            // Check for both boolean true and string "true" for isVarifiedAsArtist if it exists in extraUserQuery
            ...(extraUserQuery.isVarifiedAsArtist !== undefined ? {
                $or: [
                    { isVarifiedAsArtist: true },
                    { isVarifiedAsArtist: "true" }
                ]
            } : {}),
            // Ensure user is active
            $or: [
                { status: { $regex: new RegExp(`^active$`, "i") } },
                { status: { $exists: false } },
                { status: null }
            ]
        }).select("fullName avatar role services experties location studio status");

        if (returnUsers) {
            // If returnUsers is true, we return the users limited by global limit
            const limitedUsers = users.slice(0, limit);
            return { contents: limitedUsers, userCount: users.length };
        }

        const userIds = users.map(u => u._id);
        const contents = await Content.find({
            $and: [
                { contentOf: { $in: userIds } },
                {
                    $or: [
                        { status: { $regex: new RegExp(`^${contentStatus.active}$`, "i") } },
                        { status: { $exists: false } },
                        { status: null }
                    ]
                }
            ]
        })
            .populate({ path: "catId", select: "catName" })
            .populate({ path: "contentOf", select: "fullName avatar role" })
            .limit(limit)
            .sort({ createdAt: -1 });

        return { contents, userCount: users.length };
    };

    const [newArrival, recommended, lyrics, music, studio, youtubeVideos, channels] = await Promise.all([
        fetchByFlag("IsNew"),
        fetchByFlag("isRecommended"),
        // Lyrics: Check for ARTIST or LYRICS role, must be verified
        fetchByRole([roleContaints.artist, "LYRICS"], { isVarifiedAsArtist: true }),
        // Music: Check for MUSICIAN or MUSIC role
        fetchByRole([roleContaints.musician, "MUSIC"]),
        // Studio: Check for STUDIO role, return as users
        fetchByRole(roleContaints.studio, {}, true),
        // YouTube Videos
        YoutubeVideoModel.find().limit(limit).sort({ createdAt: -1 }),
        // YouTube Channels
        YoutubeModel.find().limit(limit).sort({ createdAt: -1 })
    ]);

    return res.status(200).json(
        new ApiResponse(200, "Home data fetched successfully", {
            newArrival,
            recommended,
            lyrics: lyrics.contents,
            music: music.contents,
            studio: studio.contents,
            youtubeVideos: youtubeVideos,
            channels: channels,
            // Debug info
            debug: {
                lyricsUserCount: lyrics.userCount,
                musicUserCount: music.userCount,
                studioUserCount: studio.userCount,
                newArrivalCount: newArrival.length,
                recommendedCount: recommended.length,
                youtubeCount: youtubeVideos.length,
                channelsCount: channels.length
            }
        })
    );
});