package com.adealink.weparty.account.login.viewmodel

import android.app.Activity
import android.content.Intent
import android.os.SystemClock
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import com.adealink.frame.base.IError
import com.adealink.frame.base.Rlt
import com.adealink.frame.coroutine.dispatcher.Dispatcher
import com.adealink.frame.log.Log
import com.adealink.frame.mvvm.livedata.ExtMutableLiveData
import com.adealink.frame.mvvm.viewmodel.BaseViewModel
import com.adealink.frame.util.isNetworkAvailable
import com.adealink.weparty.account.constant.AccountLoginAuthCancelError
import com.adealink.weparty.account.constant.AccountLoginAuthError
import com.adealink.weparty.account.constant.GOOGLE_CODE_COUNT_DOWN_TIME
import com.adealink.weparty.account.constant.TAG_ACCOUNT_LOGIN
import com.adealink.weparty.account.login.auth.AuthManager
import com.adealink.weparty.account.login.auth.IAuthCallback
import com.adealink.weparty.account.login.data.ThirdType
import com.adealink.weparty.account.login.manager.loginManager
import com.adealink.weparty.module.account.ILoginListener
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

class LoginViewModel : BaseViewModel(), ILoginViewModel, ILoginListener {

    override val loginLD: LiveData<LoginResultLD> = MutableLiveData()
    val countdownTime = ExtMutableLiveData<Int>()
    private var countdownJob: Job? = null

    init {
        loginManager.addListener(this)
    }

    private val authManager by lazy {
        AuthManager(authCallback)
    }
    private var authStartTime = 0L
    private val authCallback = object : IAuthCallback {
        override fun onSuccess(authType: ThirdType, token: String, codeVerifier: String?) {
            cancelCountdown()

            Log.d(TAG_ACCOUNT_LOGIN, "authCallback.onSuccess, $authType, $token, $codeVerifier")
            authLogin(authType, token, codeVerifier = codeVerifier)
        }

        override fun onFailed(authType: ThirdType, errorMsg: String, errorCode: Int?) {
            val result = Rlt.Failed(AccountLoginAuthError(errorCode))
            loginLD.send(LoginResultLD(authType, result), false)
            cancelCountdown()
        }

        override fun onCancel(authType: ThirdType) {
            loginLD.send(
                LoginResultLD(authType, Rlt.Failed(AccountLoginAuthCancelError())), false
            )
            cancelCountdown()
        }
    }

    fun startAuthLogin(authType: ThirdType, activity: Activity) {
        authStartTime = SystemClock.elapsedRealtime()
        if (authType == ThirdType.GOOGLE) {
            googleLoginCountDown()
        }
        authManager.startAuth(authType, activity)
    }

    fun handleOnActivityResult(requestCode: Int, resultCode: Int, intent: Intent?) {
        authManager.handleOnActivityResult(requestCode, resultCode, intent)
    }

    fun onNewIntent(intent: Intent?) {
        authManager.onNewIntent(intent)
    }

    fun authLogin(
        authType: ThirdType,
        token: String,
        tid: Long? = null,
        codeVerifier: String? = null
    ) {
        viewModelScope.launch { //避免退出页面取消login
            withContext(Dispatcher.UI) {
                when (authType) {
                    ThirdType.GOOGLE -> {
                        when (val result = loginManager.googleLogin(token)
                            .apply { Log.logRltD(TAG_ACCOUNT_LOGIN, "authLogin", this) }) {
                            is Rlt.Success -> {
                                val res = result.data.data
                                if (res == null) {
                                    loginLD.send(
                                        LoginResultLD(authType, Rlt.Failed(IError())),
                                        false
                                    )
                                } else {
                                    loginLD.send(LoginResultLD(authType, Rlt.Success(res)), false)
                                }
                            }

                            is Rlt.Failed -> {
                                loginLD.send(
                                    LoginResultLD(
                                        authType,
                                        result
                                    ), false
                                )
                            }
                        }
                    }

                    ThirdType.PHONE -> {}
                    ThirdType.EMAIL -> {}
                }
            }
        }
    }

    /**
     * 测试账号登录
     */
    fun testAuthLogin() {
        viewModelScope.launch {
            when (val result = loginManager.testLogin()
                .apply { Log.logRltD(TAG_ACCOUNT_LOGIN, "authLogin", this) }) {
                is Rlt.Success -> {
                    val res = result.data.data
                    if (res == null) {
                        loginLD.send(LoginResultLD(ThirdType.GOOGLE, Rlt.Failed(IError())), false)
                    } else {
                        loginLD.send(LoginResultLD(ThirdType.GOOGLE, Rlt.Success(res)), false)
                    }
                }

                is Rlt.Failed -> {
                    loginLD.send(
                        LoginResultLD(
                            ThirdType.GOOGLE,
                            result
                        ), false
                    )
                }
            }
        }
    }

    fun phoneLogin(region: String, number: String, verify: String) {
        viewModelScope.launch {
            when (val result = loginManager.phoneLogin(region, number, verify)
                .apply { Log.logRltD(TAG_ACCOUNT_LOGIN, "phoneLogin", this) }) {
                is Rlt.Success -> {
                    val res = result.data.data
                    if (res == null) {
                        loginLD.send(LoginResultLD(ThirdType.GOOGLE, Rlt.Failed(IError())), false)
                    } else {
                        loginLD.send(LoginResultLD(ThirdType.GOOGLE, Rlt.Success(res)), false)
                    }
                }

                is Rlt.Failed -> {
                    loginLD.send(
                        LoginResultLD(
                            ThirdType.GOOGLE,
                            result
                        ), false
                    )
                }
            }
        }
    }

    override fun onCleared() {
        super.onCleared()
        cancelCountdown()
        loginManager.removeListener(this)
    }

    private fun cancelCountdown() {
        countdownJob?.cancel()
    }

    private fun googleLoginCountDown() {
        if (!isNetworkAvailable()) {
            return
        }
        countdownJob?.cancel() // Cancel any existing countdown
        countdownJob = CoroutineScope(Dispatchers.Default).launch {
            for (time in GOOGLE_CODE_COUNT_DOWN_TIME downTo 0) {
                if (time == 0) {
                    countdownTime.send(time)
                }
                delay(1000L) // 1 second delay
            }
        }
    }

}