package com.gh.gamecenter.common.exposure.meta

import android.Manifest
import android.app.Application
import android.content.Context
import android.content.pm.PackageManager
import android.net.ConnectivityManager
import android.os.Build
import android.provider.Settings
import android.telephony.TelephonyManager
import android.text.TextUtils
import com.alibaba.android.arouter.launcher.ARouter
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.common.HaloApp
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.core.provider.IAppProvider
import com.gh.gamecenter.core.provider.IBuildConfigProvider
import com.gh.gamecenter.core.provider.IUserManagerProvider

object MetaUtil {

    private val application: Application = HaloApp.getInstance()

    private var m: Meta? = null
    private var androidId: String? = null
    private var base64EncodedAndroidId: String? = null

    fun refreshMeta() {

        val appProvider = ARouter.getInstance().build(RouteConsts.provider.app).navigation() as? IAppProvider
        val buildConfigProvider =
            ARouter.getInstance().build(RouteConsts.provider.buildConfig).navigation() as? IBuildConfigProvider
        val userManagerProvider =
            ARouter.getInstance().build(RouteConsts.provider.userManager).navigation() as? IUserManagerProvider
        m = Meta(
            mac = null,
            jnfj = getBase64EncodedIMEI(),
            model = getModel(),
            manufacturer = getManufacturer(),
            dia = getBase64EncodedAndroidId(),
            android_sdk = getAndroidSDK(),
            android_version = getAndroidVersion(),
            network = getNetwork(),
            os = getOS(),
            gid = appProvider?.getGid(),
            oaid = appProvider?.getOaid(),
            channel = getChannel(),
            appVersion = buildConfigProvider?.getVersionName(),
            userId = userManagerProvider?.getUserId(),
            exposureVersion = buildConfigProvider?.getExposureVersion(),
            rom = ""
        )
    }

    fun getMeta(): Meta {
        if (m == null) {
            refreshMeta()
        }
        return m!!
    }

    private fun getChannel(): String? {
        val appProvider = ARouter.getInstance().build(RouteConsts.provider.app).navigation() as? IAppProvider
        return appProvider?.getChannel()
    }

    /**
     * Get IMEI
     */
    @JvmStatic
    fun getIMEI(): String {
        return ""
//        val appProvider = ARouter.getInstance().build(RouteConsts.provider.app).navigation() as? IAppProvider
//        if (appProvider?.isUserAcceptPrivacyPolicy(HaloApp.getInstance()) == false) {
//            return ""
//        }
//
//        if (imei != null) {
//            return imei ?: ""
//        }
//
//        imei = SPUtils.getString(Constants.SP_IMEI)
//
//        if (!TextUtils.isEmpty(imei)) {
//            return imei ?: ""
//        }
//
//        if (application.checkCallingOrSelfPermission(Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
//            return ""
//        }
//
//        val telephonyManager = application.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
//
//        if (Build.VERSION.SDK_INT >= 29) {
//            return "".apply {
//                imei = this
//                SPUtils.setString(Constants.SP_IMEI, this)
//            }
//        } else if (Build.VERSION.SDK_INT >= 26) {
//            return (telephonyManager.imei ?: "").apply {
//                imei = this
//                SPUtils.setString(Constants.SP_IMEI, this)
//            }
//        }
//
//        return (telephonyManager.getDeviceId() ?: "").apply {
//            imei = this
//            SPUtils.setString(Constants.SP_IMEI, this)
//        }

    }

    @JvmStatic
    fun getBase64EncodedIMEI(): String {
        return ""
//        if (imei == null) {
//            getIMEI()
//        }
//
//        if (TextUtils.isEmpty(base64EncodedImei) && imei != null) {
//            try {
//                base64EncodedImei = android.util.Base64.encodeToString(getIMEI().trim().toByteArray(), android.util.Base64.NO_WRAP)
//            } catch (e: java.lang.Exception) {
//                e.printStackTrace()
//                return ""
//            }
//        }
//
//        return base64EncodedImei ?: ""
    }

    @JvmStatic
    fun getBase64EncodedAndroidId(): String {
        if (androidId == null) {
            getAndroidId()
        }

        if (TextUtils.isEmpty(base64EncodedAndroidId) && androidId != null) {
            try {
                base64EncodedAndroidId =
                    android.util.Base64.encodeToString(getAndroidId().trim().toByteArray(), android.util.Base64.NO_WRAP)
            } catch (e: java.lang.Exception) {
                e.printStackTrace()
                return ""
            }
        }

        return base64EncodedAndroidId ?: ""
    }

    fun getModel(): String? {
        return Build.MODEL
    }

    fun getManufacturer(): String? {
        return Build.MANUFACTURER
    }

    @JvmStatic
    fun getAndroidId(): String {
        val appProvider = ARouter.getInstance().build(RouteConsts.provider.app).navigation() as? IAppProvider
        if (appProvider?.isUserAcceptPrivacyPolicy(HaloApp.getInstance()) == false) {
            return ""
        }

        if (androidId != null) {
            return androidId ?: ""
        }

        androidId = SPUtils.getString(Constants.SP_ANDROID_ID)

        if (!TextUtils.isEmpty(androidId)) {
            return androidId ?: ""
        }

        return try {
            Settings.Secure.getString(application.contentResolver, Settings.Secure.ANDROID_ID).apply {
                androidId = this
                SPUtils.setString(Constants.SP_ANDROID_ID, this)
            }
        } catch (e: Exception) {
            e.printStackTrace()
            androidId = ""
            SPUtils.setString(Constants.SP_ANDROID_ID, "")
            ""
        }

    }

    fun getAndroidSDK(): Int? {
        return Build.VERSION.SDK_INT
    }

    fun getAndroidVersion(): String? {
        return Build.VERSION.RELEASE
    }

    fun getNetwork(): String? {

        if (application.checkCallingOrSelfPermission(Manifest.permission.ACCESS_NETWORK_STATE) != PackageManager.PERMISSION_GRANTED)
            return "unknown"

        val activeNetwork =
            (application.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager).activeNetworkInfo
                ?: return "unknown"

        return when (activeNetwork.type) {
            ConnectivityManager.TYPE_WIFI -> "Wifi"
            ConnectivityManager.TYPE_WIMAX -> "WifiMax"
            ConnectivityManager.TYPE_MOBILE -> {
                val telephonyManager = application.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
                if (telephonyManager.simState != TelephonyManager.SIM_STATE_READY) return "unknown"
                when (telephonyManager.networkType) {
                    // Unknown
                    TelephonyManager.NETWORK_TYPE_UNKNOWN -> "Cellular - Unknown"
                    // Cellular Data–2G
                    TelephonyManager.NETWORK_TYPE_EDGE, TelephonyManager.NETWORK_TYPE_GPRS, TelephonyManager.NETWORK_TYPE_CDMA,
                    TelephonyManager.NETWORK_TYPE_IDEN, TelephonyManager.NETWORK_TYPE_1xRTT -> "Cellular - 2G"
                    // Cellular Data–3G
                    TelephonyManager.NETWORK_TYPE_UMTS, TelephonyManager.NETWORK_TYPE_HSDPA, TelephonyManager.NETWORK_TYPE_HSPA,
                    TelephonyManager.NETWORK_TYPE_HSPAP, TelephonyManager.NETWORK_TYPE_HSUPA, TelephonyManager.NETWORK_TYPE_EVDO_0,
                    TelephonyManager.NETWORK_TYPE_EVDO_A, TelephonyManager.NETWORK_TYPE_EVDO_B -> "Cellular - 3G"
                    // Cellular Data–4G
                    TelephonyManager.NETWORK_TYPE_LTE -> "Cellular - 4G"
                    else -> "Cellular - Unknown Generation"
                }

            }
            else -> "unknown"
        }

    }

    fun getOS(): String {
        return "android"
    }
}