import { Button } from "@/components/ui/button" import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card" import { ArrowLeft, PlayCircle, History, Calendar, Trophy, Youtube, Star } from "lucide-react" import Link from "next/link" import { notFound } from "next/navigation" import { Badge } from "@/components/ui/badge" import { getApiUrl } from "@/lib/api-config" import { CommentSection } from "@/components/social/comment-section" import { EntityRating } from "@/components/social/entity-rating" import { EntityReviews } from "@/components/reviews/entity-reviews" import { SocialWrapper } from "@/components/social/social-wrapper" import { PerformanceList } from "@/components/songs/performance-list" import { SongEvolutionChart } from "@/components/songs/song-evolution-chart" import { YouTubeEmbed } from "@/components/ui/youtube-embed" async function getSong(id: string) { try { const res = await fetch(`${getApiUrl()}/songs/${id}`, { cache: 'no-store' }) if (!res.ok) return null return res.json() } catch (e) { console.error(e) return null } } // Fetch cross-band versions of this song via SongCanon async function getRelatedVersions(songId: number) { try { const res = await fetch(`${getApiUrl()}/canon/song/${songId}/related`, { next: { revalidate: 60 } }) if (!res.ok) return [] return res.json() } catch { return [] } } // Get top rated performances for "Heady Version" leaderboard function getHeadyVersions(performances: any[]) { if (!performances || performances.length === 0) return [] return [...performances] .filter(p => p.avg_rating && p.rating_count > 0) .sort((a, b) => b.avg_rating - a.avg_rating) .slice(0, 5) } export default async function SongDetailPage({ params }: { params: Promise<{ slug: string }> }) { const { slug } = await params const song = await getSong(slug) if (!song) { notFound() } const headyVersions = getHeadyVersions(song.performances || []) const topPerformance = headyVersions[0] // Fetch cross-band versions const relatedVersions = await getRelatedVersions(song.id) return (

{song.title}

{song.artist ? ( ({song.artist.name}) ) : song.original_artist ? ( ({song.original_artist}) ) : null}
{song.tags && song.tags.length > 0 && (
{song.tags.map((tag: any) => ( #{tag.name} ))}
)}
Times Played
{song.times_played}
Gap (Shows)
{song.gap}
Last Played
{song.last_played ? new Date(song.last_played).toLocaleDateString() : "Never"}
{/* Set Breakdown */} {song.set_breakdown && Object.keys(song.set_breakdown).length > 0 && ( Set Distribution
{Object.entries(song.set_breakdown).sort((a, b) => (b[1] as number) - (a[1] as number)).map(([set, count]) => (
{count as number} {set}
))}
)} {/* Heady Version Section */} {headyVersions.length > 0 && ( Heady Version Leaderboard {/* Top Performance with YouTube */} {topPerformance && (
{topPerformance.youtube_link ? ( ) : song.youtube_link ? ( ) : (

No video available

)}
🏆 #1 Heady

{topPerformance.show?.date ? new Date(topPerformance.show.date).toLocaleDateString() : "Unknown Date"}

{topPerformance.show?.venue?.name || "Unknown Venue"}

{topPerformance.avg_rating?.toFixed(1)} ({topPerformance.rating_count} ratings)
)} {/* Leaderboard List */}
{headyVersions.map((perf, index) => (
{index === 0 ? "🥇" : index === 1 ? "🥈" : index === 2 ? "🥉" : `${index + 1}.`}

{perf.show?.date ? new Date(perf.show.date).toLocaleDateString() : "Unknown"}

{perf.show?.venue?.name || "Unknown Venue"}

{perf.youtube_link && ( )}
{perf.avg_rating?.toFixed(1)}★ ({perf.rating_count})
))}
)} {/* Performance List Component (Handles Client Sorting) */}
) }