modules/Core/LegacyApiClient.psm1

# Legacy API Client Module
# Handles the simple token management and API invocation for the main Spotify CLI module.

# --- Module State ---
$script:ApiBase = "https://api.spotify.com/v1"

# --- Public Functions ---

function Invoke-SpotifyApi {
    param(
        [Parameter(Mandatory)][ValidateSet('GET', 'POST', 'PUT', 'DELETE')][string]$Method,
        [Parameter(Mandatory)][string]$Path,
        [hashtable]$Query,
        $Body
    )
    $access = Get-SpotifyAccessToken
    if (-not $access) { return $null }
    # Build the complete URI
    $uri = "$($script:ApiBase)$path"
    if ($Query -and $Query.Count -gt 0) {
        $queryString = ($Query.GetEnumerator() | ForEach-Object {
            "$($_.Key)=$([System.Uri]::EscapeDataString($_.Value))"
        }) -join "&"
        $uri += "?$queryString"
    }
    $headers = @{ Authorization = "Bearer $access" }
    try {
        if ($Body) {
            return Invoke-RestMethod -Method $Method -Uri $uri -Headers $headers -ContentType "application/json" -Body ($Body | ConvertTo-Json -Depth 10)
        } else {
            return Invoke-RestMethod -Method $Method -Uri $uri -Headers $headers
        }
    } catch {
        $statusCode = 0
        if ($_.Exception.Response) {
            $statusCode = [int]$_.Exception.Response.StatusCode
        }

        $responseBody = ""
        if ($_.Exception.Response.GetResponseStream) {
            $streamReader = [System.IO.StreamReader]::new($_.Exception.Response.GetResponseStream())
            $responseBody = $streamReader.ReadToEnd()
            $streamReader.Close()
        }

        switch ($statusCode) {
            401 {
                throw "Spotify API authentication failed. Token may be expired or invalid. (HTTP $statusCode)"
            }
            403 {
                $errorDetails = ($responseBody | ConvertFrom-Json -ErrorAction SilentlyContinue)
                $message = if ($errorDetails) { $errorDetails.error.message } else { "Permission denied. This operation may require a higher scope or Spotify Premium." }
                throw "$message (HTTP $statusCode)"
            }
            404 {
                throw "The requested resource was not found. (HTTP $statusCode)"
            }
            429 {
                $retryAfter = $_.Exception.Response.Headers['Retry-After']
                throw "Rate limited by Spotify. Retry after $retryAfter seconds. (HTTP $statusCode)"
            }
            default {
                throw "An unexpected Spotify API error occurred: $($_.Exception.Message) (HTTP $statusCode)"
            }
        }
    }
}


function Test-SpotifyAuth {
    <#
    .SYNOPSIS
    Check the current Spotify authentication status
    .DESCRIPTION
    Reads the stored token file and reports whether authentication is valid,
    how long until expiry, and which scopes are granted.
    .EXAMPLE
    Test-SpotifyAuth
    #>

    $result = [PSCustomObject]@{
        IsAuthenticated  = $false
        ExpiresInSeconds = 0
        Scopes           = @()
        TokenPath        = (Join-Path $env:APPDATA "SpotifyCLI\tokens.json")
        Error            = $null
    }

    $tokenFile = Join-Path $env:APPDATA "SpotifyCLI\tokens.json"
    if (-not (Test-Path $tokenFile)) {
        $result.Error = "Token file not found. Run Start-SpotifyCLI to authenticate."
        Write-Host "Not authenticated — token file missing." -ForegroundColor Red
        Write-Host " Run: Start-SpotifyCLI" -ForegroundColor Cyan
        return $result
    }

    try {
        $tokens = Get-Content -Path $tokenFile -Raw | ConvertFrom-Json
    } catch {
        $result.Error = "Could not read token file: $_"
        Write-Host "❌ Token file is corrupt or unreadable" -ForegroundColor Red
        return $result
    }

    if (-not $tokens.access_token) {
        $result.Error = "No access token in token file."
        Write-Host "❌ Not authenticated — no access token stored" -ForegroundColor Red
        return $result
    }

    $obtained    = [long]$tokens.obtained_at
    $expiresIn   = [int]$tokens.expires_in
    $age         = [DateTimeOffset]::UtcNow.ToUnixTimeSeconds() - $obtained
    $remaining   = $expiresIn - $age

    if ($remaining -le 0) {
        $result.Error = "Token has expired."
        Write-Host "❌ Token expired" -ForegroundColor Red
        if ($tokens.refresh_token) {
            Write-Host " A refresh token is available — run .\spotifyCLI.ps1 to refresh" -ForegroundColor Yellow
        }
        return $result
    }

    $result.IsAuthenticated  = $true
    $result.ExpiresInSeconds = [int]$remaining
    $result.Scopes           = if ($tokens.scopes) { $tokens.scopes -split ' ' } else { @() }

    $minutesLeft = [Math]::Floor($remaining / 60)
    Write-Host "✅ Authenticated" -ForegroundColor Green
    Write-Host " Token expires in: $minutesLeft minutes" -ForegroundColor Gray
    Write-Host " Scopes: $($result.Scopes.Count) granted" -ForegroundColor Gray
    Write-Host " Token file: $(Join-Path $env:APPDATA 'SpotifyCLI\tokens.json')" -ForegroundColor Gray

    return $result
}


# --- Module Exports ---

Export-ModuleMember -Function 'Invoke-SpotifyApi', 'Test-SpotifyAuth'