package com.base.easyfilemanager.activity

import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.net.ConnectivityManager
import android.net.wifi.WifiManager
import android.os.Build
import android.os.Environment
import android.os.StatFs
import androidx.activity.addCallback
import com.base.easyfilemanager.databinding.ActivityDeviceScanInfoBinding
import com.base.easyfilemanager.helps.BaseActivity
import com.base.easyfilemanager.helps.KotlinExt.toFormatSize
import com.base.easyfilemanager.helps.LogEx
import com.base.easyfilemanager.helps.ads.AdmobUtils
import com.base.easyfilemanager.utils.DeviceUtils
import com.base.easyfilemanager.view.AFunOb
import com.base.easyfilemanager.view.AdPreparationPop
import java.io.BufferedReader
import java.io.File
import java.io.FileReader
import java.io.IOException
import java.nio.file.Files
import java.nio.file.Paths
import java.util.Locale

class DeviceScanInfoActivity : BaseActivity<ActivityDeviceScanInfoBinding>() {

    private val TAG = "DeviceScanActivity"
    override val binding: ActivityDeviceScanInfoBinding by lazy {
        ActivityDeviceScanInfoBinding.inflate(layoutInflater)
    }


    @SuppressLint("SetTextI18n")
    override fun initView() {
        AdPreparationPop(this) {
            AdmobUtils.showInterstitialAd(this) {
                binding.tvDeviceName.text = getDeviceName()
                binding.tvAndroidVersion.text = "System Version: Android ${Build.VERSION.RELEASE}"
                binding.tvAbis.text = DeviceUtils.getABIs().toStringEx()
                val cupInfo = cpuInfo()
                cupInfo.forEach {
                    LogEx.logDebug(TAG, "cupInfo   $it")
                }
                binding.tvCpuCores.text = cupInfo.find { it.contains("CPU architecture") }?.split(":")?.get(1)
                binding.tvIpAddress.text = if (isWifiConnected(this)) getWifiIpAddress(this) else ""
                binding.tvSsid.text = getWifiSSID(this)
                binding.tvLinkSpeed.text = "${getWifiLinkSpeed(this)} Mbps"
                binding.tvCpuFrequency.text =
                    "${getCpuFreq("cpuinfo_min_freq") / 1000}MHZ - ${getCpuFreq("cpuinfo_max_freq") / 1000}MHZ"
                binding.tvCpuHardware.text = getCpuHardware()
            }
        }.show()
    }

    override fun initListener() {
        binding.tvOk.setOnClickListener {
            startActivity(Intent(this, ResultActivity::class.java).apply {
                putExtra("from", AFunOb.DEVICE_SCAN)
            })
            finish()
        }
        binding.flBack.setOnClickListener {
            onBackPressedDispatcher.onBackPressed()
        }
        onBackPressedDispatcher.addCallback {
            AdmobUtils.showInterstitialAd(this@DeviceScanInfoActivity) {
                finishToMain()
            }
        }
    }


    private fun capitalize(str: String?): String? {
        return if (str.isNullOrEmpty()) {
            str
        } else str.substring(0, 1).uppercase(Locale.getDefault()) + str.substring(1).lowercase(Locale.getDefault())
    }

    fun getDeviceName(): String? {
        val manufacturer = Build.MANUFACTURER
        val model = Build.MODEL
        return if (model.lowercase(Locale.getDefault()).startsWith(manufacturer.lowercase(Locale.getDefault()))) {
            capitalize(model)
        } else capitalize(manufacturer) + " " + model
    }

    private fun cpuInfo(): ArrayList<String> {
        val cpuList: ArrayList<String> = arrayListOf()
        try {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                val cpuInfo = String(Files.readAllBytes(Paths.get("/proc/cpuinfo")))
                LogEx.logDebug(TAG, "$cpuInfo")
                val arrays = cpuInfo.split("\n")
                cpuList.addAll(arrays)
            }
        } catch (e: IOException) {
            e.printStackTrace()
        }
        return cpuList
    }

    fun isWifiConnected(context: Context): Boolean {
        val connectivityManager = context.getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager
        val networkInfo = connectivityManager.activeNetworkInfo

        // 检查networkInfo是否为null以及是否连接到Wi-Fi
        return networkInfo != null && networkInfo.type == ConnectivityManager.TYPE_WIFI
    }

    fun getWifiIpAddress(context: Context): String {
        val wifiManager = context.getSystemService(WIFI_SERVICE) as WifiManager
        val wifiInfo = wifiManager.connectionInfo
        val ip = wifiInfo.ipAddress
        return if (ip == 0) {
            "No network connection"
        } else (ip and 0xff).toString() + "." + (ip shr 8 and 0xff) + "." + (ip shr 16 and 0xff) + "." + (ip shr 24 and 0xff)
    }

    fun getMobileIpAddress(context: Context): String {
        val connectivityManager = context.getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager
        val activeNetwork = connectivityManager.activeNetworkInfo
        return if (activeNetwork != null && activeNetwork.isConnected) {
            activeNetwork.extraInfo.toString().split(" ".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()[1].trim { it <= ' ' }
        } else "No network connection"
    }

    fun getWifiSSID(context: Context): String? {
        val wifiManager = context.getSystemService(WIFI_SERVICE) as WifiManager
        val wifiInfo = wifiManager.connectionInfo
        if (wifiInfo != null) {
            val ssid = wifiInfo.ssid
            // 移除SSID周围的双引号
            return if (ssid != null && ssid.isNotEmpty()) ssid.replace("\"".toRegex(), "") else null
        }
        return "<unknown ssid>"
    }

    /**
     * 获取当前Wi-Fi连接的链路速度。
     *
     * @param context Android上下文对象。
     * @return 链路速度，单位为Mbps。如果没有连接到Wi-Fi或无法获取，则返回-1。
     */
    fun getWifiLinkSpeed(context: Context): Int {
        val wifiManager = context.getSystemService(WIFI_SERVICE) as WifiManager
        val wifiInfo = wifiManager.connectionInfo
        // 获取Wi-Fi链路速度，单位为Mbps
        return wifiInfo?.linkSpeed ?: -1
    }


    /**
     * @param filePath
     * cpuinfo_cur_freq
     * cpuinfo_min_freq
     * cpuinfo_max_freq
     * scaling_available_frequencies
     *
     * @return 返回数据 546000KHZ=546MHZ
     */
    fun getCpuFreq(filePath: String): Int {
        val scalingPath = "/sys/devices/system/cpu/cpu0/cpufreq/"
        val path = File(scalingPath + filePath)
        var frequency = 0
        try {
            if (path.exists()) {
                val reader = BufferedReader(FileReader(path))
                val line = reader.readLine()
                reader.close()
                if (line != null) {
                    // 处理读取到的频率值
                    LogEx.logDebug("CPU Frequency", "$filePath: $line kHz")
                    frequency = line.toInt()
                }
            }
        } catch (e: IOException) {
            e.printStackTrace()
        }
        return frequency
    }

    @SuppressLint("PrivateApi")
    fun getCpuHardware(): String {
        val classType = Class.forName("android.os.SystemProperties")
        val method = classType.getDeclaredMethod("get", String::class.java)
        val result = method.invoke(classType, "ro.board.platform") as String
        return result
    }

    private fun <T> Array<T>.toStringEx(): String {

        val sb = StringBuffer()
        sb.append("[")
        forEachIndexed { index, t ->
            if (index == size - 1) {
                sb.append("$t")
            } else {
                sb.append("$t").append(",")
            }
        }
        sb.append("]")
        return sb.toString()
    }
}