import { MostPlayedByCard } from "@/components/songs/most-played-by-card" 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 && (
Original Artist: {song.original_artist}
)} {song.tags && song.tags.length > 0 && (
{song.tags.map((tag: any) => ( #{tag.name} ))}
)}
{/* Left Sidebar: Stats & Charts */}
{/* Basic Stats Grid - Compact */}
Times Played
{song.times_played}
Gap
{song.gap}
Last Played
{song.last_played ? new Date(song.last_played).toLocaleDateString(undefined, { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' }) : "Never"}
{/* Most Played By */} {song.artist_distribution && ( )} {/* 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]) => (
{set} {count as number}
))}
)}
{/* Right Content: Performance History */}
{/* Song Evolution (moved to bottom) */}
{/* 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})
))}
)} {/* Cross-Band Versions */} {relatedVersions && relatedVersions.length > 0 && ( Also Played By

This song is performed by {relatedVersions.length + 1} different bands

{relatedVersions.map((version: any) => (

{version.vertical_name}

{version.title}

View →
))}
)}
) }