package com.ponzischeme89.memby.data.remote

import com.ponzischeme89.memby.data.model.AuthRequest
import com.ponzischeme89.memby.data.model.AuthResult
import com.ponzischeme89.memby.data.model.ItemsResult
import com.ponzischeme89.memby.data.model.PlaybackReport
import com.ponzischeme89.memby.data.model.PlaybackInfo
import com.ponzischeme89.memby.data.model.PlaybackInfoRequest
import com.ponzischeme89.memby.data.model.UserItemData
import retrofit2.http.Body
import retrofit2.http.DELETE
import retrofit2.http.GET
import retrofit2.http.POST
import retrofit2.http.Path
import retrofit2.http.Query
import retrofit2.http.QueryMap

interface EmbyApi {

    @POST("Users/AuthenticateByName")
    suspend fun authenticate(@Body body: AuthRequest): AuthResult

    /**
     * The reachability probe on the direct path. Unauthenticated and tiny by design: a
     * probe that needed a token would report a stale session as a server outage, and the
     * response is discarded — only whether it arrived is the answer.
     */
    @GET("System/Info/Public")
    suspend fun systemInfoPublic(): okhttp3.ResponseBody

    @GET("Users/{userId}/Items")
    suspend fun getItems(
        @Path("userId") userId: String,
        @QueryMap params: Map<String, String>,
    ): ItemsResult

    @GET("Users/{userId}/Items/{itemId}")
    suspend fun getItem(
        @Path("userId") userId: String,
        @Path("itemId") itemId: String,
        @Query("Fields") fields: String,
    ): com.ponzischeme89.memby.data.model.BaseItem

    @POST("Items/{itemId}/PlaybackInfo")
    suspend fun getPlaybackInfo(
        @Path("itemId") itemId: String,
        @Query("UserId") userId: String,
        @Query("IsPlayback") isPlayback: Boolean = true,
        @Body body: PlaybackInfoRequest,
    ): PlaybackInfo

    @GET("Users/{userId}/Items/Resume")
    suspend fun getResumeItems(
        @Path("userId") userId: String,
        @QueryMap params: Map<String, String>,
    ): ItemsResult

    @GET("Users/{userId}/Items/{itemId}/LocalTrailers")
    suspend fun getLocalTrailers(
        @Path("userId") userId: String,
        @Path("itemId") itemId: String,
    ): ItemsResult

    /**
     * Emby's own similarity ranking. The direct path has no recommendation engine behind
     * it, so this is the whole of "More like this" when the gateway is not in play.
     */
    @GET("Items/{itemId}/Similar")
    suspend fun getSimilar(
        @Path("itemId") itemId: String,
        @QueryMap params: Map<String, String>,
    ): ItemsResult

    @GET("Shows/NextUp")
    suspend fun getNextUp(@QueryMap params: Map<String, String>): ItemsResult

    @POST("Sessions/Playing")
    suspend fun reportPlaybackStarted(@Body body: PlaybackReport)

    @POST("Sessions/Playing/Progress")
    suspend fun reportPlaybackProgress(@Body body: PlaybackReport)

    @POST("Sessions/Playing/Stopped")
    suspend fun reportPlaybackStopped(@Body body: PlaybackReport)

    @GET("Shows/{seriesId}/Episodes")
    suspend fun getEpisodes(
        @Path("seriesId") seriesId: String,
        @QueryMap params: Map<String, String>,
    ): ItemsResult

    @POST("Users/{userId}/FavoriteItems/{itemId}")
    suspend fun addFavorite(
        @Path("userId") userId: String,
        @Path("itemId") itemId: String,
    ): UserItemData

    @DELETE("Users/{userId}/FavoriteItems/{itemId}")
    suspend fun removeFavorite(
        @Path("userId") userId: String,
        @Path("itemId") itemId: String,
    ): UserItemData

    @POST("Users/{userId}/PlayedItems/{itemId}")
    suspend fun markPlayed(
        @Path("userId") userId: String,
        @Path("itemId") itemId: String,
    ): UserItemData

    @DELETE("Users/{userId}/PlayedItems/{itemId}")
    suspend fun markUnplayed(
        @Path("userId") userId: String,
        @Path("itemId") itemId: String,
    ): UserItemData

    /** Hides an item from Emby's resume/next-up feeds without changing watched state. */
    @POST("Users/{userId}/Items/{itemId}/HideFromResume")
    suspend fun hideFromResume(
        @Path("userId") userId: String,
        @Path("itemId") itemId: String,
        @Query("Hide") hide: Boolean = true,
    ): UserItemData
}
