Public/Get-ShellPhishYearInReview.ps1

function Get-ShellPhishYearInReview {
    <#
    .SYNOPSIS
        Comprehensive statistical summary of a Phish touring year.
    .PARAMETER Year
        Four-digit year to summarize.
    .PARAMETER ExportPath
        Optional file path (.csv or .json) to export results.
    .PARAMETER DelayMs
        Delay in milliseconds between API calls. Default 500.
    .EXAMPLE
        PS C:\> Get-ShellPhishYearInReview -Year 1997
    #>

    [CmdletBinding()]
    param (
        [Parameter(Mandatory=$true)]
        [ValidatePattern('^\d{4}$')]
        [string]$Year,

        [Parameter()]
        [string]$ExportPath,

        [Parameter()]
        [int]$DelayMs = 500
    )

    Write-Verbose "Fetching shows for $Year..."
    $shows = (Get-ShellPhishShows -Year $Year -OrderBy showdate -Direction asc).data

    if (-not $shows) {
        Write-Warning "No shows found for $Year"
        return
    }

    Write-Verbose "Found $($shows.Count) show(s). Fetching setlists..."
    $allSongs = @()
    foreach ($show in $shows) {
        Start-Sleep -Milliseconds $DelayMs
        $setlist = (Get-ShellPhishSetlists -ShowDate $show.showdate).data
        if ($setlist) {
            foreach ($entry in $setlist) {
                $allSongs += [PSCustomObject]@{
                    Song = $entry.song
                    Slug = $entry.slug
                }
            }
        }
    }

    $uniqueSongs = ($allSongs | Select-Object -ExpandProperty Song -Unique).Count
    $states = ($shows | Select-Object -ExpandProperty state -Unique)
    $venues = ($shows | Select-Object -ExpandProperty venue -Unique)

    $topSongs = $allSongs | Group-Object -Property Song |
        Sort-Object Count -Descending |
        Select-Object -First 10 |
        ForEach-Object { [PSCustomObject]@{ Song = $_.Name; TimePlayed = $_.Count } }

    # Jam chart entries
    Write-Verbose "Checking jam chart entries..."
    $jamChartSongs = @()
    $songSlugs = $allSongs | Select-Object -ExpandProperty Slug -Unique
    foreach ($slug in $songSlugs) {
        Start-Sleep -Milliseconds $DelayMs
        $jc = (Get-ShellPhishJamCharts -Slug $slug).data
        if ($jc) {
            $yearEntries = $jc | Where-Object { $_.showdate -like "$Year*" }
            if ($yearEntries) {
                foreach ($entry in $yearEntries) {
                    $jamChartSongs += [PSCustomObject]@{
                        Song     = $entry.song
                        ShowDate = $entry.showdate
                    }
                }
            }
        }
    }

    Write-Host "`n=== $Year YEAR IN REVIEW ===" -ForegroundColor Cyan
    Write-Host "Total shows: $($shows.Count)"
    Write-Host "Unique songs: $uniqueSongs"
    Write-Host "States visited: $($states.Count) ($($states -join ', '))"
    Write-Host "Unique venues: $($venues.Count)"
    Write-Host "Jam chart entries: $($jamChartSongs.Count)"

    Write-Host "`nTop 10 most-played songs:" -ForegroundColor Yellow
    $topSongs | ForEach-Object {
        Write-Host " $($_.TimePlayed)x $($_.Song)"
    }

    if ($jamChartSongs.Count -gt 0) {
        Write-Host "`nJam chart highlights:" -ForegroundColor Yellow
        $jamChartSongs | ForEach-Object {
            Write-Host " $($_.ShowDate) - $($_.Song)"
        }
    }

    if ($ExportPath) {
        $exportData = [PSCustomObject]@{
            Year           = $Year
            TotalShows     = $shows.Count
            UniqueSongs    = $uniqueSongs
            StatesVisited  = $states.Count
            UniqueVenues   = $venues.Count
            JamChartCount  = $jamChartSongs.Count
            TopSongs       = ($topSongs | ForEach-Object { "$($_.TimePlayed)x $($_.Song)" }) -join '; '
        }
        Export-ShellPhishData -Data @($exportData) -ExportPath $ExportPath
    }
}