package com.lanyun.wanglaotou.viewModel

import android.util.Log
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.ui.text.input.TextFieldValue
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import com.lanyun.common.base.BaseViewModel
import com.lanyun.common.baseDate.CommonConstant
import com.lanyun.common.baseDate.updateMainEvent
import com.lanyun.common.ext.toJsonStr
import com.lanyun.common.model.MainEvent
import com.lanyun.common.widget.SpUtilsMMKV
import com.lanyun.net.ext.*
import com.lanyun.net.widget.DataStoreUtils
import com.lanyun.wanglaotou.model.LoginModel
import com.lanyun.wanglaotou.public.PageState
import com.lanyun.wanglaotou.repo.LoginRepo
import com.lanyun.wanglaotou.util.MmkvManager
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.receiveAsFlow

class LoginAndRegViewModel : BaseViewModel() {

    var viewStates by mutableStateOf(LoginAndRegState())
        private set
    private val _viewEvents = Channel<LoginViewEvent>(Channel.BUFFERED)
    val viewEvents = _viewEvents.receiveAsFlow()


    fun dispatch(action: LoginViewAction) {
        when (action) {
            is LoginViewAction.Login -> getUserLoginData()
            is LoginViewAction.Reg -> reg()
            is LoginViewAction.ClearAccount -> clearAccount()
            is LoginViewAction.ClearPassword -> clearPassword()
            is LoginViewAction.UpdateAccount -> updateAccount(action.userName)
            is LoginViewAction.UpdatePassword -> updatePassword(action.passWord)
            is LoginViewAction.UpdateButtonVisible -> updateButtonVisible(action.loginButtonVisible)
            is LoginViewAction.UpdatePageState ->  updateLoading(action.pageState)
            is LoginViewAction.UpdateIsReg ->  updateIsReg(action.isReg)
        }
    }



    private fun reg() = serverAwait {
        if (viewStates.userName.isEmpty() || viewStates.passWord.isEmpty()) {
            updateLoading(PageState.Error(  "账号或者密码为空"))
            return@serverAwait
        }
        updateLoading(PageState.Loading)
        LoginRepo.getUserReg(viewStates.userName, viewStates.passWord).serverData().onSuccess {
            onBizError { code, error_message ->
                updateLoading(PageState.Error(error_message ?: ""))
                //  mError.postValue("登录失败，$err_message")
                android.util.Log.e("xxx", "登录 接口异常 $code $error_message")
            }
            onBizOK<LoginModel>{code, data,_ ->
                data?.let {
                    //保存登录数据
                    SpUtilsMMKV.put(CommonConstant.IS_LOGIN, true)

                    DataStoreUtils.putSyncData("token",it.token)
                    DataStoreUtils.putSyncData("auth_data",it.auth_data)
                    //保存用户信息
                    SpUtilsMMKV.put(CommonConstant.USER_FINO, it.toJsonStr())
                    //通知刷新个人信息
                    updateMainEvent(MainEvent.Login)

                    it.auth_data?.let { auth_data ->
                        updateLoading(PageState.Success(auth_data.isEmpty()))
                    }
                }
            }

        }.onFailure {

            updateLoading(PageState.Error(it.errorMsg ?: ""))
            // mToast.postValue("登录失败 ${it.errorMsg}")
            Log.e("xxx", "登录 接口异常 ${it.errorMsg}")
        }
    }

    /**
     * 登录
     */
    private fun getUserLoginData() = serverAwait {

        if (viewStates.userName.isEmpty() || viewStates.passWord.isEmpty()) {
            updateLoading(PageState.Error(  "账号或者密码为空"))
            return@serverAwait
        }


        updateLoading(PageState.Loading)
        LoginRepo.getUserLogin(viewStates.userName, viewStates.passWord).serverData().onSuccess {

            onBizError { code, err_message ->
                updateLoading(PageState.Error(err_message ?: ""))
              //  mError.postValue("登录失败，$err_message")
                Log.e("xxx", "登录 接口异常 $code $err_message")

            }
            onBizOK<LoginModel> { code, data, _ ->

                data?.let {
                    //保存登录数据
                    SpUtilsMMKV.put(CommonConstant.IS_LOGIN, true)
                    //保存信息
                    DataStoreUtils.putSyncData("token",it.token)
                    DataStoreUtils.putSyncData("auth_data",it.auth_data)
                    //保存用户信息
                    SpUtilsMMKV.put(CommonConstant.USER_FINO, it.toJsonStr())
                    //通知刷新个人信息
                    updateMainEvent(MainEvent.Login)

                    it.auth_data?.let { auth_data ->
                        updateLoading(PageState.Success(auth_data.isEmpty()))
                    }


                }

            }
        }.onFailure {

            updateLoading(PageState.Error(it.errorMsg ?: ""))
           // mToast.postValue("登录失败 ${it.errorMsg}")
            Log.e("xxx", "登录 接口异常 ${it.errorMsg}")

        }
    }


    private fun clearAccount() {
        viewStates = viewStates.copy(userName = "")
    }

    private fun clearPassword() {
        viewStates = viewStates.copy(passWord = "")
    }

    private fun updateAccount(account: String) {
        viewStates = viewStates.copy(userName = account)
    }

    private fun updatePassword(password: String) {
        viewStates = viewStates.copy(passWord = password)
    }

    private fun updateButtonVisible(loginButtonVisible: Boolean){
        viewStates = viewStates.copy(loginButtonVisible=loginButtonVisible)
    }

    private fun updateIsReg(UpdateIsReg: Boolean){
        viewStates = viewStates.copy(isReg=UpdateIsReg)
    }

    private fun updateLoading(loading: PageState){
        viewStates = viewStates.copy(pageState = loading)
    }

    fun getRegUrl() : String{
        val urlModel = MmkvManager.decodeUrlInfo()
        var url = ""
        urlModel?.let {
            url = it.register
        }
        return url
    }
}


data class LoginAndRegState(
    val userName: String = "",
    val passWord: String = "",
    val loginButtonVisible: Boolean = false,
    val pageState: PageState = PageState.NoLoading,
    val isReg: Boolean = false

    )

/**
 * 一次性事件
 */
sealed class LoginViewEvent {
    object PopBack : LoginViewEvent()
    data class ErrorMessage(val message: String) : LoginViewEvent()
}



sealed class LoginViewAction {
    object Login : LoginViewAction()
    object Reg : LoginViewAction()
    object ClearAccount : LoginViewAction()
    object ClearPassword : LoginViewAction()
    data class UpdateAccount(val userName: String) : LoginViewAction()
    data class UpdatePassword(val passWord: String) : LoginViewAction()
    data class UpdateButtonVisible(val loginButtonVisible: Boolean) : LoginViewAction()
    data class UpdateIsReg(val isReg: Boolean) : LoginViewAction()
    data class UpdatePageState(val pageState: PageState) : LoginViewAction()
}