/// Library Provider - Library state management library; import 'dart:async'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../../../infrastructure/datasources/remote/playlist_api_service.dart'; import '../../../infrastructure/datasources/remote/music_api_service.dart'; import '../../../domain/entities/playlist.dart'; import '../../../domain/entities/track.dart'; import '../../../domain/entities/album.dart'; import '../../../domain/entities/artist.dart'; /// Library state class LibraryState { final List playlists; final List likedSongs; final List savedAlbums; final List followedArtists; final bool isLoading; final String? error; const LibraryState({ this.playlists = const [], this.likedSongs = const [], this.savedAlbums = const [], this.followedArtists = const [], this.isLoading = false, this.error, }); LibraryState copyWith({ List? playlists, List? likedSongs, List? savedAlbums, List? followedArtists, bool? isLoading, String? error, }) { return LibraryState( playlists: playlists ?? this.playlists, likedSongs: likedSongs ?? this.likedSongs, savedAlbums: savedAlbums ?? this.savedAlbums, followedArtists: followedArtists ?? this.followedArtists, isLoading: isLoading ?? this.isLoading, error: error, ); } int get totalItems => playlists.length + likedSongs.length + savedAlbums.length + followedArtists.length; } /// Library notifier class LibraryNotifier extends StateNotifier { LibraryNotifier(this._playlistApiService, this._musicApiService) : super(const LibraryState()); final PlaylistApiService _playlistApiService; final MusicApiService _musicApiService; Future loadLibrary() async { state = state.copyWith(isLoading: true, error: null); try { // Load playlists in parallel final results = await Future.wait([ _loadPlaylists(), // TODO: Implement these endpoints when backend is ready // _loadLikedSongs(), // _loadSavedAlbums(), // _loadFollowedArtists(), ]); state = LibraryState( playlists: results[0] as List, likedSongs: [], savedAlbums: [], followedArtists: [], ); } catch (e) { state = LibraryState( playlists: state.playlists, likedSongs: state.likedSongs, savedAlbums: state.savedAlbums, followedArtists: state.followedArtists, error: e.toString(), ); } finally { state = state.copyWith(isLoading: false); } } Future> _loadPlaylists() async { final playlistsJson = await _playlistApiService.getPlaylists(); return playlistsJson .map((json) => Playlist.fromJson(json as Map)) .toList(); } Future addLikedSong(Track track) async { // TODO: Implement when backend endpoint is ready final updated = [...state.likedSongs, track]; state = state.copyWith(likedSongs: updated); } Future removeLikedSong(String trackId) async { // TODO: Implement when backend endpoint is ready final updated = state.likedSongs.where((t) => t.id != trackId).toList(); state = state.copyWith(likedSongs: updated); } Future addSavedAlbum(Album album) async { // TODO: Implement when backend endpoint is ready final updated = [...state.savedAlbums, album]; state = state.copyWith(savedAlbums: updated); } Future removeSavedAlbum(String albumId) async { // TODO: Implement when backend endpoint is ready final updated = state.savedAlbums.where((a) => a.id != albumId).toList(); state = state.copyWith(savedAlbums: updated); } Future followArtist(Artist artist) async { // TODO: Implement when backend endpoint is ready final updated = [...state.followedArtists, artist]; state = state.copyWith(followedArtists: updated); } Future unfollowArtist(String artistId) async { // TODO: Implement when backend endpoint is ready final updated = state.followedArtists.where((a) => a.id != artistId).toList(); state = state.copyWith(followedArtists: updated); } Future deletePlaylist(String playlistId) async { await _playlistApiService.deletePlaylist(playlistId); final updated = state.playlists.where((p) => p.id != playlistId).toList(); state = state.copyWith(playlists: updated); } Future createPlaylist({ required String name, String? description, String? imageUrl, bool isPublic = false, }) async { final playlistJson = await _playlistApiService.createPlaylist( name: name, description: description, imageUrl: imageUrl, isPublic: isPublic, ); final playlist = Playlist.fromJson(playlistJson as Map); final updated = [...state.playlists, playlist]; state = state.copyWith(playlists: updated); } Future refresh() async { await loadLibrary(); } } /// Library provider final libraryProvider = StateNotifierProvider((ref) { final playlistApiService = ref.watch(playlistApiServiceProvider); final musicApiService = ref.watch(musicApiServiceProvider); return LibraryNotifier(playlistApiService, musicApiService); });