package com.example.myapplication.api

import com.example.myapplication.api.bike.BikeRemote
import com.example.myapplication.api.rent.RentRemote
import com.example.myapplication.api.item.ItemFromBikeRemote
import com.example.myapplication.api.item.ItemRemote
import com.example.myapplication.api.item.ItemWithBikeRemote
import com.example.myapplication.api.user.UserRemote
import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory
import kotlinx.serialization.json.Json
import kotlinx.serialization.modules.SerializersModule
import kotlinx.serialization.modules.contextual
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.http.Body
import retrofit2.http.DELETE
import retrofit2.http.GET
import retrofit2.http.POST
import retrofit2.http.PUT
import retrofit2.http.Path
import retrofit2.http.Query

interface MyServerService {
    @GET("rents")
    suspend fun getRents(): List<RentRemote>
    @GET("users/{id}")
    suspend fun getUser(
        @Path("id") id: Int,
    ): UserRemote

    @GET("users")
    suspend fun getUsers(): List<UserRemote>

    @POST("users")
    suspend fun createUser(
        @Body user: UserRemote,
    ): UserRemote
    @PUT("users/{id}")
    suspend fun updateUser(
        @Path("id") id: Int,
        @Body user: UserRemote,
    ): UserRemote
    @DELETE("users/{id}")
    suspend fun deleteUser(
        @Path("id") id: Int,
    ): UserRemote

    @GET("bikes")
    suspend fun getBikes(
        @Query("_page") page: Int,
        @Query("_limit") limit: Int,
    ): List<BikeRemote>

    @GET("bikes/{id}")
    suspend fun getBike(
        @Path("id") id: Int,
    ): BikeRemote

    @POST("bikes")
    suspend fun createBike(
        @Body bike: BikeRemote,
    ): BikeRemote

    @PUT("bikes/{id}")
    suspend fun updateBike(
        @Path("id") id: Int,
        @Body bike: BikeRemote,
    ): BikeRemote

    @DELETE("bikes/{id}")
    suspend fun deleteBike(
        @Path("id") id: Int,
    )

    @GET("bikes/{bikeId}/items")
    suspend fun getItemsForBike(
        @Path("bikeId") bikeId: Int
    ): List<ItemFromBikeRemote>

    @GET("items/{id}?_expand=bike")
    suspend fun getItem(
        @Path("id") id: Int,
    ): ItemWithBikeRemote

    @POST("items")
    suspend fun createItem(
        @Body item: ItemRemote,
    ): ItemRemote

    @PUT("items/{id}")
    suspend fun updateItem(
        @Path("id") id: Int,
        @Body item: ItemRemote,
    ): ItemRemote

    @DELETE("items/{id}")
    suspend fun deleteItem(
        @Path("id") id: Int,
    ): ItemFromBikeRemote

    @GET("users/{id}")
    suspend fun getUserCart(
        @Path("id") id: Int,
    ): UserRemote

    @PUT("users/{id}")
    suspend fun updateUserCart(
        @Path("id") id: Int,
        @Body userRemote: UserRemote,
    ): UserRemote

    @GET("rents")
    suspend fun getRents(
        @Query("_page") page: Int,
        @Query("_limit") limit: Int,
    ): List<RentRemote>

    @GET("rents/{id}")
    suspend fun getRent(
        @Path("id") id: Int,
    ): RentRemote

    @POST("rents")
    suspend fun createRent(
        @Body bike: RentRemote,
    ): RentRemote

    @DELETE("rents/{id}")
    suspend fun deleteRent(
        @Path("id") id: Int
    )

    @PUT("rents/{id}")
    suspend fun updateRent(
        @Path("id") id: Int,
        @Body rentRemote: RentRemote,
    ): RentRemote

    companion object {
        private const val BASE_URL = "http://192.168.0.104:8079/"
        //private const val BASE_URL = "http://10.0.2.2:8079/"

        @Volatile
        private var INSTANCE: MyServerService? = null

        fun getInstance(): MyServerService {
            return INSTANCE ?: synchronized(this) {
                val logger = HttpLoggingInterceptor()
                logger.level = HttpLoggingInterceptor.Level.BASIC
                val client = OkHttpClient.Builder().addInterceptor(logger).build()
                val json = Json {
                    ignoreUnknownKeys = true
                    serializersModule = SerializersModule {
                        contextual(LocalDateTimeSerializer)
                    }
                } // Создаем экземпляр Json с ignoreUnknownKeys = true
                return Retrofit.Builder().baseUrl(BASE_URL).client(client)
                    .addConverterFactory(json.asConverterFactory("application/json".toMediaType())) // Применяем конфигурацию Json
                    .build().create(MyServerService::class.java).also { INSTANCE = it }
            }
        }
    }
}