package com.ydl.ydlcommon.utils.actionutil

import android.annotation.SuppressLint
import android.content.Context
import android.net.ConnectivityManager
import android.net.NetworkInfo
import android.net.wifi.WifiManager
import android.os.Build
import android.provider.Settings
import android.text.TextUtils
import android.util.Log
import com.google.gson.Gson
import com.ydl.devicesidlib.DeviceIDHelper
import com.ydl.devicesidlib.Utils
import com.ydl.ydlcommon.base.BaseApp
import com.ydl.ydlcommon.data.http.api.ApiRequestUtil
import com.ydl.ydlcommon.data.http.params.ActionDataBean
import com.ydl.ydlcommon.data.http.params.BaiduActionDataBean
import com.ydl.ydlcommon.modular.ModularServiceManager
import com.ydl.ydlcommon.router.YdlCommonOut
import com.ydl.ydlcommon.utils.ActivityManager
import com.ydl.ydlcommon.utils.DeviceTool
import com.yidianling.common.tools.LogUtil
import com.yidianling.common.tools.RxDeviceTool
import com.yidianling.common.tools.RxTool
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import java.net.Inet4Address
import java.net.InetAddress
import java.net.NetworkInterface
import java.net.SocketException
import java.util.*


/**
 * 行为数据埋点工具类
 * Created by xj on 2019/6/22.
 */
class ActionCountUtils {

    companion object {
        const val TAG: String = "ActionCountUtils"
        var appId: String = ""
        var appName: String = ""
        var packageName: String = ""

        /**
         * appId:消息端来源  - ydl:ydl-app-android-user、xlzx:ydl-app-android-xlzx
         * appName:应用名称 - "心理咨询" else "壹点灵心理咨询"
         */
        fun init(id: String, name: String) {
            packageName = BaseApp.instance.packageName
            appId = id
            appName = name
        }

        /**
         * BI埋点封装方法
         * 传入埋点事件名称 格式：xxx|xxx
         *
         * 除非特殊说明 url 和 api 默认传空
         */
        fun count(eventName: String, vararg sign1: String) {
            count(eventName, *sign1, urlStr = "", apiStr = "")
        }

        fun countUid(eventName: String, uid: String, vararg sign1: String) {
            count(eventName, *sign1, urlStr = "", apiStr = "", uid = uid)
        }

        fun count(
            eventName: String,
            vararg sign1: String,
            urlStr: String = "",
            apiStr: String = "",
            uid: String = ""
        ) {
            var partId = ""
            var position = ""
            var userId = uid
            if (TextUtils.isEmpty(uid)) {
                userId = ModularServiceManager.getPlatformUserService()?.getUser()?.userId ?: ""
            }
            if (eventName.contains("|")) {
                val splitList = eventName.split("|")
                if (splitList.isNotEmpty() && splitList.size > 1) {
                    partId = splitList[0]
                    position = splitList[1]
                }
            }
            //除非特殊说明 url 和 api 默认传空
            count(userId, partId, position, url = urlStr, api = apiStr, signs = *sign1)
        }

        /**
         * 行为数据埋点调用的方法
         */
        fun count(
            uid: String?,
            partId: String,
            position: String,
            url: String,
            api: String,
            sign1: String
        ) {
            count(uid, partId, position, url, api, signs = *arrayOf(sign1))
        }

        /*
        *
        * 测试用埋点，现在服务端统一用百度埋点
        * */
        fun count(
            uid: String?,
            partId: String,
            position: String,
            url: String,
            api: String,
            vararg signs: String
        ) {


            try {

                val actionDataParams = ActionDataBean.Builder()
                actionDataParams.partId(partId)
                actionDataParams.position(position)
                actionDataParams.url(url)

                uid?.let {
                    actionDataParams.uid(uid)
                }
                actionDataParams.time(System.currentTimeMillis())
                actionDataParams.appVersion(RxDeviceTool.getAppVersionName(BaseApp.getApp()))
                actionDataParams.appId(appId)
                actionDataParams.api(api)
                actionDataParams.manufacturer(Build.BRAND.trim().toUpperCase())
                actionDataParams.model(Build.MODEL)
                actionDataParams.os(BIConstants.OS)
                actionDataParams.osVersion(Build.VERSION.RELEASE)
                actionDataParams.wifi(if (isWifi()) 0 else 1)
                var deviceId = ""
                /*
                * 因为DeviceIDHelper.getInstance().deviceId对于imei
                * 序列号对于小米手机Utils.getIMEI(context)
                * 第一次安装获取失败，第二次打开就能成功
                * 所以Utils.getIMEI(topTaskActivity)传入activity解决这个问题
                * */
                deviceId = if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) {
                    val topTaskActivity = ActivityManager.getInstance().getTopTaskActivity()
                    //获取imei
                    Utils.getIMEI(topTaskActivity)
                } else {
                    //android Q及以上取oaid
                    DeviceIDHelper.getInstance().deviceId
                }
                actionDataParams.deviceId(deviceId)
                signs == null ?: signs.forEachIndexed { index, s ->
                    //拓展参数个数确定，暂不使用反射调用
                    //actionDataParams.javaClass.getMethod("sign$index").invoke(s)
                    when (index) {
                        0 -> {
                            actionDataParams.sign1(s)
                        }
                        1 -> {
                            actionDataParams.sign2(s)
                        }
                        2 -> {
                            actionDataParams.sign3(s)
                        }
                        3 -> {
                            actionDataParams.sign4(s)
                        }
                        4 -> {
                            actionDataParams.sign5(s)
                        }
                    }

                }
                actionDataParams.screenWidth(RxDeviceTool.getScreenWidth(RxTool.getContext()!!))
                actionDataParams.screenHeight(RxDeviceTool.getScreenHeight(RxTool.getContext()!!))
                //剩余额外参数根据需求定义
                LogUtil.e("androididgetMacFromHardwareMAC地址:${DeviceTool.getMacFromHardware()}")
                //请求
                request(actionDataParams.build())


            } catch (e: Exception) {
                LogUtil.i(TAG, e.toString())
            }
        }

        /**
         * 百度检测数据埋点调用的方法
         */
        fun baiduCount(partId: String, position: String, convertType: Int) {
            val userId = ModularServiceManager.getPlatformUserService()?.getUser()?.userId ?: ""
            baiduCount(userId, partId, position, "", "", convertType, "")
        }

        /**
         * 百度检测数据埋点调用的方法
         */
        fun baiduCount(partId: String, position: String, convertType: Int, openInstallKey: String) {
            val userId = ModularServiceManager.getPlatformUserService()?.getUser()?.userId ?: ""
            baiduCount(userId, partId, position, "", "", convertType, openInstallKey)
        }

        /**
         * 百度检测数据埋点调用的方法
         */
        fun baiduCount(
            uid: String?,
            partId: String,
            position: String,
            url: String,
            api: String,
            convertType: Int
        ) {
            val userId = ModularServiceManager.getPlatformUserService()?.getUser()?.userId ?: ""
            baiduCount(userId, partId, position, url, api, convertType, "")
        }

        /**
         * @param openInstallKey  openInstall统计渠道的key和Value值
         * */
        fun baiduCount(
            uid: String?,
            partId: String,
            position: String,
            url: String,
            api: String,
            convertType: Int,
            openInstallKey: String?
        ) {
            try {
                val actionDataParams = ActionDataBean.Builder()
                actionDataParams.partId(partId)
                actionDataParams.position(position)
                actionDataParams.url(url)

                actionDataParams.time(System.currentTimeMillis())
                actionDataParams.appVersion(RxDeviceTool.getAppVersionName(BaseApp.getApp()))
                actionDataParams.appId(appId)
                actionDataParams.api(api)
                actionDataParams.manufacturer(Build.BRAND.trim().toUpperCase())
                actionDataParams.model(Build.MODEL)
                actionDataParams.os(BIConstants.OS)
                actionDataParams.uid=uid
                actionDataParams.osVersion(Build.VERSION.RELEASE)
                actionDataParams.wifi(if (isWifi()) 0 else 1)
                actionDataParams.screenWidth(RxDeviceTool.getScreenWidth(RxTool.getContext()!!))
                actionDataParams.screenHeight(RxDeviceTool.getScreenHeight(RxTool.getContext()!!))
                val baiduActionDataParams = BaiduActionDataBean.Builder()
                baiduActionDataParams.pkname = packageName
                baiduActionDataParams.deviceType = 2
                var deviceId = ""
                /*
                * 因为DeviceIDHelper.getInstance().deviceId对于imei
                * 序列号对于小米手机Utils.getIMEI(context)
                * 第一次安装获取失败，第二次打开就能成功
                * 所以Utils.getIMEI(topTaskActivity)传入activity解决这个问题
                * */
                deviceId = if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) {
                    val topTaskActivity = ActivityManager.getInstance().getTopTaskActivity()
                    //获取imei
                    Utils.getIMEI(topTaskActivity)
                } else {
                    //android Q及以上取oaid
                    DeviceIDHelper.getInstance().deviceId
                }
                baiduActionDataParams.deviceId(deviceId)
                baiduActionDataParams.convertType(convertType)
                baiduActionDataParams.convertTime(System.currentTimeMillis() / 1000)
                baiduActionDataParams.appid(0.toLong())
                baiduActionDataParams.appName(appName)
                try {
                    @SuppressLint("HardwareIds") val id =
                        Settings.Secure.getString(
                            RxTool.getContext().contentResolver,
                            Settings.Secure.ANDROID_ID
                        )
                    LogUtil.e("androidid未加密:${id}")
                } catch (e: java.lang.Exception) {

                }

                baiduActionDataParams.androidId(DeviceTool.getAndroidID())//MD5加密的androidId
                baiduActionDataParams.ip("")
                baiduActionDataParams.ipv6("")//给服务端传IPV6地址DeviceTool.getLocalIpV6()
                baiduActionDataParams.tp(Build.MODEL)
                baiduActionDataParams.network(DeviceTool.getNetworkState(RxTool.getContext()))
                baiduActionDataParams.convertParam("")
                baiduActionDataParams.uid(uid)
                Log.e("baiduActionDataParams", "---------${baiduActionDataParams}")
                try {
                    var mac = DeviceTool.getMacFromHardware()//获得mac地址，gprs和wifi返回同一个mac地址
                    LogUtil.e("androidid:mac:${mac}")
                    baiduActionDataParams.mac(mac)
                } catch (e: Exception) {

                }
                baiduActionDataParams.channel(YdlCommonOut.getChannelName())
                val gson = Gson().toJson(baiduActionDataParams)
                Log.e("Action", "---------$gson")
                actionDataParams.sign2(gson)
                actionDataParams.sign3(YdlCommonOut.getChannelName())
                //openInstall渠道统计
                openInstallKey?.let {
                    actionDataParams.sign4(it)
                }
                //剩余额外参数根据需求定义
                //请求
                ActionCountUtils.request(actionDataParams.build())
            } catch (e: Exception) {
            }
        }

        /**
         * 接口返回错误埋点调用该方法
         * @param partId pardId-ydl_user_error_business
         * @param position error_log
         * @param sign1 访问接口对应的参数
         * @param sign2 接口返回的错误信息
         */
        fun baiDuCount(
            partId: String,
            position: String,
            api: String,
            sign1: String,
            sign2: String
        ) {
            val actionDataParams = ActionDataBean.Builder()
            actionDataParams.partId = partId
            actionDataParams.position = position
            actionDataParams.sign1 = sign1
            actionDataParams.sign2 = sign2
            actionDataParams.api = api
            actionDataParams.appVersion(RxDeviceTool.getAppVersionName(BaseApp.getApp()))
            val deviceId = if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) {
                val topTaskActivity = ActivityManager.getInstance().getTopTaskActivity()
                //获取imei
                Utils.getIMEI(topTaskActivity)
            } else {
                //android Q及以上取oaid
                DeviceIDHelper.getInstance().deviceId
            }
            actionDataParams.deviceId=deviceId

            actionDataParams.time(System.currentTimeMillis())
            actionDataParams.appId(appId)
            actionDataParams.manufacturer(Build.BRAND.trim().toUpperCase())
            actionDataParams.model(Build.MODEL)
            actionDataParams.os(BIConstants.OS)
            actionDataParams.osVersion(Build.VERSION.RELEASE)
            actionDataParams.wifi(if (isWifi()) 0 else 1)
            actionDataParams.uid = ModularServiceManager.getPlatformUserService()!!.getUser()?.userId
            //请求
            request(actionDataParams.build())
        }

        /**
         * 传入ActionDataParams参数，访问接口
         */
        @SuppressLint("CheckResult")
        fun request(actionDataBean: ActionDataBean) {
            try {
                ApiRequestUtil.actionDataCount(actionDataBean)
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe({
                        LogUtil.i(TAG, it.data)
                    }) {
                        LogUtil.i(TAG, it.toString())
                    }
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }

        /**
         * 获取当前ipv4地址
         * @return
         */
        fun getIpAddress(context: Context): String {
            // 获取WiFi服务
            val wifiManager = context.getSystemService(Context.WIFI_SERVICE) as WifiManager
            // 判断WiFi是否开启
            if (wifiManager.isWifiEnabled) {
                // 已经开启了WiFi
                val wifiInfo = wifiManager.connectionInfo
                val ipAddress = wifiInfo.ipAddress
                return intToIp(ipAddress)
            } else {
                // 未开启WiFi
                return getIpAddress()
            }
        }

        private fun intToIp(ipAddress: Int): String {
            return (ipAddress and 0xFF).toString() + "." +
                    (ipAddress shr 8 and 0xFF) + "." +
                    (ipAddress shr 16 and 0xFF) + "." +
                    (ipAddress shr 24 and 0xFF)
        }

        private fun getIpAddress(): String {
            try {
                var networkInterface: NetworkInterface
                var inetAddress: InetAddress
                val en = NetworkInterface.getNetworkInterfaces()
                while (en.hasMoreElements()) {
                    networkInterface = en.nextElement()
                    val enumIpAddr = networkInterface.inetAddresses
                    while (enumIpAddr.hasMoreElements()) {
                        inetAddress = enumIpAddr.nextElement()
                        if (!inetAddress.isLoopbackAddress && !inetAddress.isLinkLocalAddress) {
                            return inetAddress.hostAddress
                        }
                    }
                }
                return ""
            } catch (ex: SocketException) {
                ex.printStackTrace()
                return ""
            }

        }

        fun getLocalIPAddress(): String {
            var en: Enumeration<NetworkInterface> = NetworkInterface.getNetworkInterfaces()

            while (en.hasMoreElements()) {
                var intf: NetworkInterface = en.nextElement()
                var enumIpAddr: Enumeration<InetAddress> = intf.inetAddresses
                while (enumIpAddr.hasMoreElements()) {
                    var inetAddress: InetAddress = enumIpAddr.nextElement()
                    if (!inetAddress.isLoopbackAddress && (inetAddress is Inet4Address)) {
                        return inetAddress.getHostAddress().toString()

                    }
                }
            }
            return "null"
        }

        /**
         * 判断是否是wifi
         */
        private fun isWifi(): Boolean {
            try {
                var connectivityManager: ConnectivityManager =
                    RxTool.getContext()
                        .getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
                var info: NetworkInfo = connectivityManager.activeNetworkInfo
                if (info != null && info.type == ConnectivityManager.TYPE_WIFI) {
                    return true
                }
                return false
            } catch (e: Exception) {
                return false
            }

        }
    }
}