import { prisma } from './prisma' import { requireAuth } from './auth' export async function getUserQueue(userId: string): Promise { const queue = await prisma.queue.findUnique({ where: { userId }, }) if (!queue) { // Create a new queue for the user return prisma.queue.create({ data: { userId, songIds: JSON.stringify([]), }, }) } return { ...queue, songIds: JSON.parse(queue.songIds), } } export async function updateUserQueue( userId: string, songIds: string[], currentIndex?: number, isShuffled?: boolean, repeatMode?: string ): Promise { const queue = await prisma.queue.upsert({ where: { userId }, update: { songIds: JSON.stringify(songIds), currentIndex, isShuffled, repeatMode, updatedAt: new Date(), }, create: { userId, songIds: JSON.stringify(songIds), currentIndex, isShuffled, repeatMode, }, }) return { ...queue, songIds: JSON.parse(queue.songIds), } } export async function addToQueue(userId: string, songIds: string[]): Promise { const queue = await getUserQueue(userId) const currentSongIds = queue.songIds as string[] || [] const newSongIds = [...currentSongIds, ...songIds] return updateUserQueue(userId, newSongIds, queue.currentIndex, queue.isShuffled, queue.repeatMode) } export async function removeFromQueue(userId: string, index: number): Promise { const queue = await getUserQueue(userId) const songIds = queue.songIds as string[] || [] if (index < 0 || index >= songIds.length) { throw new Error('Invalid index') } songIds.splice(index, 1) let newCurrentIndex = queue.currentIndex || 0 // Adjust current index if necessary if (index < newCurrentIndex) { newCurrentIndex-- } else if (newCurrentIndex >= songIds.length) { newCurrentIndex = Math.max(0, songIds.length - 1) } return updateUserQueue(userId, songIds, newCurrentIndex, queue.isShuffled, queue.repeatMode) } export async function playSong(userId: string, songId: string, source?: string): Promise { // Add to play history await prisma.playHistory.create({ data: { userId, songId, source, }, }) // Update song play count await prisma.song.update({ where: { id: songId }, data: { playCount: { increment: 1, }, }, }) } export async function getPlayHistory( userId: string, limit: number = 50, offset: number = 0 ): Promise { return prisma.playHistory.findMany({ where: { userId }, include: { song: { select: { id: true, title: true, slug: true, duration: true, artist: { select: { id: true, name: true, slug: true, }, }, album: { select: { id: true, title: true, slug: true, coverUrl: true, }, }, }, }, }, orderBy: { playedAt: 'desc' }, take: limit, skip: offset, }) } export async function updatePlayHistoryItem( userId: string, songId: string, playedDuration: number, completed: boolean ): Promise { await prisma.playHistory.updateMany({ where: { userId, songId, completed: false, }, data: { playedDuration, completed, }, }) } export async function getNextInQueue(userId: string): Promise { const queue = await getUserQueue(userId) const songIds = queue.songIds as string[] || [] let currentIndex = queue.currentIndex || 0 const repeatMode = queue.repeatMode || 'none' if (songIds.length === 0) { return null } // Handle repeat modes if (repeatMode === 'one') { return songIds[currentIndex] } // Move to next currentIndex++ // Handle wrap around for repeat all if (currentIndex >= songIds.length) { if (repeatMode === 'all') { currentIndex = 0 } else { return null // End of queue } } // Update queue with new index await updateUserQueue(userId, songIds, currentIndex, queue.isShuffled, repeatMode) return songIds[currentIndex] } export async function getPreviousInQueue(userId: string): Promise { const queue = await getUserQueue(userId) const songIds = queue.songIds as string[] || [] let currentIndex = queue.currentIndex || 0 if (songIds.length === 0 || currentIndex <= 0) { return null } // Move to previous currentIndex-- // Update queue with new index await updateUserQueue(userId, songIds, currentIndex, queue.isShuffled, queue.repeatMode) return songIds[currentIndex] } export async function shuffleQueue(userId: string): Promise { const queue = await getUserQueue(userId) const songIds = queue.songIds as string[] || [] if (songIds.length === 0) { return queue } // Shuffle the array const shuffledIds = [...songIds] for (let i = shuffledIds.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [shuffledIds[i], shuffledIds[j]] = [shuffledIds[j], shuffledIds[i]] } // Find current song in shuffled array const currentSongId = songIds[queue.currentIndex || 0] const newCurrentIndex = shuffledIds.indexOf(currentSongId) return updateUserQueue( userId, shuffledIds, newCurrentIndex, true, queue.repeatMode ) } export async function unshuffleQueue(userId: string): Promise { const queue = await getUserQueue(userId) const songIds = queue.songIds as string[] || [] return updateUserQueue( userId, songIds, queue.currentIndex, false, queue.repeatMode ) }