import 'package:dio/dio.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

import '../api/client.dart';
import '../api/endpoints/library.dart';
import '../auth/auth_provider.dart';
import '../models/album.dart';
import '../models/artist.dart';
import '../models/home_data.dart';
import '../models/track.dart';

/// Shared authenticated dio. This is the ONLY place tokenResolver is wired
/// to the secure-storage `session_token` read — every other endpoint
/// awaits `dioProvider.future` rather than constructing its own dio.
///
/// Riverpod will invalidate any FutureProvider that watches this when
/// the server URL changes; auth state changes don't need to invalidate
/// the provider because the resolver re-reads the token on every request.
final dioProvider = FutureProvider<Dio>((ref) async {
  final url = await ref.watch(serverUrlProvider.future);
  if (url == null || url.isEmpty) {
    throw StateError('no server URL set');
  }
  final storage = ref.watch(secureStorageProvider);
  return ApiClient.buildDio(
    baseUrl: url,
    tokenResolver: () async => storage.read(key: 'session_token'),
    on401: () async => ref.read(authControllerProvider.notifier).clearSession(),
  );
});

final libraryApiProvider = FutureProvider<LibraryApi>((ref) async {
  return LibraryApi(await ref.watch(dioProvider.future));
});

final homeProvider = FutureProvider<HomeData>((ref) async {
  return (await ref.watch(libraryApiProvider.future)).getHome();
});

final artistProvider =
    FutureProvider.family<ArtistRef, String>((ref, id) async {
  return (await ref.watch(libraryApiProvider.future)).getArtist(id);
});

final artistAlbumsProvider =
    FutureProvider.family<List<AlbumRef>, String>((ref, id) async {
  return (await ref.watch(libraryApiProvider.future)).getArtistAlbums(id);
});

final artistTracksProvider =
    FutureProvider.family<List<TrackRef>, String>((ref, id) async {
  return (await ref.watch(libraryApiProvider.future)).getArtistTracks(id);
});

final albumProvider =
    FutureProvider.family<({AlbumRef album, List<TrackRef> tracks}), String>(
  (ref, id) async {
    return (await ref.watch(libraryApiProvider.future)).getAlbum(id);
  },
);
