import { Request, Response } from 'express'
import { IUser, User } from '../users/models'
import { DynamicReelFlat, IReel, Reel } from './models'
import { Types } from 'mongoose'
import helpers from '../../utils/helpers'
import { View } from '../views/models'
import { Like } from '../likes/models'
import { SuperLike } from '../super-likes/models'
import { Share } from '../shares/models'
import { Favorite } from '../favorites/models'
import { Comment } from '../comments/models'
import services from '../../utils/services'
import { Chat, IChat, IChatParticipant } from '../chats/models'
import { IMessage, Message } from '../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: IReel & Record<string, any>) {
	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.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,
	}
}

async function getReels(req: Request, res: Response) {
	interface Payload {
		limit?: string | number
		dynamic?: 'true' | 'false'
		chips?: 'focus' | 'mindfulness' | 'reflection'
	}

	try {
		const user = res.locals.user as IUser
		let { limit = '10', dynamic, chips } = req.query as unknown as Payload
		limit = +limit

		if (chips) {
			limit = 1
		}

		const match: any = {
			// user: {$ne: user._id},
			...(chips ? { chips } : {}),
			...(dynamic === 'true' ? { dynamic: { $exists: true } } : {})
		}
		const aggregate: any = [
			{
				$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: IReel[] = await 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' })
	}
}

async function getExploreReels(req: Request, res: Response) {
	interface Payload {
		limit?: string | number
		page?: string | number
		chat?: string
		tag?: string
	}

	try {
		const user = res.locals.user as IUser
		let { limit = '10', page = '1', chat, tag } = req.query as unknown as Payload
		limit = +limit
		page = +page
		const skip = (page - 1) * limit

		const match: any = {
			...(chat ? { chat: new Types.ObjectId(chat) } : {}),
			...(tag ? { tag } : {}),
		}
		const aggregate: any = [
			{
				$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 = await Reel.aggregate(aggregate)
		let reels: IReel[] = result[0]?.reels || []
		const count = result[0]?.count?.[0]?.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' })
	}
}

async function getUserReels(req: Request, res: Response) {
	interface Payload {
		limit?: string | number
		page?: string | number
	}

	try {
		const user = res.locals.user as IUser
		const userId = req.params.userId
		let { limit = '10', page = '1' } = req.query as unknown as Payload
		limit = +limit
		page = +page
		const skip = (page - 1) * limit

		let targetUser: IUser
		if (userId !== `${user._id}`) {
			targetUser = await User.findById(userId) as IUser
			if (!targetUser) {
				return res.status(404).json({ message: 'user not found' })
			}
		} else {
			targetUser = user
		}

		const match: any = { user: targetUser._id }
		if (targetUser._id.toString() !== user._id.toString()) {
			match.$or = [
				{ isAnonymous: false },
				{ isAnonymous: { $exists: false } },
			]
		}
		const aggregate: any = [
			{
				$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 = await Reel.aggregate(aggregate)
		let reels: IReel[] = result[0]?.reels || []
		const count = result[0]?.count?.[0]?.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' })
	}
}

async function getReel(req: Request, res: Response) {
	try {
		const user = res.locals.user as IUser
		const id = req.params.id

		const aggregate: any = [
			{
				$match: { _id: new 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 = await Reel.aggregate(aggregate)
		let reel: IReel = 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' })
	}
}

async function postPresignUrl(req: Request, res: Response) {
	try {
		const user = res.locals.user as IUser
		const fileNames = req.body.files as string[]
		let id = req.body.id as string | Types.ObjectId
		id ??= new 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: any[] = []
		for (const file of files) {
			const url = await helpers.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' })
	}
}

async function postReel(req: Request, res: Response) {
	interface Payload {
		id: string
		tag?: string
		chat?: string
		subTag?: string
		description?: string
		cover?: string
		video?: string
		dynamic?: DynamicReelFlat[]
		photos?: string[]
		hashtags?: string[]
		isAnonymous?: boolean
		socket?: string
	}
	try {
		const user = res.locals.user as IUser
		let { id, chat: chatId, description, tag, subTag, cover, video, photos, dynamic, hashtags = [], isAnonymous, socket: socketId } = req.body as Payload
		let participant: IChatParticipant | undefined

		let message: IMessage | null = null
		let chat: IChat | null = null
		if (chatId) {
			chat = await 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 = await Reel.findById(id)
		if (r) {
			return res.status(409).json({ message: 'reel with this id already exist' })
		}

		let reel = await Reel.create({
			_id: new Types.ObjectId(id),
			user: user._id,
			tag,
			chat: chat?._id,
			event: chat?.event,
			subTag,
			description,
			cover,
			video,
			dynamic,
			hashtags,
			photos: photos?.map(e => ({ url: e })),
			isAnonymous: isAnonymous ?? undefined,
		})

		if (chat) {
			// create a new message with the reel id
			message = await Message.create({
				user: user._id,
				chat: chat._id,
				reel: reel._id
			}) as unknown as IMessage

			participant!.lastReadAt = new Date()
			// @ts-ignore
			chat.lastMessage = message._id
			await chat.save()

			// also add the message id in that reel
			reel.message = message._id
			await reel.save()

				// fcm notify
				; (async () => {
					try {
						if (!message) {
							return
						}
						// notify other participants with push only notification
						const otherParticipants = chat.participants.filter(e => `${e.user}` !== `${user._id}`)
						const participants: IUser[] = await User.find({ _id: { $in: otherParticipants.map(e => e.user) } })
						const title = `New vibe from ${user.name ?? user.username ?? 'a user'}`
						const description = message.content ?? `${message.files?.length ?? 0} file${message.files?.length ?? 0 > 1 ? 's' : ''}`
						for (const participant of participants) {
							await services.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
			(async () => {
				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.socketNotifyUser({
							userId: participantId,
							event: 'messages-received',
							data: payload
						})
					}
					// notify current user's other sockets(if socket available) with event "message-sent"
					services.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)

		// AI prompt to get comment properties
		// ;(async () => {
		// 	try {
		// 		const systemPrompt = await fs.readFile(path.join(__dirname, 'reel-prompt.md'), {encoding: 'utf-8'})
		// 		let reelData: ReelData = {}
		// 		reelData.video = reel.video
		// 		if(reel.photos) {
		// 			reelData.photos = reel.photos.map(e => e.url)
		// 		}
		// 		if(reel.dynamic) {
		// 			reelData.dynamic = reel.dynamic.map(e => e.video)
		// 		}
		// 		const result = await services.analyzeReelByAi(systemPrompt, reelData)
		// 		if(!result) {
		// 			return
		// 		}
		// 		if(result.isInappropriate || result.isExtremelyInappropriate) {
		// 			return deleteReelAndItsAssets(reel, user)
		// 		}
		// 		reel.metaData = {
		// 			comments: result.comments || undefined,
		// 			vectorMetaData: result.vectorMetaData || undefined,
		// 			isPositive: result.isPositive || undefined,
		// 			isNegative: result.isNegative || undefined,
		// 			awarenessExercise: result.awarenessExercise || undefined,
		// 			groundingExercise: result.groundingExercise || undefined,
		// 			isProductivity: result.isProductivity || undefined,
		// 			isMeditation: result.isMeditation || undefined,
		// 		}
		// 		await reel.save()
		// 	} catch (error) {
		// 		console.log(error)
		// 	}
		// })()

		// Update user reels count
		; (async () => {
			try {
				const count = await Reel.countDocuments({ user: user._id })
				user.posts = count
				await 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' })
	}
}

async function patchReel(req: Request, res: Response) {
	interface Payload {
		tag?: string
		subTag?: string
		description?: string
		hashtags?: string[]
		cover?: string
		isAnonymous?: boolean
	}
	try {
		const user = res.locals.user as IUser
		const id = req.params.id
		const { description, tag, subTag, cover, hashtags, isAnonymous } = req.body as Payload

		const reel = await 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 ?? reel.tag
		reel.subTag = subTag ?? reel.subTag
		reel.description = description ?? reel.description
		reel.hashtags = hashtags ?? reel.hashtags
		if (typeof isAnonymous === 'boolean') {
			reel.isAnonymous = isAnonymous
		}
		if (cover && cover !== reel.cover) {
			if (reel.cover) {
				await helpers.deleteR2File(reel.cover)
			}
			reel.cover = cover
		}
		await reel.save()

		return res.json({ message: 'reel updated successfully' })
	} catch (error) {
		console.log(error)
		return res.status(500).json({ message: 'server error' })
	}
}

async function deleteReel(req: Request, res: Response) {
	try {
		const user = res.locals.user as IUser
		const id = req.params.id

		const reel = await 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' })
	}
}

async function deleteReelAndItsAssets(reel: IReel, user: IUser, hardDelete = true) {
	try {
		await reel.deleteOne()
		const count = await Reel.countDocuments({ user: user._id })
		user.posts = count
		await user.save()

		if (!hardDelete) {
			return
		}
		if (reel.cover) {
			await helpers.deleteR2File(reel.cover)
		}
		if (reel.video) {
			await helpers.deleteR2File(reel.video)
		}
		if (reel.photos) {
			for (const photo of reel.photos) {
				await helpers.deleteR2File(photo.url)
			}
		}
		if (reel.dynamic) {
			for (const e of reel.dynamic) {
				if (e.cover) {
					await helpers.deleteR2File(e.cover)
				}
				await helpers.deleteR2File(e.video)
			}
		}
		const allCommentIds = (await Comment.distinct('_id', { reel: reel._id }))
		await Promise.all([
			Like.deleteMany({
				$or: [
					{ reel: reel._id },
					{ comment: { $in: allCommentIds } },
				],
			}),
			View.deleteMany({ reel: reel._id }),
			SuperLike.deleteMany({ reel: reel._id }),
			Share.deleteMany({ reel: reel._id }),
			Favorite.deleteMany({ reel: reel._id }),
			Comment.deleteMany({ reel: reel._id }),
		])
	} catch (error) {
		console.log(error)
	}
}

const reelControllers = {
	getReels,
	getExploreReels,
	getUserReels,
	getReel,
	postPresignUrl,
	postReel,
	patchReel,
	deleteReel,
	reelFieldsToProject,
	deleteReelAndItsAssets
}

export default reelControllers
