package dev.fluttercommunity.android_id

import android.annotation.SuppressLint
import android.content.ContentResolver
import android.provider.Settings
import androidx.annotation.NonNull

import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
import io.flutter.plugin.common.MethodChannel.Result
import android.content.Context
import android.net.wifi.WifiInfo
import android.net.wifi.WifiManager
import android.os.Build
import android.text.TextUtils
import androidx.core.app.ActivityCompat

import java.io.IOException
import java.io.InputStreamReader
import java.io.LineNumberReader
import java.net.NetworkInterface
import java.util.Collections
import java.util.List
import java.util.ArrayList
import java.util.Locale
import android.content.pm.PackageManager
import android.telephony.TelephonyManager
//import com.umeng.commonsdk.UMConfigure

/** AndroidIdPlugin */
class AndroidIdPlugin : FlutterPlugin, MethodCallHandler {
    /// The MethodChannel that will the communication between Flutter and native Android
    ///
    /// This local reference serves to register the plugin with the Flutter Engine and unregister it
    /// when the Flutter Engine is detached from the Activity
    private lateinit var channel: MethodChannel

    private lateinit var contentResolver: ContentResolver

    private lateinit var context: Context

    override fun onAttachedToEngine(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
        contentResolver = flutterPluginBinding.applicationContext.contentResolver
        channel = MethodChannel(flutterPluginBinding.binaryMessenger, "android_id")
        channel.setMethodCallHandler(this)
        context = flutterPluginBinding.getApplicationContext()
    }

    override fun onMethodCall(call: MethodCall, result: Result) {
        when (call.method) {
            "getId" -> {
                try {
                    result.success(getAndroidId())
                } catch (e: Exception) {
                    result.success("")
//                    result.error("ERROR_GETTING_ID", "Failed to get Android ID", e.localizedMessage)
                }
            }

            "getImei" -> {
                try {
                    result.success(getImei())
                } catch (e: Exception) {
                    result.success("")
//                    result.error("ERROR_GETTING_ID", "Failed to get Imei ", e.localizedMessage)
                }
            }

            "getMacAddress" -> {
                try {
                    result.success(getMacAddress())
                } catch (e: Exception) {
                    result.success("")
//                    result.error("ERROR_GETTING_ID", "Failed to get MacAddress", e.localizedMessage)
                }
            }

//            "getOaid" -> {
//                try {
//                    UMConfigure.getOaid(context) { p0 ->
//                        if (p0 != null) {
//                            result.success(p0)
//                        } else {
//                            result.success("")
//                        }
//                    }
//                } catch (e: Exception) {
//                    result.success("")
////                    result.error("ERROR_GETTING_ID", "Failed to get MacAddress", e.localizedMessage)
//                }
//            }

            "checkRoot" -> {
                try {
                    result.success(checkRoot())
                } catch (e: Exception) {
                    result.success(false)
//                    result.error("ERROR_GETTING_ID", "Failed to get MacAddress", e.localizedMessage)
                }
            }
            "checkIsEmulator" -> {
                try {
                    result.success(checkIsEmulator())
                } catch (e: Exception) {
                    result.success(false)
//                    result.error("ERROR_GETTING_ID", "Failed to get MacAddress", e.localizedMessage)
                }
            }

            else -> result.notImplemented()
        }
    }

    override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
        channel.setMethodCallHandler(null)
    }

    // Fetch the Android ID while suppressing lint warning about hardware IDs
    @SuppressLint("HardwareIds")
    private fun getAndroidId(): String {
        return Settings.Secure.getString(contentResolver, Settings.Secure.ANDROID_ID)
    }

    private fun getImei(): String? {
        val tm: TelephonyManager =
            context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
        var IMEIStr = ""
        if (ActivityCompat.checkSelfPermission(
                context,
                android.Manifest.permission.READ_PHONE_STATE
            ) !== PackageManager.PERMISSION_GRANTED
        ) {
        } else {
            try {
                IMEIStr = tm.getDeviceId()
                if (TextUtils.isEmpty(IMEIStr)) {
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                        IMEIStr = tm.getImei()
                    }
                }
            } catch (e: java.lang.Exception) {
            }
        }
        return IMEIStr
    }

    private fun getMacAddress(): String? {
        var macNo = MacUtil().getMac(context)
        return macNo
    }


    private fun checkRoot(): Boolean {
        return false
    }

    private fun checkIsEmulator(): Boolean {
        return false
    }

}

class MacUtil {
    /**
     * Android 6.0 之前（不包括6.0）获取mac地址
     * 必须的权限 <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
     *
     * @param context * @return
     */
    @SuppressLint("MissingPermission")
    fun getMacDefault(context: Context?): String? {
        var mac = ""
        if (context == null) {
            return mac
        }
        val wifi: WifiManager =
            context.getApplicationContext().getSystemService(Context.WIFI_SERVICE) as WifiManager
        var info: WifiInfo? = null
        try {
            info = wifi.getConnectionInfo()
        } catch (e: java.lang.Exception) {
            e.printStackTrace()
        }

        if (info == null) {
            return null
        }
        mac = info.getMacAddress()
        if (!TextUtils.isEmpty(mac)) {
            mac = mac.uppercase()
        }
        return mac
    }

    val macAddress: String?
        /**
         * Android 6.0-Android 7.0 获取mac地址
         */
        get() {
            var macSerial: String? = null
            var str = ""

            try {
                val pp: java.lang.Process =
                    java.lang.Runtime.getRuntime().exec("cat/sys/class/net/wlan0/address")
                val ir: InputStreamReader = InputStreamReader(pp.getInputStream())
                val input: LineNumberReader = LineNumberReader(ir)

                while (null != str) {
                    str = input.readLine()
                    if (str != null) {
                        macSerial = str.trim { it <= ' ' } //去空格
                        break
                    }
                }
            } catch (ex: IOException) {
                // 赋予默认值
                ex.printStackTrace()
            }

            return macSerial
        }

    /**
     * 获取mac地址（适配所有Android版本）
     *
     * @return
     */
    fun getMac(context: Context?): String? {
        var mac: String? = ""
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
            mac = getMacDefault(context)
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
            mac = macAddress
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            mac = macFromHardware
        }
        return mac
    }

    companion object {
        private val macFromHardware: String?
            /**
             * Android 7.0之后获取Mac地址
             * 遍历循环所有的网络接口，找到接口是 wlan0
             * 必须的权限 <uses-permission android:name="android.permission.INTERNET"></uses-permission>
             *
             * @return
             */
            get() {
                try {
                    val all: ArrayList<NetworkInterface> =
                        Collections.list<NetworkInterface>(NetworkInterface.getNetworkInterfaces())
                    for (nif in all) {
                        if (!nif.getName().equals("wlan0", ignoreCase = true)) {
                            continue
                        }

                        val macBytes: ByteArray = nif.getHardwareAddress() ?: return null

                        val res1: java.lang.StringBuilder = java.lang.StringBuilder()
                        for (b in macBytes) {
                            res1.append(String.format("%02X:", b))
                        }

                        if (res1.length > 0) {
                            res1.deleteCharAt(res1.length - 1)
                        }
                        return res1.toString()
                    }
                } catch (e: java.lang.Exception) {
                    e.printStackTrace()
                }
                return null
            }
    }
}
