package cn.yyxx.eyuancomm.comm.impl

import android.app.Activity
import android.app.Application
import android.content.Context
import android.content.Intent
import android.text.TextUtils
import cn.yyxx.eyuancomm.comm.entity.*
import cn.yyxx.eyuancomm.comm.entity.Function
import cn.yyxx.eyuancomm.comm.internal.ICallback
import cn.yyxx.eyuancomm.comm.network.Host
import cn.yyxx.eyuancomm.comm.network.SdkRequest
import cn.yyxx.eyuancomm.comm.utils.Logger
import cn.yyxx.eyuancomm.comm.utils.ParamsUtils
import cn.yyxx.eyuancomm.comm.widget.ScaleLoadingDialog
import cn.yyxx.support.JsonUtils
import cn.yyxx.support.device.DeviceInfoUtils
import cn.yyxx.support.gaid.GAIDUtils
import cn.yyxx.support.msa.MsaDeviceIdsHandler
import org.json.JSONObject
import java.util.concurrent.atomic.AtomicInteger

/**
 * @author #Suyghur.
 * Created on 2022/01/17
 */
class CommSdkImpl(context: Context) {

    private var mSdkProxy: Any? = null
    private var hasSdkInit = false
    private var channelSdkInit = false
    private var hasReadDeviceId = false
    private var channelId: String = ""

    private var initLoadingDialog: ScaleLoadingDialog? = null
    private var payLoadingDialog: ScaleLoadingDialog? = null

    @Volatile
    private var timeCount = AtomicInteger(0)

    companion object {
        var isLandscape = false
    }

    init {
        channelId = ParamsUtils.getChannelId(context)
        getSdkProxyManager(context)
    }

    private fun getSdkProxyManager(context: Context): Any? {
        if (mSdkProxy == null) {
            mSdkProxy = SdkProxyManager.initSdkProxyManager(context, channelId)
        }
        return mSdkProxy
    }

    /**
     * 同步Application中的attachBaseContext
     */
    fun attachBaseContext(application: Application, context: Context) {
        Logger.initZap(application)
        Logger.i("EYuanCommSdk attachBaseContext ...")
        CommSdkDrive.instance.initSdkDrive(application)
        initGaid(application)

        if (mSdkProxy == null) {
            mSdkProxy = getSdkProxyManager(application)
        }
        SdkProxyManager.call(Function.ATTACH_BASE_CONTEXT, arrayOf(Application::class.java, Context::class.java), arrayOf(application, context))
    }


    private fun initGaid(application: Application) {
        GAIDUtils.initGoogleAdid(application) { code, _ ->
            if (code == 0) {
                if (GAIDUtils.getGoogleAdid() == "00000000-0000-0000-0000-000000000000") {
                    Logger.i("谷歌框架可以访问，gaid被限制跟踪，尝试使用oaid")
                    initOaid(application)
                } else {
                    Logger.i("谷歌框架可以访问，请求gaid")
                    CommSdkDrive.instance.setCommParam("device_id", GAIDUtils.getGoogleAdid())
                    hasReadDeviceId = true
                }
            } else {
                Logger.e("谷歌框架不可访问，尝试使用oaid")
                initOaid(application)
            }
        }
    }

    private fun initOaid(application: Application) {
        MsaDeviceIdsHandler.initMsaDeviceIds(application) { code, msg, _ ->
            if (code == 0) {
                Logger.e("获取oaid成功，使用oaid替代")
                CommSdkDrive.instance.setCommParam("device_id", MsaDeviceIdsHandler.oaid)
            } else {
                Logger.d("获取oaid失败，msg: $msg，使用android id替代")
                CommSdkDrive.instance.setCommParam("device_id", DeviceInfoUtils.getAndroidDeviceId(application))
            }
            hasReadDeviceId = true
        }
    }

    /**
     * 同步Application中的onCreate
     */
    fun initApplication(application: Application) {
        Host.initHostModel(application)
        if (mSdkProxy == null) {
            mSdkProxy = getSdkProxyManager(application)
        }
        SdkProxyManager.call(Function.INIT_APPLICATION, arrayOf(Application::class.java), arrayOf(application))
    }

    /**
     * SDK初始化
     *
     * @param activity    Activity上下文
     * @param isLandscape 是否横屏
     * @param callback    SDK初始化回调
     */
    fun initialize(activity: Activity, isLandscape: Boolean, callback: ICallback) {
        Logger.i("EYuanCommSdk initialize ...")
        CommSdkImpl.isLandscape = isLandscape
        if (checkSdkProxyNull(Function.INITIALIZE, callback)) {
            return
        }

        // 有些CP在资源再加时候回重复调用初始化，这里拦截一下
        if (hasSdkInit) {
            Logger.e("Sdk初始化已经执行，拦截此次调用")
            callback.onResult(-1, "Sdk初始化已经执行")
            return
        }

        showInitLoadingDialog(activity)

        if (!hasReadDeviceId) {
            Logger.e("还未完成deviceId加载，将延迟初始化")
//            showInitLoadingDialog(activity)
            Thread {
                while (!hasReadDeviceId) {
                    try {
                        Logger.e("还未完成deviceId加载，延迟1s初始化，$hasReadDeviceId")
                        Thread.sleep(1000)
                        timeCount.getAndIncrement()
                    } catch (e: InterruptedException) {
                        e.printStackTrace()
                    }
                }
                activity.runOnUiThread {
                    if (hasReadDeviceId) {
                        Logger.i("加载deviceI完成，共延迟${timeCount}s初始化，将进行初始化操作...")
                        startSdkInit(activity, isLandscape, callback)
                    }
                }
            }.start()
        } else {
            Logger.i("加载deviceI完成，开始初始化...")
            startSdkInit(activity, isLandscape, callback)
        }
    }

    private fun startSdkInit(activity: Activity, isLandscape: Boolean, callback: ICallback) {
        // 先渠道后融合，因为个别渠道需要在融合初始化接口透传数据
        // 渠道Sdk初始化
        val channelCallback = object : ICallback {
            override fun onResult(code: Int, result: String) {
                // 不管结果如何都不在这里回调cp
                // 融合Sdk初始化
                startInitCommSdk(activity, callback)
            }
        }

        SdkProxyManager.call(
            Function.INITIALIZE,
            arrayOf(Activity::class.java, Boolean::class.java, ICallback::class.java),
            arrayOf(activity, isLandscape, channelCallback)
        )
    }

    private fun startInitCommSdk(activity: Activity, callback: ICallback) {
        Logger.d("融合Sdk初始化...")
        SdkRequest.instance.initSdk(activity, "") { resultInfo ->
            hasSdkInit = resultInfo.code == 1
            initLoadingDialog?.apply {
                dismiss()
                initLoadingDialog = null
            }
            if (hasSdkInit) {
                callback.onResult(0, "Sdk初始化成功")
            } else {
                callback.onResult(-1, "Sdk初始化失败")
            }
        }
    }

    /**
     * SDK用户登录
     *
     * @param activity Activity上下文
     * @param callback 登录回调对象
     */
    fun login(activity: Activity, callback: ICallback) {
        if (checkSdkProxyNull(Function.LOGIN, callback)) {
            return
        }
        if (checkSdkNonInit(Function.LOGIN, callback)) {
            return
        }

        val channelCallback = object : ICallback {
            override fun onResult(code: Int, result: String) {
                if (code == 0) {
                    SdkRequest.instance.userVerify(activity, result) { resultInfo ->
                        if (resultInfo.code == 1) {
                            if (!TextUtils.isEmpty(resultInfo.data)) {
                                val jsonObject = JSONObject(resultInfo.data)
                                SdkLoginInfo.instance.userId = jsonObject.getString("uid")
                                SdkLoginInfo.instance.token = jsonObject.getString("token")
                            }
                            showFloatBall(activity)
                            callback.onResult(0, SdkLoginInfo.instance.toJsonString())
                        } else {
                            callback.onResult(-1, resultInfo.msg)
                        }
                    }
                } else {
                    callback.onResult(-1, result)
                }
            }
        }

        SdkProxyManager.call(Function.LOGIN, arrayOf(Activity::class.java, ICallback::class.java), arrayOf(activity, channelCallback))
    }

    /**
     * SDK用户登出账号
     *
     * @param activity Activity上下文
     * @param callback 登出回调对象
     */
    fun logout(activity: Activity, callback: ICallback) {
        if (checkSdkProxyNull(Function.LOGOUT, callback)) {
            return
        }
        if (checkSdkNonInit(Function.LOGOUT, callback)) {
            return
        }

        SdkProxyManager.call(Function.LOGOUT, arrayOf(Activity::class.java, ICallback::class.java), arrayOf(activity, callback))
    }

    /**
     * SDK用户支付
     *
     * @param activity   Activity上下文
     * @param chargeInfo 支付信息实体对象
     * @param callback   支付回调对象
     */
    fun charge(activity: Activity, chargeInfo: SdkChargeInfo, callback: ICallback) {
        if (checkSdkProxyNull(Function.CHARGE, callback)) {
            return
        }
        if (checkSdkNonInit(Function.CHARGE, callback)) {
            return
        }

        showPayLoadingDialog(activity)
        // 判断渠道
        if (channelId == ChannelId.YYXX) {
            // 特殊渠道，先调用渠道sdk生成支付扩展参数，在请求生成订单
            // 获取拿到channel_ext
            SdkProxyManager.call(
                Function.GET_ORDER_EXT,
                arrayOf(Activity::class.java, SdkChargeInfo::class.java, ICallback::class.java),
                arrayOf(activity, chargeInfo, object : ICallback {
                    override fun onResult(code: Int, result: String) {
                        if (code == 0 && !TextUtils.isEmpty(result)) {
                            chargeInfo.channelExt = result
                            doCharge(activity, chargeInfo, callback)
                        } else {
                            dimissPayLoadingDialog(activity)
                            callback.onResult(-1, result)
                        }
                    }
                })
            )
        } else {
            doCharge(activity, chargeInfo, callback)
        }
    }

    private fun doCharge(activity: Activity, chargeInfo: SdkChargeInfo, callback: ICallback) {
        SdkRequest.instance.createOrder(activity, "", chargeInfo) { resultInfo ->
            dimissPayLoadingDialog(activity)
            if (resultInfo.code == 1 && !TextUtils.isEmpty(resultInfo.data)) {
                val jsonObject = JSONObject(resultInfo.data)
                chargeInfo.orderId = if (JsonUtils.hasJsonKey(jsonObject, "order_id")) {
                    jsonObject.getString("order_id")
                } else {
                    ""
                }
                chargeInfo.channelNotifyUrl = if (JsonUtils.hasJsonKey(jsonObject, "notify_url")) {
                    jsonObject.getString("notify_url")
                } else {
                    ""
                }
                // 调用渠道sdk支付
                SdkProxyManager.call(
                    Function.CHARGE,
                    arrayOf(Activity::class.java, SdkChargeInfo::class.java, ICallback::class.java),
                    arrayOf(activity, chargeInfo, callback)
                )
            } else {
                callback.onResult(-1, resultInfo.msg)
            }
        }
    }

    /**
     * SDK角色创建信息上报
     *
     * @param activity Activity上下文
     * @param roleInfo 角色信息实体
     */
    fun roleCreate(activity: Activity, roleInfo: SdkRoleInfo) {
        if (checkSdkProxyNull(Function.ROLE_CREATE, null)) {
            return
        }
        if (checkSdkNonInit(Function.ROLE_CREATE, null)) {
            return
        }

        SdkProxyManager.call(Function.ROLE_CREATE, arrayOf(Activity::class.java, SdkRoleInfo::class.java), arrayOf(activity, roleInfo))
    }

    /**
     * SDK角色登录信息上报
     *
     * @param activity Activity上下文
     * @param roleInfo 角色信息实体
     */
    fun roleLauncher(activity: Activity, roleInfo: SdkRoleInfo) {
        if (checkSdkProxyNull(Function.ROLE_LAUNCHER, null)) {
            return
        }
        if (checkSdkNonInit(Function.ROLE_LAUNCHER, null)) {
            return
        }

        SdkProxyManager.call(Function.ROLE_LAUNCHER, arrayOf(Activity::class.java, SdkRoleInfo::class.java), arrayOf(activity, roleInfo))
    }

    /**
     * SDK角色升级信息上报
     *
     * @param activity Activity上下文
     * @param roleInfo 角色信息实体
     */
    fun roleLevelUp(activity: Activity, roleInfo: SdkRoleInfo) {
        if (checkSdkProxyNull(Function.ROLE_LEVEL_UP, null)) {
            return
        }
        if (checkSdkNonInit(Function.ROLE_LEVEL_UP, null)) {
            return
        }

        SdkProxyManager.call(Function.ROLE_LEVEL_UP, arrayOf(Activity::class.java, SdkRoleInfo::class.java), arrayOf(activity, roleInfo))
    }

    fun hasExitView(activity: Activity): Boolean {
        if (checkSdkProxyNull(Function.HAS_EXIT_VIEW, null)) {
            return false
        }
        if (checkSdkNonInit(Function.HAS_EXIT_VIEW, null)) {
            return false
        }

        return SdkProxyManager.callback(Function.HAS_EXIT_VIEW, arrayOf(Activity::class.java), arrayOf(activity)) as Boolean
    }

    /**
     * 显示退出框
     *
     * @param activity Activity上下文
     * @param callback 退出回调对象
     */
    fun openExitView(activity: Activity, callback: ICallback) {
        if (checkSdkProxyNull(Function.OPEN_EXIT_VIEW, null)) {
            return
        }
        if (checkSdkNonInit(Function.OPEN_EXIT_VIEW, null)) {
            return
        }

        SdkProxyManager.call(Function.OPEN_EXIT_VIEW, arrayOf(Activity::class.java, ICallback::class.java), arrayOf(activity, callback))
    }

    fun onStart(activity: Activity) {
        if (checkSdkProxyNull(Function.ON_START, null)) {
            return
        }

        SdkProxyManager.call(Function.ON_START, arrayOf(Activity::class.java), arrayOf(activity))
    }

    fun onRestart(activity: Activity) {
        if (checkSdkProxyNull(Function.ON_RESTART, null)) {
            return
        }

        SdkProxyManager.call(Function.ON_RESTART, arrayOf(Activity::class.java), arrayOf(activity))
    }

    fun onResume(activity: Activity) {
        if (checkSdkProxyNull(Function.ON_RESUME, null)) {
            return
        }

        SdkProxyManager.call(Function.ON_RESUME, arrayOf(Activity::class.java), arrayOf(activity))
    }

    fun onPause(activity: Activity) {
        if (checkSdkProxyNull(Function.ON_PAUSE, null)) {
            return
        }

        SdkProxyManager.call(Function.ON_PAUSE, arrayOf(Activity::class.java), arrayOf(activity))
    }

    fun onStop(activity: Activity) {
        if (checkSdkProxyNull(Function.ON_STOP, null)) {
            return
        }

        SdkProxyManager.call(Function.ON_STOP, arrayOf(Activity::class.java), arrayOf(activity))
    }

    fun onDestroy(activity: Activity) {
        if (checkSdkProxyNull(Function.ON_DESTROY, null)) {
            return
        }

        SdkProxyManager.call(Function.ON_DESTROY, arrayOf(Activity::class.java), arrayOf(activity))
    }

    fun onActivityResult(activity: Activity, requestCode: Int, resultCode: Int, data: Intent?) {
        if (checkSdkProxyNull(Function.ON_ACTIVITY_RESULT, null)) {
            return
        }

        SdkProxyManager.call(
            Function.ON_ACTIVITY_RESULT,
            arrayOf(Activity::class.java, Int::class.java, Int::class.java, Intent::class.java),
            arrayOf(activity, requestCode, resultCode, data)
        )
    }

    fun onNewIntent(activity: Activity, intent: Intent?) {
        if (checkSdkProxyNull(Function.ON_NEW_INTENT, null)) {
            return
        }

        SdkProxyManager.call(Function.ON_NEW_INTENT, arrayOf(Activity::class.java, Intent::class.java), arrayOf(activity, intent))
    }

    fun getCurrentUserId(): String = SdkLoginInfo.instance.userId

//    fun getChannelVersion(): String {
//        if (checkSdkProxyNull(Function.GET_CHANNEL_VERSION, null)) {
//            return ""
//        }
//        if (checkSdkNonInit(Function.GET_CHANNEL_VERSION, null)) {
//            return ""
//        }
//
//        return SdkProxyManager.callback(Function.GET_CHANNEL_VERSION, emptyArray(), emptyArray()).toString()
//    }
//
//    fun getChannelName(): String {
//        if (checkSdkProxyNull(Function.GET_CHANNEL_NAME, null)) {
//            return ""
//        }
//        if (checkSdkNonInit(Function.GET_CHANNEL_NAME, null)) {
//            return ""
//        }
//
//        return SdkProxyManager.callback(Function.GET_CHANNEL_NAME, emptyArray(), emptyArray()).toString()
//    }

    fun linkingEvent(context: Context, sdkEvent: SdkEvent) {
        if (checkSdkProxyNull(Function.LINKING_EVENT, null)) {
            return
        }
        if (checkSdkNonInit(Function.LINKING_EVENT, null)) {
            return
        }

        SdkProxyManager.call(Function.LINKING_EVENT, arrayOf(Context::class.java, SdkEvent::class.java), arrayOf(context, sdkEvent))
    }

    fun share(activity: Activity, line: String, tag: String, quote: String, callback: ICallback) {
        if (checkSdkProxyNull(Function.SHARE, null)) {
            return
        }
        if (checkSdkNonInit(Function.SHARE, null)) {
            return
        }

        SdkProxyManager.call(
            Function.SHARE, arrayOf(Activity::class.java, String::class.java, String::class.java, String::class.java, ICallback::class.java),
            arrayOf(activity, line, tag, quote, callback)
        )
    }

    /**
     * SDK浮窗账号切换
     *
     * @param callback  切换回调对象
     */
    fun setOnFloatBallLogout(callback: ICallback) {
        if (checkSdkProxyNull(Function.SET_ON_FLOAT_BALL_LOGOUT, callback)) {
            return
        }
        if (checkSdkNonInit(Function.SET_ON_FLOAT_BALL_LOGOUT, callback)) {
            return
        }
        SdkProxyManager.call(Function.SET_ON_FLOAT_BALL_LOGOUT, arrayOf(ICallback::class.java), arrayOf(callback))
    }

    private fun showFloatBall(activity: Activity) {
        if (checkSdkProxyNull(Function.SHOW_FLOAT_BALL, null)) {
            return
        }
        if (checkSdkNonInit(Function.SHOW_FLOAT_BALL, null)) {
            return
        }
        SdkProxyManager.call(Function.SHOW_FLOAT_BALL, arrayOf(Activity::class.java), arrayOf(activity))
    }


    private fun hideFloatBall(activity: Activity) {
        if (checkSdkProxyNull(Function.HIDE_FLOAT_BALL, null)) {
            return
        }
        if (checkSdkNonInit(Function.HIDE_FLOAT_BALL, null)) {
            return
        }
        SdkProxyManager.call(Function.HIDE_FLOAT_BALL, arrayOf(activity::class.java), arrayOf(activity))
    }

    private fun checkSdkProxyNull(function: String, callback: ICallback?): Boolean {
        return if (mSdkProxy == null) {
            Logger.e("invoke $function error... SdkProxy is null")
            callback?.onResult(-1, "EYuanGameSdk 初始化失败")
            true
        } else {
            false
        }
    }

    private fun checkSdkNonInit(function: String, callback: ICallback?): Boolean {
        return if (!hasSdkInit) {
            Logger.e("invoke $function error ... EYuanGameSdk initialized failed or not initialized yet")
            callback?.onResult(-1, "EYuanGameSdk 初始化失败或还未进行初始化")
            true
        } else {
            false
        }
    }

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

    private fun showPayLoadingDialog(context: Context) {
        payLoadingDialog?.apply {
            dismiss()
            payLoadingDialog = null
        }
        payLoadingDialog = ScaleLoadingDialog(context, "")
        payLoadingDialog?.show()
    }

    private fun dimissPayLoadingDialog(context: Context) {
        payLoadingDialog?.apply {
            dismiss()
            payLoadingDialog = null
        }
    }
}