package com.aiosman.riderpro.data.api

import com.aiosman.riderpro.data.AccountFavourite
import com.aiosman.riderpro.data.AccountFollow
import com.aiosman.riderpro.data.AccountLike
import com.aiosman.riderpro.data.AccountNotice
import com.aiosman.riderpro.data.AccountProfile
import com.aiosman.riderpro.data.Comment
import com.aiosman.riderpro.data.DataContainer
import com.aiosman.riderpro.data.ListContainer
import com.aiosman.riderpro.data.Moment
import com.google.gson.annotations.SerializedName
import okhttp3.MultipartBody
import okhttp3.RequestBody
import retrofit2.Response
import retrofit2.http.Body
import retrofit2.http.DELETE
import retrofit2.http.GET
import retrofit2.http.Multipart
import retrofit2.http.PATCH
import retrofit2.http.POST
import retrofit2.http.Part
import retrofit2.http.Path
import retrofit2.http.Query

data class RegisterRequestBody(
    @SerializedName("username")
    val username: String,
    @SerializedName("password")
    val password: String,

    )

data class LoginUserRequestBody(
    @SerializedName("username")
    val username: String? = null,
    @SerializedName("password")
    val password: String? = null,
    @SerializedName("googleId")
    val googleId: String? = null,
)

data class GoogleRegisterRequestBody(
    @SerializedName("idToken")
    val idToken: String
)

data class AuthResult(
    @SerializedName("code")
    val code: Int,
    @SerializedName("expire")
    val expire: String,
    @SerializedName("token")
    val token: String
)

data class ValidateTokenResult(
    @SerializedName("id")
    val id: Int,
)

data class CommentRequestBody(
    @SerializedName("content")
    val content: String,
    @SerializedName("parentCommentId")
    val parentCommentId: Int? = null,
    @SerializedName("replyUserId")
    val replyUserId: Int? = null,
    @SerializedName("replyCommentId")
    val replyCommentId: Int? = null,
)

data class ChangePasswordRequestBody(
    @SerializedName("currentPassword")
    val oldPassword: String = "",
    @SerializedName("newPassword")
    val newPassword: String = ""
)

data class UpdateNoticeRequestBody(
    @SerializedName("lastLookLikeTime")
    val lastLookLikeTime: String? = null,
    @SerializedName("lastLookFollowTime")
    val lastLookFollowTime: String? = null,
    @SerializedName("lastLookFavoriteTime")
    val lastLookFavouriteTime: String? = null
)

data class RegisterMessageChannelRequestBody(
    @SerializedName("client")
    val client: String,
    @SerializedName("identifier")
    val identifier: String,
)

data class ResetPasswordRequestBody(
    @SerializedName("username")
    val username: String,
)

interface RiderProAPI {
    @POST("register")
    suspend fun register(@Body body: RegisterRequestBody): Response<Unit>

    @POST("login")
    suspend fun login(@Body body: LoginUserRequestBody): Response<AuthResult>

    @GET("auth/token")
    suspend fun checkToken(): Response<ValidateTokenResult>

    @GET("auth/refresh_token")
    suspend fun refreshToken(
        @Query("token") token: String
    ): Response<AuthResult>

    @GET("posts")
    suspend fun getPosts(
        @Query("page") page: Int = 1,
        @Query("pageSize") pageSize: Int = 20,
        @Query("timelineId") timelineId: Int? = null,
        @Query("authorId") authorId: Int? = null,
        @Query("contentSearch") contentSearch: String? = null,
        @Query("postUser") postUser: Int? = null,
        @Query("trend") trend: String? = null,
        @Query("favouriteUserId") favouriteUserId: Int? = null,
    ): Response<ListContainer<Moment>>

    @Multipart
    @POST("posts")
    suspend fun createPost(
        @Part image: List<MultipartBody.Part>,
        @Part("textContent") textContent: RequestBody,
    ): Response<DataContainer<Moment>>

    @GET("post/{id}")
    suspend fun getPost(
        @Path("id") id: Int
    ): Response<DataContainer<Moment>>

    @POST("post/{id}/like")
    suspend fun likePost(
        @Path("id") id: Int
    ): Response<Unit>

    @POST("post/{id}/dislike")
    suspend fun dislikePost(
        @Path("id") id: Int
    ): Response<Unit>

    @POST("post/{id}/favorite")
    suspend fun favoritePost(
        @Path("id") id: Int
    ): Response<Unit>

    @POST("post/{id}/unfavorite")
    suspend fun unfavoritePost(
        @Path("id") id: Int
    ): Response<Unit>

    @POST("post/{id}/comment")
    suspend fun createComment(
        @Path("id") id: Int,
        @Body body: CommentRequestBody
    ): Response<DataContainer<Comment>>

    @POST("comment/{id}/like")
    suspend fun likeComment(
        @Path("id") id: Int
    ): Response<Unit>

    @POST("comment/{id}/dislike")
    suspend fun dislikeComment(
        @Path("id") id: Int
    ): Response<Unit>

    @POST("comment/{id}/read")
    suspend fun updateReadStatus(
        @Path("id") id: Int
    ): Response<Unit>


    @GET("comments")
    suspend fun getComments(
        @Query("page") page: Int = 1,
        @Query("postId") postId: Int? = null,
        @Query("pageSize") pageSize: Int = 20,
        @Query("postUser") postUser: Int? = null,
        @Query("selfNotice") selfNotice: Int? = 0,
        @Query("order") order: String? = null,
        @Query("parentCommentId") parentCommentId: Int? = null,
    ): Response<ListContainer<Comment>>

    @GET("account/my")
    suspend fun getMyAccount(): Response<DataContainer<AccountProfile>>

    @Multipart
    @PATCH("account/my/profile")
    suspend fun updateProfile(
        @Part avatar: MultipartBody.Part?,
        @Part banner: MultipartBody.Part?,
        @Part("nickname") nickname: RequestBody?,
        @Part("bio") bio: RequestBody?,
    ): Response<Unit>

    @POST("account/my/password")
    suspend fun changePassword(
        @Body body: ChangePasswordRequestBody
    ): Response<Unit>

    @GET("account/my/notice/like")
    suspend fun getMyLikeNotices(
        @Query("page") page: Int = 1,
        @Query("pageSize") pageSize: Int = 20,
    ): Response<ListContainer<AccountLike>>

    @GET("account/my/notice/follow")
    suspend fun getMyFollowNotices(
        @Query("page") page: Int = 1,
        @Query("pageSize") pageSize: Int = 20,
    ): Response<ListContainer<AccountFollow>>

    @GET("account/my/notice/favourite")
    suspend fun getMyFavouriteNotices(
        @Query("page") page: Int = 1,
        @Query("pageSize") pageSize: Int = 20,
    ): Response<ListContainer<AccountFavourite>>

    @GET("account/my/notice")
    suspend fun getMyNoticeInfo(): Response<DataContainer<AccountNotice>>

    @POST("account/my/notice")
    suspend fun updateNoticeInfo(
        @Body body: UpdateNoticeRequestBody
    ): Response<Unit>

    @POST("account/my/messaging")
    suspend fun registerMessageChannel(
        @Body body: RegisterMessageChannelRequestBody
    ): Response<Unit>


    @GET("profile/{id}")
    suspend fun getAccountProfileById(
        @Path("id") id: Int
    ): Response<DataContainer<AccountProfile>>

    @POST("user/{id}/follow")
    suspend fun followUser(
        @Path("id") id: Int
    ): Response<Unit>

    @POST("user/{id}/unfollow")
    suspend fun unfollowUser(
        @Path("id") id: Int
    ): Response<Unit>

    @GET("users")
    suspend fun getUsers(
        @Query("page") page: Int = 1,
        @Query("pageSize") pageSize: Int = 20,
        @Query("nickname") search: String? = null,
        @Query("followerId") followerId: Int? = null,
        @Query("followingId") followingId: Int? = null,
    ): Response<ListContainer<AccountProfile>>

    @POST("register/google")
    suspend fun registerWithGoogle(@Body body: GoogleRegisterRequestBody): Response<AuthResult>

    @DELETE("post/{id}")
    suspend fun deletePost(
        @Path("id") id: Int
    ): Response<Unit>

    @DELETE("comment/{id}")
    suspend fun deleteComment(
        @Path("id") id: Int
    ): Response<Unit>

    @POST("account/my/password/reset")
    suspend fun resetPassword(
        @Body body: ResetPasswordRequestBody
    ): Response<Unit>
}