package com.kaixed.kchat.repository

import androidx.lifecycle.MutableLiveData
import com.google.gson.Gson
import com.kaixed.kchat.model.friend.AcceptContactRequest
import com.kaixed.kchat.model.friend.ContactRequestResponse
import com.kaixed.kchat.model.friend.FriendItem
import com.kaixed.kchat.model.response.ApplyFriend
import com.kaixed.kchat.model.response.friend.FriendList
import com.kaixed.kchat.model.response.friend.SearchFriends
import com.kaixed.kchat.network.NetworkInterface.ACCEPT_CONTACT_REQUEST
import com.kaixed.kchat.network.NetworkInterface.ADD_FRIEND
import com.kaixed.kchat.network.NetworkInterface.FRIEND_LIST
import com.kaixed.kchat.network.NetworkInterface.FRIEND_REQUEST_LIST
import com.kaixed.kchat.network.NetworkInterface.SERVER_URL
import com.kaixed.kchat.network.NetworkInterface.USER_LIST
import com.kaixed.kchat.network.NetworkRequest
import com.kaixed.kchat.utils.ConstantsUtil.getUsername
import kotlinx.serialization.json.Json
import okhttp3.Call
import okhttp3.Callback
import okhttp3.FormBody
import okhttp3.Response
import java.io.IOException

/**
 * @Author: kaixed
 * @Date: 2024/10/20 17:32
 */
class ContactRepo {

    fun getContactRequestList(
        username: String,
    ): MutableLiveData<ContactRequestResponse?> {
        val applyFriendMutableLiveData = MutableLiveData<ContactRequestResponse?>()

        val requestBody = FormBody.Builder()
            .add("userId", username)
            .build()

        NetworkRequest().postAsync(
            "$SERVER_URL$FRIEND_REQUEST_LIST",
            requestBody,
            object : Callback {
                override fun onFailure(call: Call, e: IOException) {
                    applyFriendMutableLiveData.postValue(null)
                }

                override fun onResponse(call: Call, response: Response) {
                    response.body?.string()?.let { responseBody ->
                        val contactResponse =
                            Json.decodeFromString<ContactRequestResponse>(responseBody)
                        applyFriendMutableLiveData.postValue(contactResponse)
                    }
                }
            }
        )
        return applyFriendMutableLiveData
    }

    fun acceptContactRequest(
        username: String,
        contactId: String,
    ): MutableLiveData<AcceptContactRequest?> {
        val acceptFriendMutableLiveData = MutableLiveData<AcceptContactRequest?>()
        val requestBody = FormBody.Builder()
            .add("requestId", contactId)
            .add("receiverId", username)
            .build()

        NetworkRequest().postAsync(
            SERVER_URL + ACCEPT_CONTACT_REQUEST,
            requestBody,
            object : Callback {
                override fun onFailure(call: Call, e: IOException) {
                    acceptFriendMutableLiveData.postValue(null)
                }

                override fun onResponse(call: Call, response: Response) {
                    response.body?.string()?.let { responseBody ->
                        val contactResponse =
                            Json.decodeFromString<AcceptContactRequest>(responseBody)
                        acceptFriendMutableLiveData.postValue(contactResponse)
                    } ?: acceptFriendMutableLiveData.postValue(null)
                }
            }
        )
        return acceptFriendMutableLiveData
    }

    fun addContact(contactId: String, message: String): MutableLiveData<ApplyFriend?> {
        val mutableLiveData = MutableLiveData<ApplyFriend?>()
        val requestBody = FormBody.Builder()
            .add("senderId", getUsername())
            .add("receiverId", contactId)
            .add("message", message)
            .build()

        NetworkRequest().postAsync(
            "$SERVER_URL$ADD_FRIEND",
            requestBody,
            object : Callback {
                override fun onResponse(call: Call, response: Response) {
                    response.body?.string()?.let { responseBody ->
                        val applyFriend =
                            Json.decodeFromString<ApplyFriend>(responseBody)
                        mutableLiveData.postValue(applyFriend)
                    } ?: mutableLiveData.postValue(null)
                }

                override fun onFailure(call: Call, e: IOException) {
                    mutableLiveData.postValue(null)
                }
            }
        )
        return mutableLiveData
    }

    fun searchContact(username: String): MutableLiveData<SearchFriends?> {
        val listMutableLiveData = MutableLiveData<SearchFriends?>()

        NetworkRequest().getAsync(
            "$SERVER_URL$USER_LIST$username",
            object : Callback {
                override fun onFailure(call: Call, e: IOException) {
                    listMutableLiveData.postValue(null)
                }

                @Throws(IOException::class)
                override fun onResponse(call: Call, response: Response) {
                    response.body?.string()?.let { responseBody ->
                        val searchFriends = Json.decodeFromString<SearchFriends>(responseBody)
                        listMutableLiveData.postValue(searchFriends)
                    } ?: listMutableLiveData.postValue(null)
                }
            }
        )
        return listMutableLiveData
    }

    fun getContactList(username: String): MutableLiveData<List<FriendItem>?> {
        val applyFriendMutableLiveData = MutableLiveData<List<FriendItem>?>()

        val requestBody = FormBody.Builder()
            .add("userId", username)
            .build()

        NetworkRequest().postAsync(
            "$SERVER_URL$FRIEND_LIST",
            requestBody,
            object : Callback {
                override fun onFailure(call: Call, e: IOException) {
                    applyFriendMutableLiveData.postValue(null)
                }

                override fun onResponse(call: Call, response: Response) {
                    response.body?.string()?.let { responseBody ->
                        val friendList = Gson().fromJson(responseBody, FriendList::class.java)
                        applyFriendMutableLiveData.postValue(friendList.data)
                    } ?: applyFriendMutableLiveData.postValue(null)
                }
            }
        )

        return applyFriendMutableLiveData
    }
}
