package com.adealink.weparty.profile.viewmodel

import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import com.adealink.frame.aab.util.getCompatString
import com.adealink.frame.base.CommonDataNullError
import com.adealink.frame.base.CommonParamError
import com.adealink.frame.base.Rlt
import com.adealink.frame.log.Log
import com.adealink.frame.mvvm.livedata.OnceMutableLiveData
import com.adealink.frame.mvvm.viewmodel.BaseViewModel
import com.adealink.frame.oss.data.UploadFile
import com.adealink.weparty.App
import com.adealink.weparty.commonui.ext.isGIFImage
import com.adealink.weparty.imageselect.util.compressImage
import com.adealink.weparty.module.profile.data.UserInfo
import com.adealink.weparty.module.profile.listener.IProfileListener
import com.adealink.weparty.module.profile.viewmodel.IProfileViewModel
import com.adealink.weparty.profile.R
import com.adealink.weparty.profile.data.AVATAR_IMAGE_MAX_HEIGHT
import com.adealink.weparty.profile.data.AVATAR_IMAGE_MAX_SIZE_KB
import com.adealink.weparty.profile.data.AVATAR_IMAGE_MAX_WIDTH
import com.adealink.weparty.profile.data.AVATAR_IMAGE_MIN_QUALITY
import com.adealink.weparty.profile.data.TAG_PROFILE
import com.adealink.weparty.profile.data.UpdateMyUserInfoReq
import com.adealink.weparty.profile.datasource.remote.ProfileHttpService
import com.adealink.weparty.profile.manager.profileManager
import kotlinx.coroutines.launch

class ProfileViewModel : BaseViewModel(), IProfileViewModel, IProfileListener {

    override val userInfoLD: LiveData<UserInfo?> = MutableLiveData<UserInfo?>()

    private val profileHttpService by lazy {
        App.instance.networkService.getHttpService(ProfileHttpService::class.java)
    }

    override fun pullUserInfoBy(uid: String, cache: Boolean) {
        viewModelScope.launch {
            val rlt = profileManager.getUserInfoByUid(uid, cache)
            when (rlt) {
                is Rlt.Failed -> {
                    userInfoLD.send(null)
                }

                is Rlt.Success -> {
                    userInfoLD.send(rlt.data)
                }
            }
        }
    }

    override fun pullUserInoBy(
        uids: List<String>,
        cache: Boolean
    ): LiveData<Rlt<Map<String, UserInfo>>> {
        val liveData = OnceMutableLiveData<Rlt<Map<String, UserInfo>>>()
        viewModelScope.launch {
            liveData.send(profileManager.getUsersInfoByUid(uids.toSet(), cache))
        }
        return liveData
    }

    override fun getUserInfoBy(uid: String): UserInfo? {
        return profileManager.getCacheUserInfo(uid)
    }

    override fun updateProfile(
        newAvatarPath: String?,
        newNickName: String?,
        newGender: Int?,
        newBirthday: String?,
    ): LiveData<Rlt<Any>> {
        val liveData = OnceMutableLiveData<Rlt<Any>>()
        viewModelScope.launch {
            val myUserInfo = profileManager.getMyUserInfo()
            if (myUserInfo == null) {
                liveData.send(Rlt.Failed(CommonDataNullError()))
                return@launch
            }

            val editUserInfo = myUserInfo.copy()

            newNickName?.trim()?.let { newNickName ->
                if (newNickName.isEmpty()) {
                    liveData.send(Rlt.Failed(CommonParamError(getCompatString(R.string.toast_profile_edit_name_empty))))
                    return@launch
                }
                editUserInfo.nickName = newNickName
            }

            newGender?.let { newGender ->
                editUserInfo.gender = newGender
            }

            newBirthday?.trim()?.let { newAge ->
                if (newAge.isEmpty()) {
                    liveData.send(Rlt.Failed(CommonParamError(getCompatString(R.string.toast_profile_edit_age_empty))))
                    return@launch
                }
                val age = newAge.toIntOrNull()
                if (age == null || age < 0) {
                    liveData.send(Rlt.Failed(CommonParamError(getCompatString(R.string.toast_profile_edit_age_invalid))))
                    return@launch
                }
                editUserInfo.age = age
            }

            //图片上传放到最后
            //图片上传放到最后
            //图片上传放到最后
            newAvatarPath?.trim()?.takeIf { it.isNotEmpty() }?.let { avatarPath ->
                val rlt = uploadAvatar(avatarPath)
                when (rlt) {
                    is Rlt.Failed -> {
                        liveData.send(rlt)
                        return@launch
                    }

                    is Rlt.Success -> {
                        editUserInfo.avatar = rlt.data
                    }
                }
            }

            val rlt = profileHttpService.updateUserInfo(
                UpdateMyUserInfoReq(
                    avatar = editUserInfo.avatar,
                    nickname = editUserInfo.nickName,
                    gender = editUserInfo.gender,
//                    birthday = editUserInfo.age
                )
            )
            liveData.send(rlt)
        }
        return liveData
    }

    private suspend fun uploadAvatar(avatarPath: String): Rlt<String> {
        val compressFilePath = if (isGIFImage(avatarPath)) {
            avatarPath
        } else {
            val compressRlt =
                compressImage(
                    avatarPath,
                    AVATAR_IMAGE_MAX_WIDTH,
                    AVATAR_IMAGE_MAX_HEIGHT,
                    AVATAR_IMAGE_MAX_SIZE_KB,
                    AVATAR_IMAGE_MIN_QUALITY
                )

            if (compressRlt is Rlt.Failed) {
                Log.logRltD(
                    TAG_PROFILE,
                    "uploadAvatar, compress failed, filePath:${avatarPath}",
                    compressRlt
                )
                return compressRlt
            }
            val compressResult = (compressRlt as Rlt.Success).data
            compressResult.path
        }
        return App.instance.ossService.suspendUploadFile(
            UploadFile.LocalFile(
                compressFilePath,
                UploadFile.FileType.IMAGE,
                compress = false,
                deleteAfterUploaded = avatarPath != compressFilePath
            )
        )
    }
}