package com.test.basd.smartjunkcleaner.activity

import android.annotation.SuppressLint
import android.app.AppOpsManager
import android.app.usage.NetworkStats
import android.app.usage.NetworkStatsManager
import android.content.Context
import android.graphics.Color
import android.net.ConnectivityManager
import android.os.Build
import android.util.SparseLongArray
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.ProgressBar
import android.widget.TextView
import androidx.activity.OnBackPressedCallback
import androidx.core.util.forEach
import androidx.core.view.isVisible
import androidx.core.view.updatePadding
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.blankj.utilcode.util.AppUtils
import com.blankj.utilcode.util.BarUtils
import com.test.basd.smartjunkcleaner.R
import com.test.basd.smartjunkcleaner.bean.TrafficBean
import com.test.basd.smartjunkcleaner.databinding.ActivityLayoutNetworkBinding
import com.test.basd.smartjunkcleaner.helps.BaseActivity
import com.test.basd.smartjunkcleaner.helps.ConfigHelper
import com.test.basd.smartjunkcleaner.helps.KotlinExt.toFormatSize
import com.test.basd.smartjunkcleaner.helps.NetworkStatsHelper
import com.test.basd.smartjunkcleaner.helps.ads.AdmobUtils
import com.test.basd.smartjunkcleaner.view.DialogViews
import kotlin.random.Random


class NetWorkActivity : BaseActivity<ActivityLayoutNetworkBinding>() {


    private val wifiList = mutableListOf<TrafficBean>()
    private val mobileList = mutableListOf<TrafficBean>()
    private val AllList = mutableListOf<TrafficBean>()

    private var startTime = NetworkStatsHelper.getTimesMonthmorning()
    private var types = 2
    private var ifPlayAnimal = false
    override fun onStart() {
        super.onStart()
        if (ifPlayAnimal) {
            hasAccessSettings()
        }
    }

    private fun hasAccessSettings() {
        val appOpsManager = getSystemService(Context.APP_OPS_SERVICE) as AppOpsManager
        if (
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                appOpsManager.unsafeCheckOpNoThrow(
                    AppOpsManager.OPSTR_GET_USAGE_STATS,
                    android.os.Process.myUid(),
                    this.packageName
                ) == AppOpsManager.MODE_ALLOWED
            } else {
                appOpsManager.checkOpNoThrow(
                    AppOpsManager.OPSTR_GET_USAGE_STATS,
                    android.os.Process.myUid(),
                    this.packageName
                ) == AppOpsManager.MODE_ALLOWED
            }
        ) {
            binding.idLlNoAccpermion.isVisible = false
            initList()
        } else {
            binding.idLlNoAccpermion.isVisible = true
        }
    }

    private fun playLottie() {
        binding.idLlNetDh.isVisible = true
        binding.idLottieNetwork.imageAssetsFolder = "wan_sjunk_luo/images/"
        binding.idLottieNetwork.setAnimation("wan_sjunk_luo/data.json")
        binding.idLottieNetwork.playAnimation()
        binding.root.postDelayed({
            AdmobUtils.showInterstitialAd(this) {
                binding.idLlNetDh.isVisible = false
                ifPlayAnimal = true
                hasAccessSettings()
            }
        }, Random.nextLong(2500, 4000))
    }


    override val binding: ActivityLayoutNetworkBinding by lazy {
        ActivityLayoutNetworkBinding.inflate(layoutInflater)
    }

    override fun initView() {
        BarUtils.setStatusBarLightMode(this, true)
        BarUtils.setStatusBarColor(this, Color.TRANSPARENT)
        binding.root.updatePadding(top = BarUtils.getStatusBarHeight())
        binding.idTvThisMonth.isSelected = true
        playLottie()
    }

    override fun initListener() {

        binding.idBackNetwork.setOnClickListener {
            onBackPressedDispatcher.onBackPressed()
        }
        onBackPressedDispatcher.addCallback(object : OnBackPressedCallback(true) {
            override fun handleOnBackPressed() {
                AdmobUtils.showInterstitialAd(this@NetWorkActivity) {
                    finishToMain()
                }
            }

        })
        binding.idGant.setOnClickListener {
            checkAccesSettings(true)
        }
        binding.idTvThisMonth.setOnClickListener {
            clickTop(0)
            startTime = NetworkStatsHelper.getTimesMonthmorning()
            setData()
        }
        binding.id30Day.setOnClickListener {
            clickTop(1)
            startTime = NetworkStatsHelper.getNeedTime(30)
            setData()
        }
        binding.id24Hours.setOnClickListener {
            clickTop(2)
            startTime = NetworkStatsHelper.getNeedTime(1)
            setData()
        }
        binding.idTvTypes.setOnClickListener {
            DialogViews.showBothTypes(this) {
                when (it) {
                    0 -> {
                        binding.idTvTypes.text = "Mobile Network"
                        types = 0
                    }

                    1 -> {
                        binding.idTvTypes.text = "Wi-Fi"
                        types = 1

                    }

                    2 -> {
                        binding.idTvTypes.text = "Both types"
                        types = 2
                    }
                }
                setData()
            }
        }
    }

    private fun clickTop(p: Int) {
        listOf(binding.idTvThisMonth, binding.id30Day, binding.id24Hours).forEachIndexed { index, view ->
            view.isSelected = p == index
        }

    }

    private fun initList() {


        setData()
        // setMobileData(allMobide)
    }

    private fun setData(
    ) {

        val allMobide = getNetworkStats(
            ConnectivityManager.TYPE_MOBILE,
            startTime,
            System.currentTimeMillis()
        )
        val allWifi = getNetworkStats(
            ConnectivityManager.TYPE_WIFI,
            startTime, System.currentTimeMillis()
        )
        AllList.clear()
        mobileList.clear()
        wifiList.clear()
        var mobileSize = 0L
        allMobide.forEach { key, value ->
            mobileSize += value
            val appPkg = packageManager.getPackagesForUid(key)
            if (appPkg?.isNotEmpty() == true) {
                val bean = TrafficBean(1, appPkg[0], 0, value)
                mobileList.add(bean)
            }
        }
        mobileList.sortByDescending { it.mobileUsed }
        binding.idMobileLiuliang.text = mobileSize.toFormatSize()
        var wifi = 0L
        allWifi.forEach { key, value ->
            wifi += value
            val appPkg = packageManager.getPackagesForUid(key)
            if (appPkg?.isNotEmpty() == true) {
                val bean = TrafficBean(2, appPkg[0], value, 0)
                wifiList.add(bean)
            }
        }
        binding.idWifiLiuliang.text = wifi.toFormatSize()
        wifiList.sortByDescending { it.wifiUsed }

//        mobileList.addAll(wifiList)
//        AllList.addAll(mobileList)
        val map = hashMapOf<String, TrafficBean>()
        if (types != 0) {
            for (bean in wifiList) {
                map[bean.packageName] = bean
            }
        }
        if (types != 1) {
            for (bean in mobileList) {
                if (map.containsKey(bean.packageName)) {
                    val oldBean = map[bean.packageName]
                    oldBean?.type = oldBean?.type?.plus(bean.type) ?: bean.type
                    oldBean?.mobileUsed =
                        oldBean?.mobileUsed?.plus(bean.mobileUsed) ?: bean.mobileUsed
                    oldBean?.wifiUsed = oldBean?.wifiUsed?.plus(bean.wifiUsed) ?: bean.wifiUsed
                } else {
                    map[bean.packageName] = bean
                }
            }
        }
        for (value in map.values) {
            AllList.add(value)
        }
        AllList.sortByDescending { it.mobileUsed + it.wifiUsed }
        AllList.removeAll(AllList.filter {
            it.packageName == this.packageName
        })
        // AllList.sortByDescending { it.wifiUsed }
        // Log.e("MXL", "所有的数据: " + AllList.size + AllList.toString())
        if (AllList.isNotEmpty()) {
            binding.idTvNoData.isVisible = false
            binding.idRlNetworkTra.run {
                layoutManager = LinearLayoutManager(context)
                adapter = mAdapter
            }
        } else {
            mAdapter.notifyDataSetChanged()
            binding.idTvNoData.isVisible = true
        }

    }


    fun getNetworkStats(uid: Int, start: Long, end: Long): SparseLongArray {
        val result = SparseLongArray()
        val bucket = NetworkStats.Bucket()
        try {
            val manager =
                this.getSystemService(Context.NETWORK_STATS_SERVICE) as NetworkStatsManager
            val stats = manager.querySummary(uid, null, start, end)
            while (stats.hasNextBucket()) {
                stats.getNextBucket(bucket)
                val currentUid = bucket.uid
                val txBytes = bucket.txBytes
                val rxBytes = bucket.rxBytes
                val totalBytes = txBytes + rxBytes
                val existingBytes = result[currentUid, 0]
                if (existingBytes == 0L) {
                    result.put(currentUid, totalBytes)
                } else {
                    result.put(currentUid, totalBytes + existingBytes)
                }
            }
            var b = 0L
            result.forEach { key, value ->
                val a = packageManager.getPackagesForUid(key)
                if (a?.isNotEmpty() == true) {
                    b += value
                }
            }
            stats.close()
        } catch (_: Exception) {
        }
        return result
    }

    private val mAdapter by lazy {
        class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
            val ivImage: ImageView
            val tvName: TextView
            val tvTraffic: TextView
            val wifiPro: ProgressBar
            val mobilePro: ProgressBar
            val tvstop: TextView

            init {
                ivImage = view.findViewById(R.id.id_icon)
                tvName = view.findViewById(R.id.id_name)
                tvTraffic = view.findViewById(R.id.id_tra_used)
                wifiPro = view.findViewById(R.id.id_wifi_pro)
                mobilePro = view.findViewById(R.id.id_mobile_pro)
                tvstop = view.findViewById(R.id.id_tv_stop)
            }
        }

        object : RecyclerView.Adapter<ViewHolder>() {
            override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
                val view = LayoutInflater.from(this@NetWorkActivity).inflate(
                    R.layout.item_app_used_traffic, parent, false
                )
                return ViewHolder(view)
            }

            override fun getItemCount() = AllList.size

            @SuppressLint("SetTextI18n")
            override fun onBindViewHolder(holder: ViewHolder, position: Int) {
                val c = ConfigHelper.appList?.firstOrNull {
                    it.packageName == AllList[position].packageName
                }
                holder.ivImage.setImageDrawable(c?.icon)
                holder.tvName.text = c?.name
                holder.tvTraffic.text =
                    (AllList[position].wifiUsed + AllList[position].mobileUsed).toFormatSize()

                holder.wifiPro.max = (AllList[0].wifiUsed + AllList[0].mobileUsed).toInt()
                holder.mobilePro.max = (AllList[0].wifiUsed + AllList[0].mobileUsed).toInt()
                holder.wifiPro.progress =
                    (AllList[position].wifiUsed + AllList[position].mobileUsed).toInt()
                holder.mobilePro.progress = (AllList[position].mobileUsed).toInt()
                holder.tvstop.isEnabled =
                    NetworkStatsHelper.canStop(this@NetWorkActivity, AllList[position].packageName)
                holder.tvstop.setOnClickListener {
                    AppUtils.launchAppDetailsSettings(AllList[position].packageName)
                }
                holder.itemView.setOnClickListener {

                }

            }

            override fun onBindViewHolder(
                holder: ViewHolder,
                position: Int,
                payloads: MutableList<Any>
            ) {
                super.onBindViewHolder(holder, position, payloads)
            }
        }
    }
}