package com.fabledsword.minstrel.api.endpoints

import com.fabledsword.minstrel.models.wire.AlbumDetailWire
import com.fabledsword.minstrel.models.wire.ArtistDetailWire
import com.fabledsword.minstrel.models.wire.ArtistWire
import com.fabledsword.minstrel.models.wire.TrackWire
import retrofit2.http.GET
import retrofit2.http.Path
import retrofit2.http.Query

/**
 * Retrofit interface for the server's native `/api/...` library surface.
 * Mirrors `flutter_client/lib/api/endpoints/library.dart` 1:1.
 *
 * Notes on shapes:
 *   - `GET /api/artists/{id}` returns ArtistDetailWire (ArtistRef fields
 *     plus embedded "albums" array)
 *   - `GET /api/artists/{id}/tracks` returns a bare JSON array, not an
 *     enveloped object — Retrofit's `List<TrackWire>` return type
 *     handles that.
 *   - `GET /api/albums/{id}` returns AlbumDetailWire (AlbumRef fields
 *     plus embedded "tracks" array)
 *   - `GET /api/library/shuffle` returns a bare JSON array.
 *
 * Home endpoints (`/api/home`, `/api/home/index`) live in a separate
 * `HomeApi` because they have their own wire types (HomePayload,
 * HomeIndex) that are larger and only used by the Home screen.
 */
interface LibraryApi {
    @GET("api/tracks/{id}")
    suspend fun getTrack(@Path("id") id: String): TrackWire

    @GET("api/artists/{id}")
    suspend fun getArtistDetail(@Path("id") id: String): ArtistDetailWire

    @GET("api/artists/{id}/tracks")
    suspend fun getArtistTracks(@Path("id") id: String): List<TrackWire>

    @GET("api/artists/{id}/similar")
    suspend fun getSimilarArtists(
        @Path("id") id: String,
        @Query("limit") limit: Int = SIMILAR_ARTISTS_LIMIT,
    ): List<ArtistWire>

    @GET("api/artists/{id}/top-tracks")
    suspend fun getArtistTopTracks(
        @Path("id") id: String,
        @Query("limit") limit: Int = TOP_TRACKS_LIMIT,
    ): List<TrackWire>

    @GET("api/albums/{id}")
    suspend fun getAlbumDetail(@Path("id") id: String): AlbumDetailWire

    @GET("api/library/shuffle")
    suspend fun shuffleLibrary(@Query("limit") limit: Int = 100): List<TrackWire>

    private companion object {
        const val SIMILAR_ARTISTS_LIMIT = 12
        const val TOP_TRACKS_LIMIT = 5
    }
}
