package org.dueattendant149.bookshelf.data.remote.bookshelfapi

import okhttp3.ResponseBody
import org.dueattendant149.bookshelf.data.remote.bookshelfapi.model.BookItemResponse
import org.dueattendant149.bookshelf.data.remote.bookshelfapi.model.DownloadRequest
import org.dueattendant149.bookshelf.data.remote.bookshelfapi.model.DownloadResponse
import org.dueattendant149.bookshelf.data.remote.bookshelfapi.model.DownloadsListResponse
import org.dueattendant149.bookshelf.data.remote.bookshelfapi.model.LibraryResponse
import org.dueattendant149.bookshelf.data.remote.bookshelfapi.model.PodcastRequest
import org.dueattendant149.bookshelf.data.remote.bookshelfapi.model.PodcastResponse
import org.dueattendant149.bookshelf.data.remote.bookshelfapi.model.SearchRequest
import org.dueattendant149.bookshelf.data.remote.bookshelfapi.model.SearchResponse
import org.dueattendant149.bookshelf.data.remote.bookshelfapi.model.TtsCreateRequest
import org.dueattendant149.bookshelf.data.remote.bookshelfapi.model.TtsEnginesResponse
import org.dueattendant149.bookshelf.data.remote.bookshelfapi.model.TtsJobResponse
import org.dueattendant149.bookshelf.data.remote.bookshelfapi.model.TtsJobsResponse
import org.dueattendant149.bookshelf.data.remote.bookshelfapi.model.TtsVoicesResponse
import org.dueattendant149.bookshelf.data.remote.bookshelfapi.model.YandexRequest
import org.dueattendant149.bookshelf.data.remote.bookshelfapi.model.YandexResponse
import retrofit2.Response
import retrofit2.http.Body
import retrofit2.http.GET
import retrofit2.http.POST
import retrofit2.http.Path
import retrofit2.http.Query
import retrofit2.http.Streaming

/**
 * Retrofit description of the Bookshelf API (bookshelf-api:8073).
 * All endpoints are relative to the configured base URL.
 */
interface BookshelfApiService {

    // Health
    @GET("health")
    suspend fun health(): Response<String>

    // Libraries / books
    @GET("api/v1/books/libraries")
    suspend fun getLibraries(): Response<List<LibraryResponse>>

    @GET("api/v1/books/{itemId}")
    suspend fun getBook(
        @Path("itemId") itemId: String,
    ): Response<String>

    @GET("api/v1/books/library/{libraryId}/search")
    suspend fun searchLibrary(
        @Path("libraryId") libraryId: String,
        @Query("q") query: String,
    ): Response<List<BookItemResponse>>

    @POST("api/v1/search")
    suspend fun search(
        @Body request: SearchRequest,
    ): Response<SearchResponse>

    // TTS
    @GET("api/v1/tts/engines")
    suspend fun getTtsEngines(): Response<TtsEnginesResponse>

    @GET("api/v1/tts/voices")
    suspend fun getTtsVoices(
        @Query("engine") engine: String? = null,
    ): Response<TtsVoicesResponse>

    @POST("api/v1/tts")
    suspend fun createTtsJob(
        @Body request: TtsCreateRequest,
    ): Response<TtsJobResponse>

    @GET("api/v1/tts/{jobId}")
    suspend fun getTtsJobStatus(
        @Path("jobId") jobId: String,
    ): Response<TtsJobResponse>

    @GET("api/v1/tts/jobs/list")
    suspend fun listTtsJobs(): Response<TtsJobsResponse>

    @Streaming
    @GET("api/v1/tts/{jobId}/download")
    suspend fun downloadTtsAudio(
        @Path("jobId") jobId: String,
    ): Response<ResponseBody>

    // Downloads / sources
    @POST("api/v1/download")
    suspend fun startDownload(
        @Body request: DownloadRequest,
    ): Response<DownloadResponse>

    @GET("api/v1/download/list")
    suspend fun listDownloads(): Response<DownloadsListResponse>

    @POST("api/v1/podcasts")
    suspend fun downloadPodcast(
        @Body request: PodcastRequest,
    ): Response<PodcastResponse>

    @POST("api/v1/sources/yandex")
    suspend fun downloadYandex(
        @Body request: YandexRequest,
    ): Response<YandexResponse>
}
