package com.adealink.weparty.im.manager.login

import android.app.Application
import com.adealink.frame.frame.BaseFrame
import com.adealink.frame.log.Log
import com.adealink.frame.util.AppUtil
import com.adealink.weparty.im.constant.TAG_IM_LOGIN
import com.adealink.weparty.im.manager.GenerateUserSig
import com.adealink.weparty.im.manager.LoginWrapper
import com.adealink.weparty.im.service.TIMAppService
import com.adealink.weparty.im.util.TUIUtils
import com.adealink.weparty.module.account.AccountModule
import com.adealink.weparty.module.account.ILoginListener
import com.adealink.weparty.module.im.IMConfig
import com.tencent.qcloud.tuicore.TUILogin
import com.tencent.qcloud.tuicore.interfaces.TUICallback
import com.tencent.qcloud.tuicore.interfaces.TUILoginConfig
import com.tencent.qcloud.tuicore.interfaces.TUILoginListener

val imLoginManager: ILoginManager by lazy { LoginManager() }

class LoginManager : BaseFrame<com.adealink.weparty.im.manager.login.ILoginListener>(),
    ILoginManager,
    ILoginListener {

    override fun init(application: Application) {
        AccountModule.registerListener(this)
        login()
    }

    override fun onLogin() {
        login()
    }

    override fun onLogout() {
        handleLogout()
    }

    private fun handleLogout() {
        Log.d(TAG_IM_LOGIN, "handleLogout")
        if (isLogin()) {
            logout()
        }
    }

    private fun reLogin() {
        login(true)
    }

    override fun login(reLogin: Boolean) {
        if (!AccountModule.isLogin()) {
            Log.d(TAG_IM_LOGIN, "login return, Account is not Login")
            return
        }
        if (TUILogin.isUserLogined()) {
            Log.d(TAG_IM_LOGIN, "login return, TUILogin.isUserLogined")
            return
        }
        val uid = AccountModule.uid
        if (uid.isEmpty()) {
            Log.e(TAG_IM_LOGIN, "handleLogin fail, for $uid is invalid.")
            return
        }
        val userSig = GenerateUserSig.genTestUserSig(uid, IMConfig.APP_ID, IMConfig.SECRET_KEY)
        Log.d(TAG_IM_LOGIN, "handleLogin, userSig:$userSig")
        val tuiLoginConfig: TUILoginConfig = TUIUtils.getLoginConfig()
        LoginWrapper.loginIMSDK(
            AppUtil.appContext,
            IMConfig.APP_ID,
            uid,
            userSig, tuiLoginConfig,
            object : TUICallback() {
                override fun onSuccess() {
                    Log.i(TAG_IM_LOGIN, "login onSuccess, uid: $uid")
                    TUILogin.addLoginListener(mLoginListener)
                    TIMAppService.getInstance().registerPushManually()
                }

                override fun onError(errorCode: Int, errorMessage: String?) {
                    Log.e(
                        TAG_IM_LOGIN,
                        "login fail errorCode: $errorCode errorMessage:$errorMessage"
                    )
                }
            })
    }

    override fun isLogin(): Boolean {
        return TUILogin.isUserLogined()
    }

    private fun logout() {
        try {
            TUILogin.logout(object : TUICallback() {
                override fun onSuccess() {
                    Log.i(TAG_IM_LOGIN, "logout success")
                    TUILogin.removeLoginListener(mLoginListener)
                }

                override fun onError(errorCode: Int, errorMessage: String) {
                    Log.e(
                        TAG_IM_LOGIN,
                        "logout failed, errorCode: $errorCode , errorMessage: $errorMessage"
                    )
                }
            })
        } catch (e: Exception) {
            Log.e(TAG_IM_LOGIN, "logout failed with exception: ${e.message}", e)
        }

    }

    private val mLoginListener: TUILoginListener = object : TUILoginListener() {
        override fun onKickedOffline() {
            super.onKickedOffline()
            Log.i(TAG_IM_LOGIN, "You have been kicked off the line. Please login again!")
            logout()
        }

        override fun onUserSigExpired() {
            super.onUserSigExpired()
            Log.i(TAG_IM_LOGIN, "Your user signature information has expired")
            reLogin()
        }
    }
}