package cy.hexor.furumi.data.remote.api

import cy.hexor.furumi.data.remote.model.ArtistPageResponse
import cy.hexor.furumi.data.remote.model.ArtistDetailResponse
import cy.hexor.furumi.data.remote.model.PlayHistoryPageResponse
import cy.hexor.furumi.data.remote.model.ReleaseDetailResponse
import cy.hexor.furumi.data.remote.model.AddPlaylistTracksRequest
import cy.hexor.furumi.data.remote.model.CreatePlaylistRequest
import cy.hexor.furumi.data.remote.model.DeviceActiveRequest
import cy.hexor.furumi.data.remote.model.DeviceCommandRequest
import cy.hexor.furumi.data.remote.model.DevicePollRequest
import cy.hexor.furumi.data.remote.model.DevicePollResponse
import cy.hexor.furumi.data.remote.model.JamCreateRequest
import cy.hexor.furumi.data.remote.model.JamInviteRequest
import cy.hexor.furumi.data.remote.model.JamJoinRequest
import cy.hexor.furumi.data.remote.model.JamUserResponse
import cy.hexor.furumi.data.remote.model.LikeToggleResponse
import cy.hexor.furumi.data.remote.model.LikedTrackIdsResponse
import cy.hexor.furumi.data.remote.model.OfflineManifestResponse
import cy.hexor.furumi.data.remote.model.PlaylistCardResponse
import cy.hexor.furumi.data.remote.model.PlaylistDetailResponse
import cy.hexor.furumi.data.remote.model.RecordHistoryRequest
import cy.hexor.furumi.data.remote.model.SearchResponse
import cy.hexor.furumi.data.remote.model.SharePlaylistRequest
import cy.hexor.furumi.data.remote.model.SharePlaylistResponse
import cy.hexor.furumi.data.remote.model.TrackItemResponse
import cy.hexor.furumi.data.remote.model.TracksByIdsRequest
import retrofit2.Response
import retrofit2.http.Body
import retrofit2.http.DELETE
import retrofit2.http.GET
import retrofit2.http.Headers
import retrofit2.http.POST
import retrofit2.http.Query
import retrofit2.http.Url

interface PlayerApi {
    @Headers("Accept: application/json")
    @GET
    suspend fun artists(
        @Url url: String,
        @Query("page") page: Int,
        @Query("limit") limit: Int,
        @Query("mine") mine: Boolean
    ): Response<ArtistPageResponse>

    @Headers("Accept: application/json")
    @GET
    suspend fun artistDetail(
        @Url url: String
    ): Response<ArtistDetailResponse>

    @Headers("Accept: application/json")
    @GET
    suspend fun releaseDetail(
        @Url url: String
    ): Response<ReleaseDetailResponse>

    @Headers("Accept: application/json")
    @GET
    suspend fun search(
        @Url url: String,
        @Query("q") query: String,
        @Query("limit") limit: Int
    ): Response<SearchResponse>

    @Headers("Accept: application/json")
    @GET
    suspend fun history(
        @Url url: String,
        @Query("page") page: Int,
        @Query("limit") limit: Int
    ): Response<PlayHistoryPageResponse>

    @Headers("Accept: application/json")
    @POST
    suspend fun toggleLike(
        @Url url: String
    ): Response<LikeToggleResponse>

    @Headers("Accept: application/json")
    @GET
    suspend fun likes(
        @Url url: String
    ): Response<LikedTrackIdsResponse>

    @Headers("Accept: application/json", "Content-Type: application/json")
    @POST
    suspend fun recordHistory(
        @Url url: String,
        @Body body: RecordHistoryRequest
    ): Response<Unit>

    @Headers("Accept: application/json")
    @GET
    suspend fun playlists(
        @Url url: String
    ): Response<List<PlaylistCardResponse>>

    @Headers("Accept: application/json")
    @GET
    suspend fun offlineManifest(
        @Url url: String
    ): Response<OfflineManifestResponse>

    @Headers("Accept: application/json", "Content-Type: application/json")
    @POST
    suspend fun tracksByIds(
        @Url url: String,
        @Body body: TracksByIdsRequest
    ): Response<List<TrackItemResponse>>

    @Headers("Accept: application/json")
    @GET
    suspend fun playlistDetail(
        @Url url: String
    ): Response<PlaylistDetailResponse>

    @Headers("Accept: application/json", "Content-Type: application/json")
    @POST
    suspend fun createPlaylist(
        @Url url: String,
        @Body body: CreatePlaylistRequest
    ): Response<PlaylistCardResponse>

    @Headers("Accept: application/json")
    @DELETE
    suspend fun deletePlaylist(
        @Url url: String
    ): Response<Unit>

    @Headers("Accept: application/json", "Content-Type: application/json")
    @POST
    suspend fun addTracksToPlaylist(
        @Url url: String,
        @Body body: AddPlaylistTracksRequest
    ): Response<Unit>

    @Headers("Accept: application/json", "Content-Type: application/json")
    @POST
    suspend fun sharePlaylist(
        @Url url: String,
        @Body body: SharePlaylistRequest
    ): Response<SharePlaylistResponse>

    @Headers("Accept: application/json", "Content-Type: application/json")
    @POST
    suspend fun pollDevice(
        @Url url: String,
        @Body body: DevicePollRequest
    ): Response<DevicePollResponse>

    @Headers("Accept: application/json", "Content-Type: application/json")
    @POST
    suspend fun setActiveDevice(
        @Url url: String,
        @Body body: DeviceActiveRequest
    ): Response<DevicePollResponse>

    @Headers("Accept: application/json", "Content-Type: application/json")
    @POST
    suspend fun sendDeviceCommand(
        @Url url: String,
        @Body body: DeviceCommandRequest
    ): Response<Unit>

    @Headers("Accept: application/json", "Content-Type: application/json")
    @POST
    suspend fun createJam(
        @Url url: String,
        @Body body: JamCreateRequest
    ): Response<DevicePollResponse>

    @Headers("Accept: application/json", "Content-Type: application/json")
    @POST
    suspend fun joinJam(
        @Url url: String,
        @Body body: JamJoinRequest
    ): Response<DevicePollResponse>

    @Headers("Accept: application/json", "Content-Type: application/json")
    @POST
    suspend fun leaveJam(
        @Url url: String,
        @Body body: JamJoinRequest
    ): Response<DevicePollResponse>

    @Headers("Accept: application/json")
    @GET
    suspend fun searchJamUsers(
        @Url url: String,
        @Query("q") query: String,
        @Query("limit") limit: Int
    ): Response<List<JamUserResponse>>

    @Headers("Accept: application/json", "Content-Type: application/json")
    @POST
    suspend fun inviteToJam(
        @Url url: String,
        @Body body: JamInviteRequest
    ): Response<DevicePollResponse>
}
