package pl.firmatpp.kierowca.data.api

import okhttp3.MultipartBody
import okhttp3.RequestBody
import pl.firmatpp.kierowca.data.model.BootstrapResponse
import pl.firmatpp.kierowca.data.model.BroadcastAuthBody
import pl.firmatpp.kierowca.data.model.BroadcastAuthResponse
import pl.firmatpp.kierowca.data.model.CancelLeaveRequestBody
import pl.firmatpp.kierowca.data.model.CompleteRouteResponse
import pl.firmatpp.kierowca.data.model.CreateLeaveRequestBody
import pl.firmatpp.kierowca.data.model.DispatchSheetUploadResponse
import pl.firmatpp.kierowca.data.model.FinishRouteBody
import pl.firmatpp.kierowca.data.model.LeaveCalendarResponse
import pl.firmatpp.kierowca.data.model.LeaveRequestListResponse
import pl.firmatpp.kierowca.data.model.LeaveRequestResponse
import pl.firmatpp.kierowca.data.model.LeaveRequestTypesResponse
import pl.firmatpp.kierowca.data.model.OtpResponse
import pl.firmatpp.kierowca.data.model.NotificationPreferencesBody
import pl.firmatpp.kierowca.data.model.NotificationPreferencesDto
import pl.firmatpp.kierowca.data.model.PhotoUploadResponse
import pl.firmatpp.kierowca.data.model.PushTokenBody
import pl.firmatpp.kierowca.data.model.RealtimeStatusBody
import pl.firmatpp.kierowca.data.model.RequestOtpBody
import pl.firmatpp.kierowca.data.model.RouteActionResponse
import pl.firmatpp.kierowca.data.model.RoutePointBatchBody
import pl.firmatpp.kierowca.data.model.RoutePointsResponse
import pl.firmatpp.kierowca.data.model.RouteResponse
import pl.firmatpp.kierowca.data.model.StartRouteBody
import pl.firmatpp.kierowca.data.model.SyncStateResponse
import pl.firmatpp.kierowca.data.model.VerifyOtpBody
import pl.firmatpp.kierowca.data.model.VerifyOtpResponse
import retrofit2.http.Body
import retrofit2.http.DELETE
import retrofit2.http.GET
import retrofit2.http.Header
import retrofit2.http.Multipart
import retrofit2.http.POST
import retrofit2.http.PUT
import retrofit2.http.Part
import retrofit2.http.Path
import retrofit2.http.Query

interface MobileDriverApi {
    @POST("mobile/driver/auth/request-otp")
    suspend fun requestOtp(@Body body: RequestOtpBody): OtpResponse

    @POST("mobile/driver/auth/verify-otp")
    suspend fun verifyOtp(@Body body: VerifyOtpBody): VerifyOtpResponse

    @POST("mobile/driver/auth/logout")
    suspend fun logout(@Header("Authorization") authorization: String): Map<String, Boolean>

    @GET("mobile/driver/notification-preferences")
    suspend fun notificationPreferences(
        @Header("Authorization") authorization: String,
    ): NotificationPreferencesDto

    @PUT("mobile/driver/notification-preferences")
    suspend fun updateNotificationPreferences(
        @Header("Authorization") authorization: String,
        @Body body: NotificationPreferencesBody,
    ): NotificationPreferencesDto

    @GET("mobile/driver/bootstrap")
    suspend fun bootstrap(
        @Header("Authorization") authorization: String,
        @Query("date") date: String?,
    ): BootstrapResponse

    @GET("mobile/driver/leave-request-types")
    suspend fun leaveRequestTypes(
        @Header("Authorization") authorization: String,
    ): LeaveRequestTypesResponse

    @GET("mobile/driver/leave-requests")
    suspend fun leaveRequests(
        @Header("Authorization") authorization: String,
    ): LeaveRequestListResponse

    @GET("mobile/driver/leave-requests/calendar")
    suspend fun leaveCalendar(
        @Header("Authorization") authorization: String,
        @Query("from") from: String,
        @Query("to") to: String,
    ): LeaveCalendarResponse

    @POST("mobile/driver/leave-requests")
    suspend fun createLeaveRequest(
        @Header("Authorization") authorization: String,
        @Body body: CreateLeaveRequestBody,
    ): LeaveRequestResponse

    @GET("mobile/driver/leave-requests/{id}")
    suspend fun leaveRequest(
        @Header("Authorization") authorization: String,
        @Path("id") id: String,
    ): LeaveRequestResponse

    @POST("mobile/driver/leave-requests/{id}/cancel")
    suspend fun cancelLeaveRequest(
        @Header("Authorization") authorization: String,
        @Path("id") id: String,
        @Body body: CancelLeaveRequestBody,
    ): LeaveRequestResponse

    @GET("mobile/driver/routes/{routeId}")
    suspend fun route(
        @Header("Authorization") authorization: String,
        @Path("routeId") routeId: String,
    ): RouteResponse

    @POST("mobile/driver/routes/{routeId}/complete")
    suspend fun completeRoute(
        @Header("Authorization") authorization: String,
        @Path("routeId") routeId: String,
    ): CompleteRouteResponse

    @POST("mobile/driver/routes/{routeId}/start")
    suspend fun startRoute(
        @Header("Authorization") authorization: String,
        @Path("routeId") routeId: String,
        @Body body: StartRouteBody,
    ): RouteActionResponse

    @POST("mobile/driver/routes/{routeId}/finish")
    suspend fun finishRoute(
        @Header("Authorization") authorization: String,
        @Path("routeId") routeId: String,
        @Body body: FinishRouteBody,
    ): RouteActionResponse

    @POST("mobile/driver/routes/{routeId}/points")
    suspend fun storeRoutePoints(
        @Header("Authorization") authorization: String,
        @Path("routeId") routeId: String,
        @Body body: RoutePointBatchBody,
    ): RoutePointsResponse

    @GET("mobile/driver/sync-state")
    suspend fun syncState(
        @Header("Authorization") authorization: String,
        @Query("date") date: String?,
        @Query("routeId") routeId: String?,
    ): SyncStateResponse

    @POST("mobile/driver/broadcasting/auth")
    suspend fun broadcastAuth(
        @Header("Authorization") authorization: String,
        @Body body: BroadcastAuthBody,
    ): BroadcastAuthResponse

    @PUT("mobile/driver/push-token")
    suspend fun storePushToken(
        @Header("Authorization") authorization: String,
        @Body body: PushTokenBody,
    ): Map<String, Boolean>

    @PUT("mobile/driver/realtime-status")
    suspend fun storeRealtimeStatus(
        @Header("Authorization") authorization: String,
        @Body body: RealtimeStatusBody,
    ): Map<String, Boolean>

    @DELETE("mobile/driver/push-token")
    suspend fun deletePushToken(
        @Header("Authorization") authorization: String,
    ): Map<String, Boolean>

    @Multipart
    @POST("mobile/driver/routes/{routeId}/photos")
    suspend fun uploadPhoto(
        @Header("Authorization") authorization: String,
        @Header("Idempotency-Key") idempotencyKey: String,
        @Path("routeId") routeId: String,
        @Part photo: MultipartBody.Part,
        @Part("clientRequestId") clientRequestId: RequestBody,
        @Part("contentSha256") contentSha256: RequestBody,
        @Part("source") source: RequestBody,
        @Part("stage") stage: RequestBody?,
        @Part("takenAt") takenAt: RequestBody?,
        @Part("latitude") latitude: RequestBody?,
        @Part("longitude") longitude: RequestBody?,
        @Part("locationAccuracyMeters") locationAccuracyMeters: RequestBody?,
    ): PhotoUploadResponse

    @Multipart
    @POST("mobile/driver/dispatch-sheet-photos")
    suspend fun uploadDispatchSheetPhoto(
        @Header("Authorization") authorization: String,
        @Header("Idempotency-Key") idempotencyKey: String,
        @Part photo: MultipartBody.Part,
        @Part("clientRequestId") clientRequestId: RequestBody,
        @Part("contentSha256") contentSha256: RequestBody,
        @Part("source") source: RequestBody,
        @Part("takenAt") takenAt: RequestBody?,
        @Part("latitude") latitude: RequestBody?,
        @Part("longitude") longitude: RequestBody?,
        @Part("locationAccuracyMeters") locationAccuracyMeters: RequestBody?,
        @Part("replacePhotoId") replacePhotoId: RequestBody?,
    ): DispatchSheetUploadResponse

    @DELETE("mobile/driver/photos/{photoId}")
    suspend fun deletePhoto(
        @Header("Authorization") authorization: String,
        @Path("photoId") photoId: String,
    ): Map<String, Boolean>
}
