"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const models_1 = require("../users/models");
const models_2 = require("./models");
const mongoose_1 = require("mongoose");
const helpers_1 = __importDefault(require("../../utils/helpers"));
const models_3 = require("../views/models");
const models_4 = require("../likes/models");
const models_5 = require("../super-likes/models");
const models_6 = require("../shares/models");
const models_7 = require("../favorites/models");
const models_8 = require("../comments/models");
const services_1 = __importDefault(require("../../utils/services"));
const models_9 = require("../chats/models");
const models_10 = require("../messages/models");
const reelFieldsToProject = {
    tag: 1,
    subTag: 1,
    chips: 1,
    description: 1,
    cover: 1,
    video: 1,
    dynamic: 1,
    hashtags: 1,
    photos: 1,
    song: 1,
    isAnonymous: 1,
    views: 1,
    likes: 1,
    superLikes: 1,
    shares: 1,
    comments: 1,
    createdAt: 1,
    updatedAt: 1,
    isLiked: 1,
    isSuperLiked: 1,
    isFavorite: 1,
    chat: 1,
    user: {
        _id: 1,
        name: 1,
        username: 1,
        bio: 1,
        photo: 1,
        createdAt: 1,
        auth: {
            emailVerified: 1,
            phoneVerified: 1
        },
        isFollowed: 1
    }
};
function formatReel(reel) {
    return {
        _id: reel._id,
        user: reel.user,
        chat: reel.chat,
        event: reel.event,
        tag: reel.tag,
        subTag: reel.subTag,
        chips: reel.chips,
        description: reel.description,
        cover: reel.cover,
        video: reel.video,
        dynamic: reel.dynamic ? services_1.default.flatDynamicToNested(reel.dynamic) : undefined,
        vectorIndex: reel.vectorIndex,
        hashtags: reel.hashtags,
        photos: reel.photos,
        song: reel.song,
        isAnonymous: reel.isAnonymous,
        views: reel.views,
        likes: reel.likes,
        superLikes: reel.superLikes,
        shares: reel.shares,
        comments: reel.comments,
        reports: reel.reports,
        favorites: reel.favorites,
        createdAt: reel.createdAt,
        updatedAt: reel.updatedAt,
        isLiked: reel.isLiked,
        isSuperLiked: reel.isSuperLiked,
        isFavorite: reel.isFavorite,
    };
}
function getReels(req, res) {
    return __awaiter(this, void 0, void 0, function* () {
        try {
            const user = res.locals.user;
            let { limit = '10', dynamic, chips } = req.query;
            limit = +limit;
            if (chips) {
                limit = 1;
            }
            const match = Object.assign(Object.assign({}, (chips ? { chips } : {})), (dynamic === 'true' ? { dynamic: { $exists: true } } : {}));
            const aggregate = [
                {
                    $match: match
                },
                {
                    $sample: { size: limit }
                },
                {
                    $lookup: {
                        from: 'users',
                        localField: 'user',
                        foreignField: '_id',
                        as: 'user'
                    }
                },
                {
                    $unwind: '$user'
                },
                // isLiked
                {
                    $lookup: {
                        from: 'likes',
                        let: { reelId: '$_id', userId: user._id },
                        pipeline: [
                            {
                                $match: {
                                    $expr: {
                                        $and: [
                                            { $eq: ['$reel', '$$reelId'] },
                                            { $eq: ['$user', '$$userId'] }
                                        ]
                                    }
                                }
                            },
                            { $limit: 1 }
                        ],
                        as: 'liked'
                    }
                },
                // isSuperLiked
                {
                    $lookup: {
                        from: 'super-likes',
                        let: { reelId: '$_id', userId: user._id },
                        pipeline: [
                            {
                                $match: {
                                    $expr: {
                                        $and: [
                                            { $eq: ['$reel', '$$reelId'] },
                                            { $eq: ['$user', '$$userId'] }
                                        ]
                                    }
                                }
                            },
                            { $limit: 1 }
                        ],
                        as: 'superLiked'
                    }
                },
                // isFavorite
                {
                    $lookup: {
                        from: 'favorites',
                        let: { reelId: '$_id', userId: user._id },
                        pipeline: [
                            {
                                $match: {
                                    $expr: {
                                        $and: [
                                            { $eq: ['$reel', '$$reelId'] },
                                            { $eq: ['$user', '$$userId'] }
                                        ]
                                    }
                                }
                            },
                            { $limit: 1 }
                        ],
                        as: 'favorite'
                    }
                },
                // user.isFollowed
                {
                    $lookup: {
                        from: 'followers',
                        let: { currentUserId: user._id, reelOwnerId: '$user._id' },
                        pipeline: [
                            {
                                $match: {
                                    $expr: {
                                        $and: [
                                            { $eq: ['$follower', '$$currentUserId'] },
                                            { $eq: ['$following', '$$reelOwnerId'] }
                                        ]
                                    }
                                }
                            },
                            { $limit: 1 }
                        ],
                        as: 'follow'
                    }
                },
                {
                    $addFields: {
                        isLiked: { $gt: [{ $size: '$liked' }, 0] },
                        isSuperLiked: { $gt: [{ $size: '$superLiked' }, 0] },
                        isFavorite: { $gt: [{ $size: '$favorite' }, 0] },
                        'user.isFollowed': { $gt: [{ $size: '$follow' }, 0] }
                    }
                },
                {
                    $project: reelFieldsToProject
                }
            ];
            let reels = yield models_2.Reel.aggregate(aggregate);
            for (const reel of reels) {
                if (reel.isAnonymous) {
                    // @ts-ignore
                    reel.user = undefined;
                }
            }
            // @ts-ignore
            reels = reels.map(formatReel);
            return res.json({ reels });
        }
        catch (error) {
            console.error(error);
            return res.status(500).json({ message: 'server error' });
        }
    });
}
function getExploreReels(req, res) {
    return __awaiter(this, void 0, void 0, function* () {
        var _a, _b, _c, _d;
        try {
            const user = res.locals.user;
            let { limit = '10', page = '1', chat, tag } = req.query;
            limit = +limit;
            page = +page;
            const skip = (page - 1) * limit;
            const match = Object.assign(Object.assign({}, (chat ? { chat: new mongoose_1.Types.ObjectId(chat) } : {})), (tag ? { tag } : {}));
            const aggregate = [
                {
                    $match: match
                },
                {
                    $facet: {
                        reels: [
                            // users
                            {
                                $lookup: {
                                    from: 'users',
                                    localField: 'user',
                                    foreignField: '_id',
                                    as: 'user',
                                }
                            },
                            {
                                $unwind: '$user'
                            },
                            // isLiked
                            {
                                $lookup: {
                                    from: 'likes',
                                    let: { reelId: '$_id', userId: user._id },
                                    pipeline: [
                                        {
                                            $match: {
                                                $expr: {
                                                    $and: [
                                                        { $eq: ['$reel', '$$reelId'] },
                                                        { $eq: ['$user', '$$userId'] }
                                                    ]
                                                }
                                            }
                                        },
                                        { $limit: 1 }
                                    ],
                                    as: 'liked'
                                }
                            },
                            // isSuperLiked
                            {
                                $lookup: {
                                    from: 'super-likes',
                                    let: { reelId: '$_id', userId: user._id },
                                    pipeline: [
                                        {
                                            $match: {
                                                $expr: {
                                                    $and: [
                                                        { $eq: ['$reel', '$$reelId'] },
                                                        { $eq: ['$user', '$$userId'] }
                                                    ]
                                                }
                                            }
                                        },
                                        { $limit: 1 }
                                    ],
                                    as: 'superLiked'
                                }
                            },
                            // isFavorite
                            {
                                $lookup: {
                                    from: 'favorites',
                                    let: { reelId: '$_id', userId: user._id },
                                    pipeline: [
                                        {
                                            $match: {
                                                $expr: {
                                                    $and: [
                                                        { $eq: ['$reel', '$$reelId'] },
                                                        { $eq: ['$user', '$$userId'] }
                                                    ]
                                                }
                                            }
                                        },
                                        { $limit: 1 }
                                    ],
                                    as: 'favorite'
                                }
                            },
                            {
                                $addFields: {
                                    isLiked: { $gt: [{ $size: '$liked' }, 0] },
                                    isSuperLiked: { $gt: [{ $size: '$superLiked' }, 0] },
                                    isFavorite: { $gt: [{ $size: '$favorite' }, 0] },
                                }
                            },
                            {
                                $project: reelFieldsToProject
                            },
                            { $sort: { views: -1 } },
                            { $skip: skip },
                            { $limit: limit }
                        ],
                        count: [
                            { $count: 'total' }
                        ]
                    }
                }
            ];
            const result = yield models_2.Reel.aggregate(aggregate);
            let reels = ((_a = result[0]) === null || _a === void 0 ? void 0 : _a.reels) || [];
            const count = ((_d = (_c = (_b = result[0]) === null || _b === void 0 ? void 0 : _b.count) === null || _c === void 0 ? void 0 : _c[0]) === null || _d === void 0 ? void 0 : _d.total) || 0;
            for (const reel of reels) {
                if (reel.isAnonymous) {
                    // @ts-ignore
                    reel.user = undefined;
                }
            }
            // @ts-ignore
            reels = reels.map(formatReel);
            return res.json({ reels, count });
        }
        catch (error) {
            console.error(error);
            return res.status(500).json({ message: 'server error' });
        }
    });
}
function getUserReels(req, res) {
    return __awaiter(this, void 0, void 0, function* () {
        var _a, _b, _c, _d;
        try {
            const user = res.locals.user;
            const userId = req.params.userId;
            let { limit = '10', page = '1' } = req.query;
            limit = +limit;
            page = +page;
            const skip = (page - 1) * limit;
            let targetUser;
            if (userId !== `${user._id}`) {
                targetUser = (yield models_1.User.findById(userId));
                if (!targetUser) {
                    return res.status(404).json({ message: 'user not found' });
                }
            }
            else {
                targetUser = user;
            }
            const match = { user: targetUser._id };
            if (targetUser._id.toString() !== user._id.toString()) {
                match.$or = [
                    { isAnonymous: false },
                    { isAnonymous: { $exists: false } },
                ];
            }
            const aggregate = [
                {
                    $match: match
                },
                {
                    $facet: {
                        reels: [
                            // isLiked
                            {
                                $lookup: {
                                    from: 'likes',
                                    let: { reelId: '$_id', userId: user._id },
                                    pipeline: [
                                        {
                                            $match: {
                                                $expr: {
                                                    $and: [
                                                        { $eq: ['$reel', '$$reelId'] },
                                                        { $eq: ['$user', '$$userId'] }
                                                    ]
                                                }
                                            }
                                        },
                                        { $limit: 1 }
                                    ],
                                    as: 'liked'
                                }
                            },
                            // isSuperLiked
                            {
                                $lookup: {
                                    from: 'super-likes',
                                    let: { reelId: '$_id', userId: user._id },
                                    pipeline: [
                                        {
                                            $match: {
                                                $expr: {
                                                    $and: [
                                                        { $eq: ['$reel', '$$reelId'] },
                                                        { $eq: ['$user', '$$userId'] }
                                                    ]
                                                }
                                            }
                                        },
                                        { $limit: 1 }
                                    ],
                                    as: 'superLiked'
                                }
                            },
                            // isFavorite
                            {
                                $lookup: {
                                    from: 'favorites',
                                    let: { reelId: '$_id', userId: user._id },
                                    pipeline: [
                                        {
                                            $match: {
                                                $expr: {
                                                    $and: [
                                                        { $eq: ['$reel', '$$reelId'] },
                                                        { $eq: ['$user', '$$userId'] }
                                                    ]
                                                }
                                            }
                                        },
                                        { $limit: 1 }
                                    ],
                                    as: 'favorite'
                                }
                            },
                            {
                                $addFields: {
                                    isLiked: { $gt: [{ $size: '$liked' }, 0] },
                                    isSuperLiked: { $gt: [{ $size: '$superLiked' }, 0] },
                                    isFavorite: { $gt: [{ $size: '$favorite' }, 0] },
                                }
                            },
                            {
                                $project: {
                                    user: 1,
                                    tag: 1,
                                    subTag: 1,
                                    chips: 1,
                                    description: 1,
                                    cover: 1,
                                    video: 1,
                                    dynamic: 1,
                                    hashtags: 1,
                                    photos: 1,
                                    song: 1,
                                    isAnonymous: 1,
                                    views: 1,
                                    likes: 1,
                                    superLikes: 1,
                                    shares: 1,
                                    comments: 1,
                                    createdAt: 1,
                                    updatedAt: 1,
                                    isLiked: 1,
                                    isSuperLiked: 1,
                                    isFavorite: 1
                                }
                            },
                            { $sort: { createdAt: -1 } },
                            { $skip: skip },
                            { $limit: limit }
                        ],
                        count: [
                            { $count: 'total' }
                        ]
                    }
                }
            ];
            const result = yield models_2.Reel.aggregate(aggregate);
            let reels = ((_a = result[0]) === null || _a === void 0 ? void 0 : _a.reels) || [];
            const count = ((_d = (_c = (_b = result[0]) === null || _b === void 0 ? void 0 : _b.count) === null || _c === void 0 ? void 0 : _c[0]) === null || _d === void 0 ? void 0 : _d.total) || 0;
            // @ts-ignore
            reels = reels.map(formatReel);
            return res.json({ reels, count });
        }
        catch (error) {
            console.error(error);
            return res.status(500).json({ message: 'server error' });
        }
    });
}
function getReel(req, res) {
    return __awaiter(this, void 0, void 0, function* () {
        try {
            const user = res.locals.user;
            const id = req.params.id;
            const aggregate = [
                {
                    $match: { _id: new mongoose_1.Types.ObjectId(id) }
                },
                {
                    $lookup: {
                        from: 'users',
                        localField: 'user',
                        foreignField: '_id',
                        as: 'user'
                    }
                },
                {
                    $unwind: '$user'
                },
                // isLiked
                {
                    $lookup: {
                        from: 'likes',
                        let: { reelId: '$_id', userId: user._id },
                        pipeline: [
                            {
                                $match: {
                                    $expr: {
                                        $and: [
                                            { $eq: ['$reel', '$$reelId'] },
                                            { $eq: ['$user', '$$userId'] }
                                        ]
                                    }
                                }
                            },
                            { $limit: 1 }
                        ],
                        as: 'liked'
                    }
                },
                // isSuperLiked
                {
                    $lookup: {
                        from: 'super-likes',
                        let: { reelId: '$_id', userId: user._id },
                        pipeline: [
                            {
                                $match: {
                                    $expr: {
                                        $and: [
                                            { $eq: ['$reel', '$$reelId'] },
                                            { $eq: ['$user', '$$userId'] }
                                        ]
                                    }
                                }
                            },
                            { $limit: 1 }
                        ],
                        as: 'superLiked'
                    }
                },
                // isFavorite
                {
                    $lookup: {
                        from: 'favorites',
                        let: { reelId: '$_id', userId: user._id },
                        pipeline: [
                            {
                                $match: {
                                    $expr: {
                                        $and: [
                                            { $eq: ['$reel', '$$reelId'] },
                                            { $eq: ['$user', '$$userId'] }
                                        ]
                                    }
                                }
                            },
                            { $limit: 1 }
                        ],
                        as: 'favorite'
                    }
                },
                // user.isFollowed
                {
                    $lookup: {
                        from: 'followers',
                        let: { currentUserId: user._id, reelOwnerId: '$user._id' },
                        pipeline: [
                            {
                                $match: {
                                    $expr: {
                                        $and: [
                                            { $eq: ['$follower', '$$currentUserId'] },
                                            { $eq: ['$following', '$$reelOwnerId'] }
                                        ]
                                    }
                                }
                            },
                            { $limit: 1 }
                        ],
                        as: 'follow'
                    }
                },
                {
                    $addFields: {
                        isLiked: { $gt: [{ $size: '$liked' }, 0] },
                        isSuperLiked: { $gt: [{ $size: '$superLiked' }, 0] },
                        isFavorite: { $gt: [{ $size: '$favorite' }, 0] },
                        'user.isFollowed': { $gt: [{ $size: '$follow' }, 0] }
                    }
                },
                {
                    $project: reelFieldsToProject
                }
            ];
            const reels = yield models_2.Reel.aggregate(aggregate);
            let reel = reels[0];
            if (!reel) {
                return res.status(404).json({ message: 'reel not found' });
            }
            // @ts-ignore
            reel = formatReel(reel);
            if (reel.isAnonymous && `${reel.user._id}` !== `${user._id}`) {
                // @ts-ignore
                reel.user = undefined;
            }
            return res.json({ reel });
        }
        catch (error) {
            console.error(error);
            return res.status(500).json({ message: 'server error' });
        }
    });
}
function postPresignUrl(req, res) {
    return __awaiter(this, void 0, void 0, function* () {
        try {
            const user = res.locals.user;
            const fileNames = req.body.files;
            let id = req.body.id;
            id !== null && id !== void 0 ? id : (id = new mongoose_1.Types.ObjectId());
            const files = fileNames.map(e => {
                const extension = e.split('.').at(-1);
                e = e.split('.').slice(0, -1).join('.');
                let name = e
                    .replace(/ /g, '-')
                    .replace(/#/g, '-')
                    .replace(/,/g, '-')
                    .split('')
                    .filter(c => /[A-Za-z0-9_\-.]/.test(c))
                    .join('');
                while (name.includes('--')) {
                    name = name.replace(/\-\-/g, '-');
                }
                name = name.length >= 10 ? name.slice(0, 10) : name;
                if (name.endsWith('-')) {
                    name = name.slice(0, -1);
                }
                name += '.' + extension;
                const hash = Date.now().toString() + '-' + Math.random().toString().split('.')[1];
                const path = `reels/${id}/${hash}-${name}`;
                return { path, name: e + '.' + extension };
            });
            const urls = [];
            for (const file of files) {
                const url = yield helpers_1.default.generateSignedUrl(file.path);
                if (!url) {
                    return res.status(500).json({ message: 'server error' });
                }
                urls.push({
                    file: file.name,
                    upload: url.upload,
                    download: url.download,
                });
            }
            return res.status(201).json({ id, urls });
        }
        catch (error) {
            console.log(error);
            return res.status(500).json({ message: 'server error' });
        }
    });
}
function postReel(req, res) {
    return __awaiter(this, void 0, void 0, function* () {
        try {
            const user = res.locals.user;
            let { id, chat: chatId, description, tag, subTag, cover, video, photos, dynamic, hashtags = [], isAnonymous, socket: socketId } = req.body;
            let participant;
            let message = null;
            let chat = null;
            if (chatId) {
                chat = yield models_9.Chat.findById(chatId);
                if (!chat) {
                    return res.status(404).json({ message: 'chat not found' });
                }
                if (!chat.isGroup) {
                    return res.status(403).json({ message: 'chat must be a group chat' });
                }
                participant = chat.participants.find(e => `${e.user}` === `${user._id}`);
                if (!participant) {
                    return res.status(403).json({ message: 'you must be the member of this chat' });
                }
                if (!chat.allowPublicPost && !participant.isAdmin) {
                    return res.status(403).json({ message: 'only admins can upload vibe in this community' });
                }
            }
            const r = yield models_2.Reel.findById(id);
            if (r) {
                return res.status(409).json({ message: 'reel with this id already exist' });
            }
            let reel = yield models_2.Reel.create({
                _id: new mongoose_1.Types.ObjectId(id),
                user: user._id,
                tag,
                chat: chat === null || chat === void 0 ? void 0 : chat._id,
                event: chat === null || chat === void 0 ? void 0 : chat.event,
                subTag,
                description,
                cover,
                video,
                dynamic,
                hashtags,
                photos: photos === null || photos === void 0 ? void 0 : photos.map(e => ({ url: e })),
                isAnonymous: isAnonymous !== null && isAnonymous !== void 0 ? isAnonymous : undefined,
            });
            if (chat) {
                // create a new message with the reel id
                message = (yield models_10.Message.create({
                    user: user._id,
                    chat: chat._id,
                    reel: reel._id
                }));
                participant.lastReadAt = new Date();
                // @ts-ignore
                chat.lastMessage = message._id;
                yield chat.save();
                // also add the message id in that reel
                reel.message = message._id;
                yield reel.save();
                (() => __awaiter(this, void 0, void 0, function* () {
                    var _a, _b, _c, _d, _e, _f, _g;
                    try {
                        if (!message) {
                            return;
                        }
                        // notify other participants with push only notification
                        const otherParticipants = chat.participants.filter(e => `${e.user}` !== `${user._id}`);
                        const participants = yield models_1.User.find({ _id: { $in: otherParticipants.map(e => e.user) } });
                        const title = `New vibe from ${(_b = (_a = user.name) !== null && _a !== void 0 ? _a : user.username) !== null && _b !== void 0 ? _b : 'a user'}`;
                        const description = (_c = message.content) !== null && _c !== void 0 ? _c : `${(_e = (_d = message.files) === null || _d === void 0 ? void 0 : _d.length) !== null && _e !== void 0 ? _e : 0} file${((_g = (_f = message.files) === null || _f === void 0 ? void 0 : _f.length) !== null && _g !== void 0 ? _g : 0 > 1) ? 's' : ''}`;
                        for (const participant of participants) {
                            yield services_1.default.pushNotifyUser({
                                title,
                                body: description,
                                event: 'message-received',
                                user: participant,
                                data: {
                                    message: {
                                        _id: message._id,
                                        user: {
                                            _id: user._id,
                                            username: user.username,
                                            name: user.name,
                                            photo: user.photo,
                                        },
                                        reel: reel._id,
                                        isGroup: chat.isGroup,
                                        chat: message.chat,
                                        content: message.content,
                                        files: message.files,
                                        at: message.at,
                                    },
                                }
                            });
                        }
                    }
                    catch (error) {
                        console.log(error);
                    }
                }))();
                // socket notify
                (() => __awaiter(this, void 0, void 0, function* () {
                    try {
                        // notify other participants with event "message-received"
                        const participantIds = chat.participants.filter(e => `${e.user}` !== `${user._id}`).map(e => `${e.user}`);
                        const payload = {
                            message: {
                                _id: `${message._id}`,
                                user: {
                                    _id: `${user._id}`,
                                    name: user.name,
                                    photo: user.photo,
                                    username: user.username
                                },
                                chat: `${chat._id}`,
                                reel: `${reel._id}`,
                                content: message.content,
                                files: message.files,
                                at: message.at.toISOString()
                            }
                        };
                        for (const participantId of participantIds) {
                            services_1.default.socketNotifyUser({
                                userId: participantId,
                                event: 'messages-received',
                                data: payload
                            });
                        }
                        // notify current user's other sockets(if socket available) with event "message-sent"
                        services_1.default.socketNotifyUser({
                            userId: `${user._id}`,
                            event: 'messages-sent',
                            data: payload,
                            currentSocket: socketId,
                            socketType: 'others'
                        });
                    }
                    catch (error) {
                        console.log(error);
                    }
                }))();
            }
            // @ts-ignore
            reel.vectorIndex = undefined;
            // @ts-ignore
            reel = formatReel(reel);
            (() => __awaiter(this, void 0, void 0, function* () {
                try {
                    const count = yield models_2.Reel.countDocuments({ user: user._id });
                    user.posts = count;
                    yield user.save();
                }
                catch (error) {
                    console.log(error);
                }
            }))();
            return res.status(201).json({ reel, message });
        }
        catch (error) {
            console.log(error);
            return res.status(500).json({ message: 'server error' });
        }
    });
}
function patchReel(req, res) {
    return __awaiter(this, void 0, void 0, function* () {
        try {
            const user = res.locals.user;
            const id = req.params.id;
            const { description, tag, subTag, cover, hashtags, isAnonymous } = req.body;
            const reel = yield models_2.Reel.findById(id);
            if (!reel) {
                return res.status(404).json({ message: 'reel not found' });
            }
            if (`${reel.user}` !== `${user._id}`) {
                return res.status(403).json({ message: 'permission denied' });
            }
            reel.tag = tag !== null && tag !== void 0 ? tag : reel.tag;
            reel.subTag = subTag !== null && subTag !== void 0 ? subTag : reel.subTag;
            reel.description = description !== null && description !== void 0 ? description : reel.description;
            reel.hashtags = hashtags !== null && hashtags !== void 0 ? hashtags : reel.hashtags;
            if (typeof isAnonymous === 'boolean') {
                reel.isAnonymous = isAnonymous;
            }
            if (cover && cover !== reel.cover) {
                if (reel.cover) {
                    yield helpers_1.default.deleteR2File(reel.cover);
                }
                reel.cover = cover;
            }
            yield reel.save();
            return res.json({ message: 'reel updated successfully' });
        }
        catch (error) {
            console.log(error);
            return res.status(500).json({ message: 'server error' });
        }
    });
}
function deleteReel(req, res) {
    return __awaiter(this, void 0, void 0, function* () {
        try {
            const user = res.locals.user;
            const id = req.params.id;
            const reel = yield models_2.Reel.findById(id);
            if (!reel) {
                return res.status(404).json({ message: 'reel not found' });
            }
            if (`${reel.user}` !== `${user._id}`) {
                return res.status(403).json({ message: 'permission denied' });
            }
            deleteReelAndItsAssets(reel, user);
            return res.json({ message: 'reel deleted successfully' });
        }
        catch (error) {
            console.log(error);
            return res.status(500).json({ message: 'server error' });
        }
    });
}
function deleteReelAndItsAssets(reel_1, user_1) {
    return __awaiter(this, arguments, void 0, function* (reel, user, hardDelete = true) {
        try {
            yield reel.deleteOne();
            const count = yield models_2.Reel.countDocuments({ user: user._id });
            user.posts = count;
            yield user.save();
            if (!hardDelete) {
                return;
            }
            if (reel.cover) {
                yield helpers_1.default.deleteR2File(reel.cover);
            }
            if (reel.video) {
                yield helpers_1.default.deleteR2File(reel.video);
            }
            if (reel.photos) {
                for (const photo of reel.photos) {
                    yield helpers_1.default.deleteR2File(photo.url);
                }
            }
            if (reel.dynamic) {
                for (const e of reel.dynamic) {
                    if (e.cover) {
                        yield helpers_1.default.deleteR2File(e.cover);
                    }
                    yield helpers_1.default.deleteR2File(e.video);
                }
            }
            const allCommentIds = (yield models_8.Comment.distinct('_id', { reel: reel._id }));
            yield Promise.all([
                models_4.Like.deleteMany({
                    $or: [
                        { reel: reel._id },
                        { comment: { $in: allCommentIds } },
                    ],
                }),
                models_3.View.deleteMany({ reel: reel._id }),
                models_5.SuperLike.deleteMany({ reel: reel._id }),
                models_6.Share.deleteMany({ reel: reel._id }),
                models_7.Favorite.deleteMany({ reel: reel._id }),
                models_8.Comment.deleteMany({ reel: reel._id }),
            ]);
        }
        catch (error) {
            console.log(error);
        }
    });
}
const reelControllers = {
    getReels,
    getExploreReels,
    getUserReels,
    getReel,
    postPresignUrl,
    postReel,
    patchReel,
    deleteReel,
    reelFieldsToProject,
    deleteReelAndItsAssets
};
exports.default = reelControllers;
