import mongoose from 'mongoose'; import Track from '../models/Track.js'; export const searchController = { async search(req, res, next) { try { const query = (req.query.q || '').trim(); if (!query) { return res.json({ success: true, data: { tracks: [], artists: [], albums: [] }, }); } const regex = new RegExp(query.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'i'); const tracks = await Track.find({ $or: [ { title: regex }, { artist: regex }, { album: regex }, ], }) .select('-__v') .sort({ createdAt: -1 }) .limit(50) .lean(); const artistMap = new Map(); tracks.forEach(t => { if (!artistMap.has(t.artist)) { artistMap.set(t.artist, { _id: new mongoose.Types.ObjectId(), name: t.artist, imageUrl: t.coverUrl || '', trackCount: 0, }); } const entry = artistMap.get(t.artist); entry.trackCount++; if (t.coverUrl && !entry.imageUrl) { entry.imageUrl = t.coverUrl; } }); const artists = [...artistMap.values()]; const albumMap = new Map(); tracks.forEach(t => { if (!albumMap.has(t.album)) { albumMap.set(t.album, { _id: new mongoose.Types.ObjectId(), title: t.album, artist: t.artist, coverUrl: t.coverUrl || '', trackCount: 0, }); } const entry = albumMap.get(t.album); entry.trackCount++; if (t.coverUrl && !entry.coverUrl) { entry.coverUrl = t.coverUrl; } }); const albums = [...albumMap.values()]; const data = { tracks, artists, albums }; return res.json({ success: true, data }); } catch (error) { return next(error); } }, };