package com.base.scanqrclear.luma

import android.animation.ValueAnimator
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.view.View
import android.view.animation.LinearInterpolator
import androidx.activity.addCallback
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import com.base.scanqrclear.R
import com.base.scanqrclear.bean.FileBean
import com.base.scanqrclear.bean.config.AdConfigBean
import com.base.scanqrclear.databinding.ActivityCleanJunkBinding
import com.base.scanqrclear.luma.AdmobHelps.KEY_CLEANUP_SIZE
import com.base.scanqrclear.luma.AdmobHelps.KEY_CLEAN_LAST_TIME
import com.base.scanqrclear.luma.Utils.toDate
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import pokercc.android.expandablerecyclerview.ExpandableItemAnimator
import java.util.Locale
import kotlin.random.Random

class CleanJunkActivity : BaseActivity2() {

    companion object {
        fun start(context: Context) {
            val intent = Intent(context, CleanJunkActivity::class.java)
            context.startActivity(intent)
        }
    }

    private val binding by lazy(LazyThreadSafetyMode.NONE) {
        ActivityCleanJunkBinding.inflate(layoutInflater)
    }

    private lateinit var adapter: CleanJunkAdapter
    private var total: Long = 0

    private var groupData = mutableListOf<FileBean>()
    private var childData = mutableListOf<List<FileBean>>()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(binding.root)
        initView()
        showAdInterstitial(AdConfigBean.adsConfigBean.functionInShowAd) { initData() }
        onBackPressedDispatcher.addCallback {
            handleBackPressed(this@CleanJunkActivity)
        }
    }

    private fun initView() {
        adapter = CleanJunkAdapter()
        adapter.selectionData.observe(this) { list ->
            total = list.filter { it.isSelected }.sumOf { it.length }
            setClean()
        }
        binding.expandableFiles.adapter = adapter
        binding.expandableFiles.layoutManager = LinearLayoutManager(this)
        binding.expandableFiles.itemAnimator = ExpandableItemAnimator(binding.expandableFiles)
        binding.flBack.setOnClickListener { backPressed() }
        binding.tvClean.setOnClickListener {
            if (isDisableBack) return@setOnClickListener
            showAnimationAd(LottieType.CLEAN, total > 0) {
                if (total > 0) SpUtils.getInstance().putInt("${KEY_CLEANUP_SIZE}_${toDate()}", 1)
                SpUtils.getInstance().putLong(KEY_CLEAN_LAST_TIME, System.currentTimeMillis())
                toCleanResult(total, getString(R.string.junk_scan))
            }
            cleanFiles(adapter.child.flatten())
        }
    }

    private fun initData() {
        binding.tvPath.text = ""
        binding.tvClean.visibility = View.GONE
        isDisableBack = true
        lifecycleScope.launch(Dispatchers.IO) {
            val emptyFoldersDeferred = async { FileHelps.findEmptyFolders(lifecycleScope) }
            val filesDeferred = async { MediaHelps.findSpecifiedFiles(this@CleanJunkActivity) }
            val emptyFolder = emptyFoldersDeferred.await()
            val files = filesDeferred.await()
            emptyFolder.forEach { it.isSelected = true }
            files.forEach { it.isSelected = true }
            val apkFiles = files.filter {
                it.name.lowercase(Locale.ROOT).endsWith(".apk") || it.name.lowercase(Locale.ROOT).endsWith(".aab")
            }
            val tempFiles = files.filter { it.name.lowercase(Locale.ROOT).endsWith(".temp") }
            val logsFiles = files.filter { it.name.lowercase(Locale.ROOT).endsWith(".log") }
            groupData = getGroupData()
            groupData[0].length = emptyFolder.sumOf { it.length }
            groupData[1].length = apkFiles.sumOf { it.length }
            groupData[2].length = tempFiles.sumOf { it.length }
            groupData[3].length = logsFiles.sumOf { it.length }
            total = groupData.sumOf { it.length }
            childData = mutableListOf<List<FileBean>>().apply {
                add(emptyFolder)
                add(apkFiles)
                add(tempFiles)
                add(logsFiles)
            }
            showScan()
        }
    }

    private fun showScan() {
        lifecycleScope.launch(Dispatchers.IO) {
            val list = childData.flatten().sortedByDescending { it.length }
            val totalSize = list.sumOf { it.length }
            val random = Random.nextLong(2500, 3000)
            withContext(Dispatchers.Main) {
                AnimationHelps.progress(binding.pbProgress, 0, 100, random)
                ValueAnimator.ofFloat(0f, totalSize.toFloat()).apply {
                    duration = random
                    interpolator = LinearInterpolator()
                    addUpdateListener { animation ->
                        val value = animation.animatedValue as Float
                        setSize(value.toLong())
                    }
                }.start()
            }
            for (index in list.indices) {
                if (binding.pbProgress.progress == 100) break
                withContext(Dispatchers.Main) {
                    if (list.size > index) {
                        binding.tvPath.text = list[index].path
                    }
                }
            }
            delay(random)
            withContext(Dispatchers.Main) {
                scanComplete()
                adapter.setData(groupData, childData)
            }
        }
    }

    private fun setSize(size: Long) {
        val values = Utils.getSizeArray(size)
        binding.tvLength.text = values[0]
        binding.tvUnit.text = values[1]
    }

    private fun scanComplete() {
        isDisableBack = false
        binding.expandableFiles.visibility = View.VISIBLE
        binding.tvClean.visibility = View.VISIBLE
        binding.tvPath.text = getString(R.string.clean_tips)
        setClean()
    }

    private fun setClean() {
        binding.tvClean.text = if (total > 0) "${getString(R.string.clean)} (${Utils.getSize(total)})" else getString(R.string.go_it)
        binding.tvClean.setBackgroundResource(if (total > 0) R.drawable.gradient else R.drawable.gradient_unselected)
    }

    private fun getGroupData(): MutableList<FileBean> {
        return mutableListOf<FileBean>().apply {
            add(FileBean(getString(R.string.empty_folder), icon = R.mipmap.icon_empty_junk_nor, isSelected = true))
            add(FileBean(getString(R.string.apk_files), icon = R.mipmap.icon_apk_junk_nor, isSelected = true))
            add(FileBean(getString(R.string.temp_files), icon = R.mipmap.icon_temp_junk_nor, isSelected = true))
            add(FileBean(getString(R.string.logs_files), icon = R.mipmap.icon_logs_junk_nor, isSelected = true))
        }
    }
}