package com.zxhyis.tools.ui.`fun`


import android.Manifest
import android.animation.Animator
import android.annotation.SuppressLint
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Build
import android.os.Environment
import android.provider.Settings
import android.text.format.Formatter
import android.view.View
import androidx.activity.OnBackPressedCallback
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import com.zxhyis.tools.R
import com.zxhyis.tools.base.TopActivity
import com.zxhyis.tools.databinding.ActivityJunkCleanBinding
import com.zxhyis.tools.logic.ChildBean
import com.zxhyis.tools.logic.Counts
import com.zxhyis.tools.logic.Logic
import com.zxhyis.tools.logic.ParentBean
import com.zxhyis.tools.logic.setOnClick
import com.zxhyis.tools.logic.showToast
import com.zxhyis.tools.logic.startActivity
import com.zxhyis.tools.logic.testLog
import com.zxhyis.tools.ui.adapter.CleanAdapter
import com.zxhyis.tools.ui.dialog.LoadingDialog
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import pokercc.android.expandablerecyclerview.ExpandableItemAnimator
import java.io.File

class JunkCleanActivity : TopActivity<ActivityJunkCleanBinding>() {

    private val parentList = ArrayList<ParentBean>()
    private val child = ArrayList<ChildBean>()
    private val child1 = ArrayList<ChildBean>()
    private val child2 = ArrayList<ChildBean>()
    private val newChild = ArrayList<ChildBean>()
    private val file1 = ArrayList<File>()
    private val file2 = ArrayList<File>()
    private var cacheSize = 0L
    private var unusefulApkSize = 0L
    private lateinit var cleanAdapter: CleanAdapter
    private var dialog: LoadingDialog? = null
    private var current = 0L
    private val result =
        registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {}


    override fun getViewBinding1(): ActivityJunkCleanBinding {
        return ActivityJunkCleanBinding.inflate(layoutInflater)
    }

    override fun init() {
        vb.inClean.tvTitle.text = getString(R.string.clean_up_garbage)
        vb.inClean.ivBack.setOnClick {
            finish()
        }
        vb.pb.progress = 100

        vb.tvSet.setOnClick {
            vb.tvSet.setBackgroundResource(R.drawable.bg_shape_set_click)
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
                result.launch(Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION))
            } else {
                ActivityCompat.requestPermissions(
                    this,
                    arrayOf(
                        Manifest.permission.WRITE_EXTERNAL_STORAGE,
                        Manifest.permission.READ_EXTERNAL_STORAGE
                    ), Counts.REQUEST_ALL_FILE
                )
            }
        }

        vb.btClean.setOnClick {
            vb.btClean.setBackgroundResource(R.drawable.bg_shape_set_click)
            if (isCanClean()){
                CoroutineScope(Dispatchers.IO).launch {
                    delay(500)
                    deepClean()
                    launch(Dispatchers.Main) {
                        updateUI()
                    }
                }
            }else{
                "Please select".showToast()
            }
        }

        vb.imageLoad.addAnimatorListener(object : Animator.AnimatorListener {
            override fun onAnimationStart(animation: Animator) {}

            override fun onAnimationEnd(animation: Animator) {
                lifecycleScope.launch {
                    delay(500)
                    var x=0L
                    for (file in file1){
                        x+=file.length()
                    }
                    for (file in file2){
                        x+=file.length()
                    }
                    startActivity<ResultActivity>("from" to "clean","clean_size" to x)
                    finish()
                }
            }

            override fun onAnimationCancel(animation: Animator) {}

            override fun onAnimationRepeat(animation: Animator) {}

        })


        onBackPressedDispatcher.addCallback(object : OnBackPressedCallback(true) {
            override fun handleOnBackPressed() {
                finish()
            }

        })

    }

    @SuppressLint("SetTextI18n")
    private fun initElv() {
        CoroutineScope(Dispatchers.IO).launch {
            delay(500)
            val cacheDir = cacheDir
            val fileList = cacheDir.listFiles()
            for (file in fileList!!) {
                child.add(
                    ChildBean(
                        R.drawable.ic_file,
                        file.name,
                        true,
                        file.length(),
                        file
                    )
                )
                file1.add(file)
                cacheSize += file.length()
            }
            findUselessApkFiles()
            parentList.apply {
                add(
                    ParentBean
                        (
                        title = "Cache garbage",
                        childItem = child,
                        parentSize = cacheSize,
                        isParentSelected = true,
                        expanded = true
                    )
                )

                add(
                    ParentBean
                        (
                        title = "Useless installation package",
                        childItem = child1,
                        parentSize = unusefulApkSize,
                        isParentSelected = true,
                        expanded = true
                    )
                )
                add(
                    ParentBean
                        (
                        title = "Uninstall residual",
                        childItem = child2,
                        parentSize = 0,
                        isParentSelected = false,
                        expanded = false
                    )
                )
            }
            cleanAdapter = CleanAdapter(parentList, this@JunkCleanActivity, object : Logic {
                override fun doLogic() {
                    updateSize()
                }
            })
            launch(Dispatchers.Main) {
                cleanAdapter.expandAllGroup()
                vb.erv.apply {
                    layoutManager = LinearLayoutManager(this@JunkCleanActivity)
                    adapter = cleanAdapter
                    itemAnimator = ExpandableItemAnimator(vb.erv, 500, true)
                }
                dialog?.dismiss()
                vb.allSize.text =
                    Formatter.formatFileSize(this@JunkCleanActivity, cacheSize + unusefulApkSize)
                vb.btClean.text="Clean up ${Formatter.formatFileSize(this@JunkCleanActivity, cacheSize + unusefulApkSize)}"
                current = cacheSize + unusefulApkSize
            }

        }
    }

    private fun isCanClean(): Boolean {
        return current > 0
    }

    private fun updateUI(){
        vb.imageLoad.visibility = View.VISIBLE
        vb.tvLoad.visibility = View.VISIBLE
        vb.imageLoad.playAnimation()
        vb.erv.visibility=View.GONE
        vb.btClean.visibility=View.GONE
    }

    private fun deepClean(){
        for (file in file1){
            if (file.isFile){
                file.delete()
            }
        }
        for (file in file2){
            file.delete()
        }
    }

    @SuppressLint("SetTextI18n")
    private fun updateSize() {
        var size = 0L
        newChild.clear()
        file1.clear()
        file2.clear()
        for (item in child) {
            if (item.isChildSelected) {
                newChild.add(item)
                file1.add(item.file)
            } else {
                newChild.remove(item)
                file1.remove(item.file)
            }
        }
        for (item in child1) {
            if (item.isChildSelected) {
                newChild.add(item)
                file2.add(item.file)
            } else {
                newChild.remove(item)
                file1.remove(item.file)
            }
        }
        for (data in newChild) {
            size += data.childSize
        }
        testLog("$size")

        vb.allSize.text = Formatter.formatFileSize(this, size)
        vb.btClean.text = "Clean up ${Formatter.formatFileSize(this, size)}"
        vb.pb.progress = (size.toFloat() / current * 100).toInt()

    }

    private fun getApk(): List<File> {
        val apkFiles = mutableListOf<File>()
        val directory = File("/storage/emulated/0")
        if (directory.exists() && directory.isDirectory) {
            val files = directory.listFiles()//  /storage/emulated/0
            if (files != null) {
                for (file in files) {
                    if (file.exists() && file.isDirectory) {
                        for (app in file.absoluteFile.listFiles()!!) {
                            if (app.isFile && app.name.endsWith(".apk")) {
                                apkFiles.add(app)
                            }
                        }
                    }
                }
            }
        }
        return apkFiles
    }

    private fun findUselessApkFiles(): List<File> {
        val uselessApkFiles = mutableListOf<File>()
        val apkFiles = getApk()
        val pm = packageManager
        val installedPackages = pm.getInstalledPackages(0)
        for (apkFile in apkFiles) {
            var isUseless = true
            for (packageInfo in installedPackages) {
                val packagePath = packageInfo.applicationInfo.sourceDir
                if (apkFile.absolutePath == packagePath) {
                    isUseless = false
                    break
                }
            }
            if (isUseless) {
                uselessApkFiles.add(apkFile)
                child1.add(
                    ChildBean(
                        R.drawable.home_apk,
                        apkFile.name,
                        true,
                        apkFile.length(),
                        apkFile
                    )
                )
                file2.add(apkFile)
                unusefulApkSize += apkFile.length()
            }
        }
        return uselessApkFiles
    }

    override fun onResume() {
        super.onResume()
        cacheSize = 0L
        unusefulApkSize = 0L
        current = 0L
        parentList.clear()
        child.clear()
        child1.clear()
        child2.clear()
        file1.clear()
        file2.clear()

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            if (Environment.isExternalStorageManager()) {
                vb.apply {
                    imagePer.visibility = View.GONE
                    tvDes.visibility = View.GONE
                    tvSet.visibility = View.GONE
                    clTop.visibility = View.VISIBLE
                    allSize.visibility = View.VISIBLE
                    erv.visibility = View.VISIBLE
                    btClean.visibility = View.VISIBLE
                    btClean.setBackgroundResource(R.drawable.bg_shape_set)
                    tvSet.setBackgroundResource(R.drawable.bg_shape_set)
                }
                initElv()
                dialog = LoadingDialog()
                dialog?.isCancelable = false
                dialog?.showNow(supportFragmentManager, "loading")
            } else {
                vb.apply {
                    imagePer.visibility = View.VISIBLE
                    tvDes.visibility = View.VISIBLE
                    tvSet.visibility = View.VISIBLE
                    clTop.visibility = View.GONE
                    erv.visibility = View.GONE
                    btClean.visibility = View.GONE
                }
            }
        } else {
            if (ContextCompat.checkSelfPermission(
                    this,
                    Manifest.permission.WRITE_EXTERNAL_STORAGE
                ) != PackageManager.PERMISSION_GRANTED
            ) {
                vb.apply {
                    imagePer.visibility = View.VISIBLE
                    tvDes.visibility = View.VISIBLE
                    tvSet.visibility = View.VISIBLE
                    clTop.visibility = View.GONE
                    erv.visibility = View.GONE
                    btClean.visibility = View.GONE
                }
            } else {
                vb.apply {
                    imagePer.visibility = View.GONE
                    tvDes.visibility = View.GONE
                    tvSet.visibility = View.GONE
                    clTop.visibility = View.VISIBLE
                    allSize.visibility = View.VISIBLE
                    erv.visibility = View.VISIBLE
                    btClean.visibility = View.VISIBLE
                    btClean.setBackgroundResource(R.drawable.bg_shape_set)
                    tvSet.setBackgroundResource(R.drawable.bg_shape_set)
                }
                initElv()
                dialog = LoadingDialog()
                dialog?.isCancelable = false
                dialog?.showNow(supportFragmentManager, "loading")
            }
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        cacheSize = 0L
        unusefulApkSize = 0L
        current = 0L
        parentList.clear()
        child.clear()
        child1.clear()
        child2.clear()
        file1.clear()
        file2.clear()
    }


}