exports.generatePicturePrompt = (project = {}) => { const { title = "", lyrics: lyricsRaw, musicConfig = {}, coverStyle: coverStyleRaw = "", artistName: artistNameRaw = "", } = project || {}; const sanitizeInline = (value = "") => { if (typeof value !== "string") return ""; return value .replace(/[\r\n]+/g, " ") .replace(/[<>]/g, "") .trim(); }; const titleForPrompt = sanitizeInline(title) || "Sans titre"; const artistName = sanitizeInline(artistNameRaw) || sanitizeInline(project?.userName || ""); const hasArtistName = artistName.length > 0; const { genres = [], tempo = "", voice = "", instruments = [], mood = "", } = musicConfig || {}; // Normalise les paroles en tableau de sections { type, lyrics } const lyricsSections = Array.isArray(lyricsRaw) ? lyricsRaw : [ lyricsRaw?.couplet ? { type: "couplet", lyrics: lyricsRaw.couplet } : null, lyricsRaw?.refrain ? { type: "refrain", lyrics: lyricsRaw.refrain } : null, ].filter(Boolean); // Échantillon pour l'ambiance (courtes bribes pour inspirer la direction créative) const lyricsSample = (lyricsSections || []) .map((s) => (s?.lyrics || "").split("\n").slice(0, 2).join(" ")) .filter(Boolean) .slice(0, 6) .join(" | "); // Etiquettes d'ambiance const tags = []; if (Array.isArray(genres) && genres.length) tags.push(`Genres: ${genres.join(", ")}`); if (tempo) tags.push(`Tempo: ${tempo}`); if (Array.isArray(instruments) && instruments.length) tags.push(`Instruments: ${instruments.join(", ")}`); if (voice) tags.push(`Vocal: ${voice}`); if (mood) tags.push(`Mood: ${mood}`); // Guidance palette selon tempo (simple heuristique) const paletteHint = tempo && /\b(rapid|fast|vite|agité|upbeat|energ)/i.test(String(tempo)) ? "Palette vive et contrastée (magenta, cyan, jaune, bleu électrique)" : "Palette harmonieuse et douce (bleu nuit, violet, corail, or pâle)"; const coverStyle = String(coverStyleRaw || "").trim(); const tagsLine = tags.join(" ; ") || "Non spécifié"; const lyricsLine = lyricsSample || "Pas d'extraits fournis"; const styleLine = coverStyle ? `${coverStyle}. ${paletteHint}` : `${paletteHint}. Style libre, artistique et lumineux.`; const typographyLine = hasArtistName ? `Reproduis strictement le titre de la chanson ${titleForPrompt} sans modification, sans traduction et sans ajout ou suppression de caractères. Ajoute également le nom de l'artiste ${artistName} de manière artistique, parfaitement lisible et hiérarchisée, en harmonie avec le style abstrait et lumineux de la pochette.` : `Reproduis strictement le titre de la chanson ${titleForPrompt} sans modification, sans traduction et sans ajout ou suppression de caractères. Intègre-le de manière artistique et parfaitement lisible, en harmonie avec le style abstrait et lumineux de la pochette.`; const artistLine = hasArtistName ? ` ${artistName}\n` : ""; const prompt = ` Créer une pochette d'album en adéquation avec les paroles de la musique et qui respecte le style ${coverStyle} ${titleForPrompt} ${artistLine} ${tagsLine} ${lyricsLine} Image carrée 1024x1024 pixels, résolution haute. La composition doit être dynamique et remplir toute la surface, sans laisser de bordures ni de zones vides. ${typographyLine} Aucune faute d'orthographe n'est tolérée. Respecte la casse et l'orthographe exactes du titre fourni. Personnes, visages ou silhouettes reconnaissables. Fonds blancs ou bordures délimitant l'image. Texte illisible ou trop petit. `.trim(); return prompt; };