import 'package:dio/dio.dart';

import '../../models/album.dart';
import '../../models/artist.dart';
import '../../models/page.dart';
import '../../models/track.dart';

enum LikeKind { artist, album, track }

extension LikeKindPath on LikeKind {
  String get path => switch (this) {
        LikeKind.artist => 'artists',
        LikeKind.album => 'albums',
        LikeKind.track => 'tracks',
      };
}

class LikesApi {
  LikesApi(this._dio);
  final Dio _dio;

  Future<void> like(LikeKind kind, String id) async {
    await _dio.post<void>('/api/likes/${kind.path}/$id');
  }

  Future<void> unlike(LikeKind kind, String id) async {
    await _dio.delete<void>('/api/likes/${kind.path}/$id');
  }

  /// GET /api/likes/tracks?limit=N&offset=N. Paged.
  Future<Paged<TrackRef>> listTracks({int limit = 50, int offset = 0}) async {
    final r = await _dio.get<Map<String, dynamic>>(
      '/api/likes/tracks',
      queryParameters: {'limit': limit, 'offset': offset},
    );
    return Paged.fromJson(r.data ?? const {}, TrackRef.fromJson);
  }

  Future<Paged<AlbumRef>> listAlbums({int limit = 50, int offset = 0}) async {
    final r = await _dio.get<Map<String, dynamic>>(
      '/api/likes/albums',
      queryParameters: {'limit': limit, 'offset': offset},
    );
    return Paged.fromJson(r.data ?? const {}, AlbumRef.fromJson);
  }

  Future<Paged<ArtistRef>> listArtists({int limit = 50, int offset = 0}) async {
    final r = await _dio.get<Map<String, dynamic>>(
      '/api/likes/artists',
      queryParameters: {'limit': limit, 'offset': offset},
    );
    return Paged.fromJson(r.data ?? const {}, ArtistRef.fromJson);
  }

  /// Returns sets of {artists, albums, tracks} the user has liked.
  /// Server response keys (verified in internal/api/likes.go
  /// `likedIDsResponse`): `artist_ids`, `album_ids`, `track_ids`.
  Future<({Set<String> artists, Set<String> albums, Set<String> tracks})>
      ids() async {
    final r = await _dio.get<Map<String, dynamic>>('/api/likes/ids');
    final body = r.data ?? const <String, dynamic>{};
    Set<String> set(String key) =>
        ((body[key] as List?) ?? const []).map((e) => e.toString()).toSet();
    return (
      artists: set('artist_ids'),
      albums: set('album_ids'),
      tracks: set('track_ids'),
    );
  }
}
