using allstarr.Models.Domain; namespace allstarr.Models.Spotify; /// /// Represents a track from a Spotify playlist with full metadata including position. /// This model preserves track ordering which is critical for playlists like Release Radar. /// public class SpotifyPlaylistTrack { /// /// Spotify track ID (e.g., "3a8mo25v74BMUOJ1IDUEBL") /// public string SpotifyId { get; set; } = string.Empty; /// /// Track's position in the playlist (0-based index). /// This is critical for maintaining correct playlist order. /// public int Position { get; set; } /// /// Track title /// public string Title { get; set; } = string.Empty; /// /// Album name /// public string Album { get; set; } = string.Empty; /// /// Album Spotify ID /// public string AlbumId { get; set; } = string.Empty; /// /// List of artist names /// public List Artists { get; set; } = new(); /// /// List of artist Spotify IDs /// public List ArtistIds { get; set; } = new(); /// /// ISRC (International Standard Recording Code) for exact track identification. /// This enables precise matching across different streaming services. /// public string? Isrc { get; set; } /// /// Track duration in milliseconds /// public int DurationMs { get; set; } /// /// Whether the track contains explicit content /// public bool Explicit { get; set; } /// /// Track's popularity score (0-100) /// public int Popularity { get; set; } /// /// Preview URL for 30-second audio clip (may be null) /// public string? PreviewUrl { get; set; } /// /// Album artwork URL (largest available) /// public string? AlbumArtUrl { get; set; } /// /// Release date of the album (format varies: YYYY, YYYY-MM, or YYYY-MM-DD) /// public string? ReleaseDate { get; set; } /// /// When this track was added to the playlist /// public DateTime? AddedAt { get; set; } /// /// Disc number within the album /// public int DiscNumber { get; set; } = 1; /// /// Track number within the disc /// public int TrackNumber { get; set; } = 1; /// /// Primary (first) artist name /// public string PrimaryArtist => Artists.FirstOrDefault() ?? string.Empty; /// /// All artists as a comma-separated string /// public string AllArtists => string.Join(", ", Artists); /// /// Track duration as TimeSpan /// public TimeSpan Duration => TimeSpan.FromMilliseconds(DurationMs); /// /// Converts to the legacy MissingTrack format for compatibility with existing matching logic. /// public MissingTrack ToMissingTrack() => new() { SpotifyId = SpotifyId, Title = Title, Album = Album, Artists = Artists }; } /// /// Represents a Spotify playlist with its tracks in order. /// public class SpotifyPlaylist { /// /// Spotify playlist ID /// public string SpotifyId { get; set; } = string.Empty; /// /// Playlist name /// public string Name { get; set; } = string.Empty; /// /// Playlist description /// public string? Description { get; set; } /// /// Playlist owner's display name /// public string? OwnerName { get; set; } /// /// Playlist owner's Spotify ID /// public string? OwnerId { get; set; } /// /// Total number of tracks in the playlist /// public int TotalTracks { get; set; } /// /// Playlist cover image URL /// public string? ImageUrl { get; set; } /// /// Whether this is a collaborative playlist /// public bool Collaborative { get; set; } /// /// Whether this playlist is public /// public bool Public { get; set; } /// /// Tracks in the playlist, ordered by position /// public List Tracks { get; set; } = new(); /// /// When this data was fetched from Spotify /// public DateTime FetchedAt { get; set; } = DateTime.UtcNow; /// /// Snapshot ID for change detection (Spotify's playlist version identifier) /// public string? SnapshotId { get; set; } } /// /// Represents a Spotify track that has been matched to an external provider track. /// Preserves position for correct playlist ordering. /// public class MatchedTrack { /// /// Position in the original Spotify playlist (0-based) /// public int Position { get; set; } /// /// Original Spotify track ID /// public string SpotifyId { get; set; } = string.Empty; /// /// Original Spotify track title (for debugging/logging) /// public string SpotifyTitle { get; set; } = string.Empty; /// /// Original Spotify artist (for debugging/logging) /// public string SpotifyArtist { get; set; } = string.Empty; /// /// ISRC used for matching (if available) /// public string? Isrc { get; set; } /// /// How the match was made: "isrc" or "fuzzy" /// public string MatchType { get; set; } = string.Empty; /// /// The matched song from the external provider /// public Song MatchedSong { get; set; } = null!; }