package com.fabledsword.minstrel.api.endpoints

import com.fabledsword.minstrel.models.wire.PlaylistDetailWire
import com.fabledsword.minstrel.models.wire.PlaylistsListWire
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import retrofit2.http.Body
import retrofit2.http.GET
import retrofit2.http.POST
import retrofit2.http.Path
import retrofit2.http.Query

/**
 * Retrofit interface for `/api/playlists`. Mirrors
 * `flutter_client/lib/api/endpoints/playlists.dart`.
 */
interface PlaylistsApi {
    /**
     * `kind` = "user" | "system" | "all". Server returns
     * `{"owned": [...], "public": [...]}` — `owned` is the caller's
     * playlists filtered by kind, `public` is other users' shared
     * playlists (not kind-filtered).
     */
    @GET("api/playlists")
    suspend fun list(@Query("kind") kind: String = "all"): PlaylistsListWire

    @GET("api/playlists/{id}")
    suspend fun get(@Path("id") id: String): PlaylistDetailWire

    /**
     * POST /api/playlists/{id}/tracks — append the given track IDs to
     * the owner's playlist. Server is idempotent at the (playlist_id,
     * track_id) pair level; re-firing the same payload yields no
     * duplicates.
     */
    @POST("api/playlists/{id}/tracks")
    suspend fun appendTracks(
        @Path("id") playlistId: String,
        @Body body: AppendTracksRequest,
    )

    /**
     * POST /api/playlists/system/{kind}/refresh — rebuild the caller's
     * system playlist of the given variant ("for_you" / "discover" /
     * etc.). Returns the new playlist UUID (the rebuild rotates the
     * id); playlistId is null when the library is empty / build can't
     * pick seed tracks. The kind is the raw system_variant.
     */
    @POST("api/playlists/system/{kind}/refresh")
    suspend fun refreshSystem(@Path("kind") variant: String): RefreshSystemResponse

    /**
     * GET /api/playlists/system/{kind}/shuffle (#415 / #411 R2). Returns
     * the system playlist's tracks in rotation-aware order without
     * rebuilding — used by the Home play-button overlay so taps on For
     * You / Discover / Today's mix advance rotation rather than picking
     * the stored order. Mirrors `playlists.dart.systemShuffle`.
     */
    @GET("api/playlists/system/{kind}/shuffle")
    suspend fun systemShuffle(@Path("kind") variant: String): PlaylistDetailWire
}

/**
 * POST /api/playlists/{id}/tracks body. Server expects snake_case
 * `track_ids` per the Flutter wire shape.
 */
@Serializable
data class AppendTracksRequest(
    @SerialName("track_ids") val trackIds: List<String>,
)

/**
 * Response body for the system-refresh endpoint. `playlistId` is the
 * uuid of the rebuilt playlist, or null when the build had nothing
 * to seed from.
 */
@Serializable
data class RefreshSystemResponse(
    @SerialName("playlist_id") val playlistId: String? = null,
)
