package com.adealink.weparty.im.manager

import android.content.Context
import android.text.TextUtils
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.data.UserInfo.Companion.loginUserInfo
import com.adealink.weparty.im.util.TUIUtils
import com.adealink.weparty.module.im.IMConfig.APP_ID
import com.tencent.imsdk.BaseConstants
import com.tencent.imsdk.v2.V2TIMConversationListener
import com.tencent.imsdk.v2.V2TIMManager
import com.tencent.imsdk.v2.V2TIMSDKListener
import com.tencent.qcloud.tuicore.TUILogin
import com.tencent.qcloud.tuicore.interfaces.TUICallback
import com.tencent.qcloud.tuicore.interfaces.TUILoginConfig
import com.tencent.qcloud.tuikit.timcommon.util.ThreadUtils

object LoginWrapper {
    private var v2TIMSDKListener: V2TIMSDKListener? = null
    private var v2TIMConversationListener: V2TIMConversationListener? = null
    private val appLoginObservers: MutableList<AppLoginListener> = ArrayList<AppLoginListener>()

    init {
        initIMSDKObserver()
    }

    private fun initIMSDKObserver() {
        if (v2TIMSDKListener == null) {
            v2TIMSDKListener = object : V2TIMSDKListener() {
                override fun onConnecting() {
                    for (listener in appLoginObservers) {
                        listener.onConnecting()
                    }
                }

                override fun onConnectSuccess() {
                    for (listener in appLoginObservers) {
                        listener.onConnectSuccess()
                    }

                    tryToAutoLogin()
                }

                override fun onConnectFailed(code: Int, error: String?) {
                    for (listener in appLoginObservers) {
                        listener.onConnectFailed(code, error)
                    }
                }

                override fun onUserSigExpired() {
                    for (listener in appLoginObservers) {
                        listener.onUserSigExpired()
                    }
                }
            }
        }

        if (v2TIMConversationListener == null) {
            v2TIMConversationListener = object : V2TIMConversationListener() {
                override fun onSyncServerStart() {
                    for (listener in appLoginObservers) {
                        listener.onSyncServerStart()
                    }
                }

                override fun onSyncServerFinish() {
                    for (listener in appLoginObservers) {
                        listener.onSyncServerFinish()
                    }
                }

                override fun onSyncServerFailed() {
                    for (listener in appLoginObservers) {
                        listener.onSyncServerFailed()
                    }
                }
            }
        }

        V2TIMManager.getInstance().addIMSDKListener(v2TIMSDKListener)
        V2TIMManager.getConversationManager().addConversationListener(v2TIMConversationListener)
    }

    fun addAppLoginObserver(observer: AppLoginListener?) {
        if (observer == null) {
            return
        }

        ThreadUtils.runOnUiThread(object : Runnable {
            override fun run() {
                if (!appLoginObservers.contains(observer)) {
                    appLoginObservers.add(observer)
                }
            }
        })
    }

    fun removeLoginObserver(observer: AppLoginListener?) {
        if (observer == null) {
            return
        }

        ThreadUtils.runOnUiThread(object : Runnable {
            override fun run() {
                appLoginObservers.remove(observer)
            }
        })
    }

    fun loginIMSDK(
        context: Context,
        sdkAppID: Int,
        userID: String?,
        userSig: String?,
        config: TUILoginConfig?,
        tuiCallback: TUICallback?
    ) {
        TUILogin.login(context, sdkAppID, userID, userSig, config, object : TUICallback() {
            override fun onError(code: Int, desc: String?) {
                loginUserInfo.setLastLoginCode(code)
                if (tuiCallback != null) {
                    tuiCallback.onError(code, desc)
                }
            }

            override fun onSuccess() {
                if (config == null || false == config.isInitLocalStorageOnly()) {
                    loginUserInfo.setLastLoginCode(BaseConstants.ERR_SUCC)
                }

                if (tuiCallback != null) {
                    tuiCallback.onSuccess()
                }
            }
        })
    }

    private fun tryToAutoLogin() {
        val loginStatus = V2TIMManager.getInstance().getLoginStatus()
        val userInfo = loginUserInfo
        val lastLoginCode = loginUserInfo.getLastLoginCode()
        if (loginStatus == V2TIMManager.V2TIM_STATUS_LOGOUT && !TextUtils.isEmpty(userInfo!!.getUserId()) && userInfo.isAutoLogin()) {
            if (lastLoginCode >= BaseConstants.ERR_SDK_NET_ENCODE_FAILED && lastLoginCode <= BaseConstants.ERR_SDK_NET_SEND_REMAINING_TIMEOUT_NO_NETWORK) {
                Log.i(TAG_IM_LOGIN, "onConnectSuccess, login IMSDK")
                loginIMSDK(
                    AppUtil.appContext,
                    APP_ID,
                    userInfo.getUserId(),
                    userInfo.getUserSig(),
                    TUIUtils.getLoginConfig(),
                    object : TUICallback() {
                        override fun onSuccess() {
                            // do nothing
                        }

                        override fun onError(errorCode: Int, errorMessage: String?) {
                            loginUserInfo?.setLastLoginCode(errorCode)
                            Log.e(TAG_IM_LOGIN, "tryToAutoLogin error:" + errorCode)
                            //错误码详见:
                            //https://trtc.io/zh/document/34348?product=chat&platform=android
                            if (errorCode < BaseConstants.ERR_SDK_NET_ENCODE_FAILED
                                || errorCode > BaseConstants.ERR_SDK_NET_SEND_REMAINING_TIMEOUT_NO_NETWORK
                            ) {
                                // TODO: 2025/11/14 重新登录
                            }
                        }
                    })
            }
        }
    }

    abstract class AppLoginListener {
        fun onConnecting() {}

        fun onConnectSuccess() {}

        fun onConnectFailed(code: Int, error: String?) {}

        fun onUserSigExpired() {}

        fun onSyncServerStart() {}

        fun onSyncServerFinish() {}

        fun onSyncServerFailed() {}
    }
}
