package cn.yyxx.eyuangame.core.impl

import android.app.Activity
import android.app.Application
import android.content.Context
import android.content.Intent
import android.text.TextUtils
import cn.yyxx.eyuangame.base.entity.SdkChargeInfo
import cn.yyxx.eyuangame.base.entity.SdkEvent
import cn.yyxx.eyuangame.base.entity.SdkRoleInfo
import cn.yyxx.eyuangame.base.internal.ICallback
import cn.yyxx.eyuangame.base.internal.IInitialize
import cn.yyxx.eyuangame.base.utils.Logger
import cn.yyxx.eyuangame.base.utils.ParamsUtils
import cn.yyxx.eyuangame.core.entity.ResultInfo
import cn.yyxx.eyuangame.core.entity.SdkBackLoginInfo
import cn.yyxx.eyuangame.core.entity.bean.init.InitBean
import cn.yyxx.eyuangame.core.impl.center.HybridActivity
import cn.yyxx.eyuangame.core.impl.floatball.FloatCenterServiceManager
import cn.yyxx.eyuangame.core.impl.iab.ChargeImpl
import cn.yyxx.eyuangame.core.impl.login.LoginActivity
import cn.yyxx.eyuangame.core.internal.IImplCallback
import cn.yyxx.eyuangame.core.internal.IRequestCallback
import cn.yyxx.eyuangame.core.linking.Linking
import cn.yyxx.eyuangame.core.network.Host
import cn.yyxx.eyuangame.core.network.SdkRequest
import cn.yyxx.eyuangame.core.ui.dialog.ScaleLoadingDialog
import cn.yyxx.eyuangame.core.ui.dialog.TipsDialog
import cn.yyxx.eyuangame.core.utils.MMKVUtils
import cn.yyxx.support.BeanUtils
import cn.yyxx.support.DensityUtils
import cn.yyxx.support.ResUtils
import cn.yyxx.support.device.DeviceInfoUtils
import cn.yyxx.support.gaid.GAIDUtils
import cn.yyxx.support.hawkeye.LogUtils
import cn.yyxx.support.hawkeye.OwnDebugUtils
import com.google.firebase.crashlytics.FirebaseCrashlytics
import java.util.concurrent.atomic.AtomicInteger


/**
 * @author #Suyghur.
 * Created on 2021/06/16
 */
class SdkBridgeImpl(context: Context) {

    private var hasReadGaid = false
    private var roleInfo: SdkRoleInfo? = null

    private var initState = false

    //是否有公告，默认有，为了拦截初始化后马上登录
    private var isShowInitDialog = true

    //登录接口是否在休眠中，公告接口请求完成后，会自动发起登录
    private var isSleepLogin = false

    //当前是否存在登录操作
    private var isExistLoginHandle = false
    private var isSubmitRoleData = false

    @Volatile
    private var timeCount = AtomicInteger(0)

    private var exitDialog: TipsDialog? = null

    private var initLoadingDialog: ScaleLoadingDialog? = null


    init {
        Host.initHostModel(context)
        LogUtils.DEBUG = OwnDebugUtils.isOwnDebug(context, "yyxx_cfg.properties", "yyxx_game", "YYXX_OWN_DEBUG")
    }

    fun attachBaseContext(application: Application, context: Context) {
        Logger.initZap(application)
        SdkDrive.instance.initSdkDrive(application)
        Logger.i("EYuanGameSdk attachBaseContext ...")
        GAIDUtils.initGoogleAdid(application) { code, _ ->
            if (code == 0) {
                Logger.i("谷歌框架可以访问，请求gaid")
                SdkDrive.instance.setParam("device_id", GAIDUtils.getGoogleAdid())
                FirebaseCrashlytics.getInstance().setCustomKey("device_id", GAIDUtils.getGoogleAdid())
            } else {
                Logger.e("谷歌框架不可访问，使用android id替代")
                SdkDrive.instance.setParam("device_id", DeviceInfoUtils.getAndroidDeviceId(application))
                FirebaseCrashlytics.getInstance().setCustomKey("device_id", DeviceInfoUtils.getAndroidDeviceId(application))
            }
            hasReadGaid = true
        }
    }

    fun initApplication(application: Application) {
        Logger.i("EYuanGameSdk initApplication ...")
        MMKVUtils.instance.init(application)
        Linking.instance.initialize(application)
    }

    fun initialize(activity: Activity, isLandscape: Boolean, callback: ICallback, initCallback: IInitialize) {
        Logger.i("EYuanGameSdk initialize ...")
        isLand = isLandscape

        if (TextUtils.isEmpty(ParamsUtils.getGcpCode(activity))) {
            Logger.e("初始化失败，参数异常，请检查yyxx_cfg.properties中YYXX_GCP_CODE的值")
            initCallback.onResult(-1, "初始化失败，参数异常，请检查yyxx_cfg.properties中YYXX_GAME_CODE的值")
            callback.onResult(-1, "初始化失败，参数异常，请检查yyxx_cfg.properties中YYXX_GCP_CODE的值")
            return
        }

        if (TextUtils.isEmpty(ParamsUtils.getGameCode(activity))) {
            Logger.e("初始化失败，参数异常，请检查yyxx_cfg.properties中YYXX_GAME_CODE的值")
            initCallback.onResult(-1, "初始化失败，参数异常，请检查yyxx_cfg.properties中YYXX_GAME_CODE的值")
            callback.onResult(-1, "初始化失败，参数异常，请检查yyxx_cfg.properties中YYXX_GAME_CODE的值")
            return
        }

        if (TextUtils.isEmpty(ParamsUtils.getGoogleClientId(activity))) {
            Logger.e("初始化失败，参数异常，请检查yyxx_cfg.properties中YYXX_SERVER_CLIENT_ID的值")
            initCallback.onResult(-1, "初始化失败，参数异常，请检查yyxx_cfg.properties中YYXX_GAME_CODE的值")
            callback.onResult(-1, "初始化失败，参数异常，请检查yyxx_cfg.properties中YYXX_SERVER_CLIENT_ID的值")
            return
        }

        //获取当前屏幕尺寸
        SdkDrive.instance.setParam("screen", DensityUtils.getResolutionByFullScreen(activity))

        if (!hasReadGaid) {
            Logger.e("还未完成gaid加载，将延迟初始化")
            showInitLoadingDialog(activity)
            Thread {
                while (!hasReadGaid) {
                    try {
                        Logger.e("还未完成gaid加载，延迟1s初始化，$hasReadGaid")
                        Thread.sleep(1000)
                        timeCount.getAndIncrement()
                    } catch (e: InterruptedException) {
                        e.printStackTrace()
                    }
                }
                activity.runOnUiThread {
                    if (TextUtils.isEmpty(GAIDUtils.getGoogleAdid())) {
                        Logger.e("加载gaid失败，共延迟${timeCount}s初始化，将进行初始化操作...")
                    } else {
                        Logger.i("加载gaid成功，共延迟${timeCount}s初始化，将进行初始化操作...")
                    }
                    hideInitLoadingDialog()
                    startSdkInit(activity, callback, initCallback)
                }
            }
        } else {
            Logger.i("加载gaid成功，开始初始化...")
            startSdkInit(activity, callback, initCallback)
        }
    }

    private fun startSdkInit(activity: Activity, callback: ICallback, initCallback: IInitialize) {
        SdkRequest.instance.initSdk(activity, object : IRequestCallback {
            override fun onResponse(resultInfo: ResultInfo) {
                if (resultInfo.code == 1 && !TextUtils.isEmpty(resultInfo.data)) {
                    initBean = InitBean.toBean(resultInfo.data)
                    //TODO 下载图片资源
                    cacheImageResource(activity)

                    Linking.instance.create(activity)
                    showInitDialog(activity, callback, initCallback)
                    FloatCenterServiceManager.instance.init(activity)
                } else {
                    initState = false
                    initCallback.onResult(-1, "SDK初始化失败")
                    callback.onResult(-1, "SDK初始化失败")
                }
            }
        })
    }


    private fun cacheImageResource(activity: Activity) {
        //浮标icon
        initBean.floatCfg.floatIconUrl =
            "http://gogs.yyxxgame.com/Client/EYuanGameSdk-KTX/raw/eb71e59d47ea88a5200cfe691e550334b38fff48/library_core/src/main/res/drawable-xhdpi/yyxx_float_logo_img.png"
        initBean.floatCfg.floatIconLeftUrl =
            "http://gogs.yyxxgame.com/Client/EYuanGameSdk-KTX/raw/eb71e59d47ea88a5200cfe691e550334b38fff48/library_core/src/main/res/drawable-xhdpi/yyxx_float_logo_left_img.png"
        initBean.floatCfg.floatIconRightUrl =
            "http://gogs.yyxxgame.com/Client/EYuanGameSdk-KTX/raw/eb71e59d47ea88a5200cfe691e550334b38fff48/library_core/src/main/res/drawable-xhdpi/yyxx_float_logo_right_img.png"

        SdkRequest.instance.downloadImageFile(activity, initBean.floatCfg.floatIconUrl)
        //左边
        SdkRequest.instance.downloadImageFile(activity, initBean.floatCfg.floatIconLeftUrl)
        //右边
        SdkRequest.instance.downloadImageFile(activity, initBean.floatCfg.floatIconRightUrl)
//        //会员中心
//        SdkRequest.instance.downloadImageFile(activity, initBean.floatCfg.floatIconUrl)
//        //礼包
//        SdkRequest.instance.downloadImageFile(activity, initBean.floatCfg.floatIconUrl)
//        //客服
//        SdkRequest.instance.downloadImageFile(activity, initBean.floatCfg.floatIconUrl)
//        //储值
//        SdkRequest.instance.downloadImageFile(activity, initBean.floatCfg.floatIconUrl)
//        //邀请
//        SdkRequest.instance.downloadImageFile(activity, initBean.floatCfg.floatIconUrl)
    }

    private fun showInitDialog(activity: Activity, callback: ICallback, initCallback: IInitialize) {
        isShowInitDialog = false
        initState = true
        initCallback.onResult(0, "SDK初始化成功")
        callback.onResult(0, "SDK初始化成功")
    }

    fun login(activity: Activity, isAutoLogin: Boolean, callback: ICallback) {
        Logger.i("EYuanGameSdk login ...")

        if (!initState) {
            Logger.e("登录失败，SDK未初始化或初始化失败")
            callback.onResult(-1, "登录失败，SDK未初始化或初始化失败")
            return
        }
        if (isSleepLogin) {
            Logger.e("登录接口正在执行中，请稍等...")
            return
        }
        if (isExistLoginHandle) {
            Logger.e("登录接口已经存在队列中操作，请等待...")
            return
        }
        isExistLoginHandle = true
        if (isShowInitDialog) {
            Logger.e("登录调用过快或Dialog还未关闭，延迟登录，Dialog : $isShowInitDialog")
            callback.onResult(-1, "登录调用过快或Dialog还未关闭，延迟登录")
            if (!isSleepLogin) {
                isSleepLogin = true
                Thread {
                    while (isShowInitDialog) {
                        try {
                            Logger.e("公告还在执行，延迟2秒后自动登录，Dialog : $isShowInitDialog")
                            Thread.sleep(2000)
                        } catch (e: InterruptedException) {
                            e.printStackTrace()
                        }
                    }
                    isSleepLogin = false
                    isExistLoginHandle = false
                    activity.runOnUiThread {
                        Logger.e("公告接口执行完成，发起登录...")
                        login(activity, isAutoLogin, callback)
                    }
                }.start()
            }
            return
        }
        isExistLoginHandle = false
        SdkBackLoginInfo.instance.reset()
        LoginActivity.login(activity, isAutoLogin, object : IImplCallback {
            override fun onResult(code: Int, result: String) {
                Logger.d("onResult code : $code , result : $result")
                if (code == 0) {
                    if (SdkBackLoginInfo.instance.isRegUser) {
                        Linking.instance.register(activity)
                    }
                    FirebaseCrashlytics.getInstance().setUserId(SdkBackLoginInfo.instance.userId)
                    Linking.instance.login(activity)
                }
                callback.onResult(code, result)
            }
        })
    }

    fun logout(activity: Activity, callback: ICallback) {
        Logger.i("EYuanGameSdk logout ...")

        this.roleInfo = null
        SdkBackLoginInfo.instance.reset()
        FirebaseCrashlytics.getInstance().setUserId("")
        FloatCenterServiceManager.instance.detach()
        callback.onResult(0, "用户登出成功")
    }

    fun charge(activity: Activity, chargeInfo: SdkChargeInfo, isIab: Boolean, callback: ICallback) {
        Logger.i("EYuanGameSdk charge ...")

        if (!initState) {
            Logger.e("支付失败，SDK未初始化或初始化失败")
            callback.onResult(-1, "支付失败，SDK未初始化或初始化失败")
            return
        }
        if (TextUtils.isEmpty(SdkBackLoginInfo.instance.userId)) {
            Logger.e("支付失败，用户未登录或登录失败")
            callback.onResult(-1, "支付失败，用户未登录或登录失败")
            return
        }
        if (!isSubmitRoleData) {
            Logger.e("支付失败，角色未登录或登录失败")
            callback.onResult(-1, "支付失败，角色未登录或登录失败")
            return
        }
        if (!DeviceInfoUtils.isNetworkConnected(activity)) {
            Logger.e("当前网络连接异常，请重试")
            callback.onResult(-1, "当前网络连接异常，请重试")
            return
        }

        val innerChargeInfo = BeanUtils.deepClone(chargeInfo)
        if (innerChargeInfo == null) {
            Logger.e("支付失败，支付信息对象拷贝过程异常")
            callback.onResult(-1, "支付失败，支付信息对象拷贝过程异常")
            return
        }
        if (isIab) {
            ChargeImpl.instance.charge(activity, innerChargeInfo, object : IImplCallback {
                override fun onResult(code: Int, result: String) {
                    if (code == 0) {
                        Linking.instance.charge(activity, innerChargeInfo.amount)
                    }
                    callback.onResult(code, result)
                }
            })
        } else {
            //H5支付
            HybridActivity.start(activity, initBean.floatCfg.chargeCfg.url)
        }
    }

    fun roleCreate(activity: Activity, roleInfo: SdkRoleInfo) {
        Logger.i("EYuanGameSdk roleCreate ...")
        Linking.instance.roleCreate(activity)
        isSubmitRoleData = true
    }

    fun roleLauncher(activity: Activity, roleInfo: SdkRoleInfo) {
        Logger.i("EYuanGameSdk roleLauncher ...")
        Linking.instance.roleLauncher(activity)
        isSubmitRoleData = true

    }

    fun roleLevelUp(activity: Activity, roleInfo: SdkRoleInfo) {
        Logger.i("EYuanGameSdk roleLevelUp ...")
    }

    @Deprecated("暂时不需要向服务端上报角色信息")
    private fun submitRoleData(activity: Activity, timing: Int, roleInfo: SdkRoleInfo) {
        isSubmitRoleData = true
        SdkRequest.instance.submitRoleData(activity, timing, roleInfo, object : IRequestCallback {
            override fun onResponse(resultInfo: ResultInfo) {
                Logger.d("submitRoleData code : ${resultInfo.code} , msg : ${resultInfo.msg}")
            }

        })
    }

    fun openExitView(activity: Activity, callback: ICallback) {
        Logger.i("EYuanGameSdk openExitView ...")

        exitDialog?.apply {
            dismiss()
            exitDialog = null
        }

        exitDialog = TipsDialog(activity, true)
        exitDialog?.apply {
            textView.text = ResUtils.getResString(activity, "yyxx_tv_exit_content")
            leftButton.text = ResUtils.getResString(activity, "yyxx_tv_exit_left")
            leftButton.setOnClickListener {
                if (isShowing) {
                    dismiss()
                    exitDialog = null
                }
                callback.onResult(0, "退出游戏")
            }
            rightButton.text = ResUtils.getResString(activity, "yyxx_tv_exit_right")
            rightButton.setOnClickListener {
                if (isShowing) {
                    dismiss()
                    exitDialog = null
                }
                callback.onResult(-1, "继续游戏")
            }
            show()
        }
    }

    fun onStart(activity: Activity) {
        Logger.i("EYuanGameSdk onStart ...")
    }

    fun onRestart(activity: Activity) {
        Logger.i("EYuanGameSdk onRestart ...")
    }

    fun onResume(activity: Activity) {
        Logger.i("EYuanGameSdk onResume ...")
        FloatCenterServiceManager.instance.attach()
        Linking.instance.resume(activity)
    }

    fun onPause(activity: Activity) {
        Logger.i("EYuanGameSdk onPause ...")
        FloatCenterServiceManager.instance.detach()
        Linking.instance.pause(activity)
    }

    fun onStop(activity: Activity) {
        Logger.i("EYuanGameSdk onStop ...")
    }

    fun onDestroy(activity: Activity) {
        Logger.i("EYuanGameSdk onDestroy ...")
        FloatCenterServiceManager.instance.release()
        Linking.instance.release()
    }

    fun onActivityResult(activity: Activity, requestCode: Int, resultCode: Int, intent: Intent) {
        Logger.i("EYuanGameSdk onActivityResult ...")
    }

    fun onNewIntent(activity: Activity, intent: Intent) {
        Logger.i("EYuanGameSdk onNewIntent ...")
    }

    fun getCurrentUserId(): String {
        Logger.i("EYuanGameSdk getCurrentUserId ...")
        return SdkBackLoginInfo.instance.userId
    }

    fun linkingEvent(context: Context, sdkEvent: SdkEvent) {
        Logger.i("EYuanGameSdk linkingEvent ...")
        Linking.instance.extEvent(context, sdkEvent)
    }

    private fun showInitLoadingDialog(context: Context) {
        initLoadingDialog?.apply {
            dismiss()
            initLoadingDialog = null
        }

        initLoadingDialog = ScaleLoadingDialog(context, "")
        initLoadingDialog?.show()
    }

    private fun hideInitLoadingDialog() {
        initLoadingDialog?.apply {
            dismiss()
            initLoadingDialog = null
        }
    }

    companion object {
        var isLand = false
        lateinit var initBean: InitBean
    }

}