import {getClient} from "../utils/database.js"; import jwt from "jsonwebtoken"; export async function create(req, res) { const { name } = req.body; const token = req.headers.authorization.split(' ')[1]; const userId = jwt.decode(token)["id"]; const logger = req.body.logger; const client = await getClient(); const query = `INSERT INTO playlists (name, owner) VALUES ($1, $2) RETURNING id`; try { const result = await client.query(query, [name, userId]); logger.write("Playlist created with id " + result.rows[0].id, 200); client.release() res.status(200).json({ id: result.rows[0].id }); } catch (error) { logger.write("Error creating playlist: " + error.message, 500); client.release(); res.status(500).json({ error: "Internal server error" }); } } export async function addVideo(req, res) { const { id } = req.params; const { video } = req.body; const logger = req.body.logger; const client = await getClient(); const query = `INSERT INTO playlist_elements (video, playlist) VALUES ($1, $2) RETURNING id`; try { const result = await client.query(query, [video, id]); logger.write("Video added to playlist with id " + id, 200); client.release(); res.status(200).json({id: result.rows[0].id}); } catch (error) { logger.write("Error adding video to playlist: " + error.message, 500); client.release(); res.status(500).json({error: "Internal server error"}); } } export async function getByUser(req, res) { const { id } = req.params; const logger = req.body.logger; const client = await getClient(); const query = ` SELECT * FROM ( SELECT playlists.id, playlists.name, playlists.owner, v.thumbnail as thumbnail, ROW_NUMBER() OVER (PARTITION BY playlists.id ORDER BY pt.id DESC) as rn FROM playlists LEFT JOIN playlist_elements pt on playlist = playlists.id LEFT JOIN videos v on pt.video = v.id WHERE owner = $1 ) ranked WHERE rn = 1 OR rn IS NULL `; try { const result = await client.query(query, [id]); if (result.rows.length === 0) { logger.write("No playlists found for user with id " + id, 404); client.release(); res.status(404).json({ error: "No playlists found" }); return; } logger.write("Playlists retrieved for user with id " + id, 200); client.release(); res.status(200).json(result.rows); } catch (error) { logger.write("Error retrieving playlists: " + error.message, 500); client.release(); res.status(500).json({ error: "Internal server error" }); } } export async function getById(req, res) { const { id } = req.params; const logger = req.body.logger; const client = await getClient(); const query = ` SELECT playlists.id, playlists.name, COALESCE( JSON_AGG( JSON_BUILD_OBJECT( 'id', video_data.id, 'title', video_data.title, 'thumbnail', video_data.thumbnail, 'video_description', video_data.description, 'channel', video_data.channel, 'visibility', video_data.visibility, 'file', video_data.file, 'slug', video_data.slug, 'format', video_data.format, 'release_date', video_data.release_date, 'channel_id', video_data.channel, 'owner', channels.owner, 'views', CAST(video_data.views AS TEXT), 'creator', JSON_BUILD_OBJECT( 'name', channels.name, 'profilePicture', users.picture, 'description', channels.description ), 'type', 'video' ) ) FILTER (WHERE video_data.id IS NOT NULL), '[]'::json ) AS videos FROM playlists LEFT JOIN playlist_elements ON playlists.id = playlist_elements.playlist LEFT JOIN ( SELECT videos.id, videos.title, videos.description, videos.thumbnail, videos.release_date, videos.visibility, videos.file, videos.slug, videos.format, videos.channel, COUNT(history.id) AS views FROM videos LEFT JOIN history ON history.video = videos.id GROUP BY videos.id, videos.title, videos.description, videos.thumbnail, videos.release_date, videos.visibility, videos.file, videos.slug, videos.format, videos.channel ) video_data ON playlist_elements.video = video_data.id LEFT JOIN channels ON video_data.channel = channels.id LEFT JOIN users ON channels.owner = users.id WHERE playlists.id = $1 GROUP BY playlists.id; `; try { const result = await client.query(query, [id]); if (result.rows.length === 0) { logger.write("No playlist found with id " + id, 404); client.release(); res.status(404).json({ error: "Playlist not found" }); return; } logger.write("Playlist retrieved with id " + id, 200); client.release(); res.status(200).json(result.rows[0]); } catch (error) { logger.write("Error retrieving playlist: " + error.message, 500); client.release(); res.status(500).json({ error: "Internal server error" }); } } export async function update(req, res) { const { id } = req.params; const { name } = req.body; const logger = req.body.logger; const client = await getClient(); const query = `UPDATE playlists SET name = $1 WHERE id = $2 RETURNING id`; try { const result = await client.query(query, [name, id]); if (result.rows.length === 0) { logger.write("No playlist found with id " + id, 404); client.release(); res.status(404).json({ error: "Playlist not found", result: result.rows, query: query }); return; } logger.write("Playlist updated with id " + result.rows[0].id, 200); client.release(); res.status(200).json({ id: result.rows[0].id }); } catch (error) { logger.write("Error updating playlist: " + error.message, 500); client.release(); res.status(500).json({ error: "Internal server error" }); } } export async function deleteVideo(req, res) { const { id, videoId } = req.params; const logger = req.body.logger; const client = await getClient(); const query = `DELETE FROM playlist_elements WHERE video = $1 AND playlist = $2 RETURNING id`; try { const result = await client.query(query, [videoId, id]); if (result.rows.length === 0) { logger.write("No video found in playlist with id " + id, 404); client.release(); res.status(404).json({ error: "Video not found in playlist" }); return; } logger.write("Video deleted from playlist with id " + id, 200); client.release(); res.status(200).json({ id: result.rows[0].id }); } catch (error) { logger.write("Error deleting video from playlist: " + error.message, 500); client.release(); res.status(500).json({ error: "Internal server error" }); } } export async function del(req, res) { const { id } = req.params; const logger = req.body.logger; const client = await getClient(); const query = `DELETE FROM playlists WHERE id = $1 RETURNING id`; try { const result = await client.query(query, [id]); logger.write("Playlist deleted", 200); client.release() res.status(200).json({ "message": "playlist deleted" }); } catch (error) { logger.write("Error deleting playlist: " + error.message, 500); client.release(); res.status(500).json({ error: "Internal server error" }); } } export async function getSeeLater(req, res) { const token = req.headers.authorization.split(' ')[1]; const userId = jwt.decode(token)["id"]; const logger = req.body.logger; const client = await getClient(); const query = ` SELECT COALESCE( JSON_AGG( json_build_object( 'video_id', videos.id, 'title', videos.title, 'thumbnail', videos.thumbnail, 'video_decscription', videos.description, 'channel', videos.channel, 'visibility', videos.visibility, 'file', videos.file, 'format', videos.format, 'release_date', videos.release_date, 'channel_id', channels.id, 'owner', channels.owner, 'views', COALESCE(video_views.view_count, 0), 'creator', json_build_object( 'name', channels.name, 'profilePicture', users.picture, 'description', channels.description ) ) ) FILTER (WHERE videos.id IS NOT NULL), '[]'::json ) AS videos FROM public.playlists LEFT JOIN public.playlist_elements ON public.playlists.id = public.playlist_elements.playlist LEFT JOIN ( SELECT * FROM public.videos LIMIT 10 ) videos ON public.playlist_elements.video = videos.id LEFT JOIN public.channels ON videos.channel = public.channels.id LEFT JOIN public.users ON public.channels.owner = public.users.id LEFT JOIN ( SELECT video, COUNT(*) as view_count FROM public.history GROUP BY video ) video_views ON videos.id = video_views.video WHERE playlists.owner = $1 GROUP BY playlists.id, playlists.name ORDER BY playlists.id ASC LIMIT 1; `; try { const result = await client.query(query, [userId]); if (result.rows.length === 0) { logger.write("No 'See Later' playlist found for user with id " + userId, 404); client.release(); res.status(404).json({ error: "'See Later' playlist not found" }); return; } logger.write("'See Later' playlist retrieved for user with id " + userId, 200); client.release(); res.status(200).json(result.rows[0].videos); } catch (error) { logger.write("Error retrieving 'See Later' playlist: " + error.message, 500); client.release(); res.status(500).json({ error: "Internal server error" }); } }