const express = require("express"); const router = express.Router(); const { query } = require("../db"); const { v4: uuidv4 } = require("uuid"); // GET all profiles router.get("/", async (req, res) => { try { const result = await query("SELECT * FROM profiles ORDER BY name ASC"); res.json({ success: true, profiles: result.rows }); } catch (err) { console.error("Error fetching profiles:", err); res .status(500) .json({ success: false, message: "Failed to fetch profiles" }); } }); // GET single profile by ID router.get("/:id", async (req, res) => { try { const result = await query("SELECT * FROM profiles WHERE id = $1", [ req.params.id, ]); if (result.rows.length === 0) { return res .status(404) .json({ success: false, message: "Profile not found" }); } // Also get profile's songs with their preferred keys const songsResult = await query( ` SELECT s.*, psk.song_key as preferred_key FROM songs s INNER JOIN profile_songs ps ON s.id = ps.song_id LEFT JOIN profile_song_keys psk ON ps.profile_id = psk.profile_id AND ps.song_id = psk.song_id WHERE ps.profile_id = $1 ORDER BY s.title ASC `, [req.params.id], ); res.json({ success: true, profile: result.rows[0], songs: songsResult.rows, }); } catch (err) { console.error("Error fetching profile:", err); res .status(500) .json({ success: false, message: "Failed to fetch profile" }); } }); // POST create new profile router.post("/", async (req, res) => { try { const { first_name, last_name, name, email, contact_number, notes, default_key, } = req.body; const profileName = name || `${first_name || ""} ${last_name || ""}`.trim(); if (!profileName) { return res .status(400) .json({ success: false, message: "Name is required" }); } const id = uuidv4(); const result = await query( `INSERT INTO profiles (id, first_name, last_name, name, email, contact_number, notes, default_key) VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING *`, [ id, first_name || "", last_name || "", profileName, email || "", contact_number || "", notes || "", default_key || "C", ], ); res.status(201).json({ success: true, profile: result.rows[0] }); } catch (err) { console.error("Error creating profile:", err); res .status(500) .json({ success: false, message: "Failed to create profile" }); } }); // PUT update profile router.put("/:id", async (req, res) => { try { const { first_name, last_name, name, email, contact_number, notes, default_key, } = req.body; const result = await query( `UPDATE profiles SET first_name = COALESCE($1, first_name), last_name = COALESCE($2, last_name), name = COALESCE($3, name), email = COALESCE($4, email), contact_number = COALESCE($5, contact_number), notes = COALESCE($6, notes), default_key = COALESCE($7, default_key) WHERE id = $8 RETURNING *`, [ first_name, last_name, name, email, contact_number, notes, default_key, req.params.id, ], ); if (result.rows.length === 0) { return res .status(404) .json({ success: false, message: "Profile not found" }); } res.json({ success: true, profile: result.rows[0] }); } catch (err) { console.error("Error updating profile:", err); res .status(500) .json({ success: false, message: "Failed to update profile" }); } }); // DELETE profile router.delete("/:id", async (req, res) => { try { const result = await query( "DELETE FROM profiles WHERE id = $1 RETURNING id", [req.params.id], ); if (result.rows.length === 0) { return res .status(404) .json({ success: false, message: "Profile not found" }); } res.json({ success: true, message: "Profile deleted" }); } catch (err) { console.error("Error deleting profile:", err); res .status(500) .json({ success: false, message: "Failed to delete profile" }); } }); // POST add song to profile router.post("/:id/songs/:songId", async (req, res) => { try { const { id, songId } = req.params; const { song_key } = req.body; const psId = uuidv4(); // Add song to profile await query( `INSERT INTO profile_songs (id, profile_id, song_id) VALUES ($1, $2, $3) ON CONFLICT (profile_id, song_id) DO NOTHING`, [psId, id, songId], ); // If key provided, set it if (song_key) { const pskId = uuidv4(); await query( `INSERT INTO profile_song_keys (id, profile_id, song_id, song_key) VALUES ($1, $2, $3, $4) ON CONFLICT (profile_id, song_id) DO UPDATE SET song_key = $4`, [pskId, id, songId, song_key], ); } res.json({ success: true, message: "Song added to profile" }); } catch (err) { console.error("Error adding song to profile:", err); res .status(500) .json({ success: false, message: "Failed to add song to profile" }); } }); // DELETE remove song from profile router.delete("/:id/songs/:songId", async (req, res) => { try { const { id, songId } = req.params; await query( "DELETE FROM profile_songs WHERE profile_id = $1 AND song_id = $2", [id, songId], ); await query( "DELETE FROM profile_song_keys WHERE profile_id = $1 AND song_id = $2", [id, songId], ); res.json({ success: true, message: "Song removed from profile" }); } catch (err) { console.error("Error removing song from profile:", err); res .status(500) .json({ success: false, message: "Failed to remove song from profile" }); } }); // GET profile count router.get("/stats/count", async (req, res) => { try { const result = await query("SELECT COUNT(*) as count FROM profiles"); res.json({ success: true, count: parseInt(result.rows[0].count) }); } catch (err) { console.error("Error counting profiles:", err); res .status(500) .json({ success: false, message: "Failed to count profiles" }); } }); module.exports = router;