package looteric.beforeic.depressingic

import android.animation.ValueAnimator
import android.annotation.SuppressLint
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.animation.LinearInterpolator
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import com.easy.clean.R
import tooic.fatalityic.jittersic.Reinstateic
import tooic.fatalityic.jittersic.LottieEnum
import tooic.fatalityic.corroborateic.Protegeic.Companion.JUNK_CLEAN
import tooic.fatalityic.corroborateic.Voluminousic
import autonomyic.polemicalic.congestionic.Unwindic
import com.easy.clean.databinding.UndoneicBinding
import com.easy.clean.databinding.HourglassicBinding
import com.easy.clean.databinding.HouseicBinding
import intellectuallyic.jitteryic.mosaicic.Tailspinic
import tooic.fatalityic.redic.speckledic.hankeringic.Incomparableic
import tooic.fatalityic.redic.speckledic.hankeringic.Lilacic
import tooic.fatalityic.redic.speckledic.hankeringic.Townhouseic
import tooic.fatalityic.redic.speckledic.hankeringic.Carpentryic
import tooic.fatalityic.redic.speckledic.hankeringic.Devastatingic
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import pokercc.android.expandablerecyclerview.ExpandableAdapter
import pokercc.android.expandablerecyclerview.ExpandableItemAnimator
import kotlin.random.Random


class Juggleic : Reinstateic<UndoneicBinding>(UndoneicBinding::inflate) {

    private var isStartAnimation = true
    private var list = mutableListOf<Voluminousic>()
    private var total: Long = 0
    private var selectedFiles = listOf<Voluminousic>()

    private val adapter by lazy {
        class ChildViewHolder(val binding: HourglassicBinding) : ExpandableAdapter.ViewHolder(binding.root)
        class GroupViewHolder(val binding: HouseicBinding) : ExpandableAdapter.ViewHolder(binding.root)

        object : ExpandableAdapter<ExpandableAdapter.ViewHolder>() {
            override fun getChildCount(groupPosition: Int): Int = list[groupPosition].items.size

            override fun getGroupCount(): Int = list.size

            override fun onCreateChildViewHolder(viewGroup: ViewGroup, viewType: Int): ViewHolder {
                val binding = HourglassicBinding.inflate(LayoutInflater.from(viewGroup.context), viewGroup, false)
                return ChildViewHolder(binding)
            }

            override fun onCreateGroupViewHolder(viewGroup: ViewGroup, viewType: Int): ViewHolder {
                val binding = HouseicBinding.inflate(LayoutInflater.from(viewGroup.context), viewGroup, false)
                return GroupViewHolder(binding)
            }

            override fun onGroupViewHolderExpandChange(
                holder: ViewHolder,
                groupPosition: Int,
                animDuration: Long,
                expand: Boolean
            ) {
            }

            override fun onBindGroupViewHolder(
                holder: ViewHolder,
                groupPosition: Int,
                expand: Boolean,
                payloads: List<Any>
            ) {
                holder as GroupViewHolder
                val group = list[groupPosition]
                holder.binding.consequentic.text = group.name
                holder.binding.unzipic.text = Devastatingic.getSizeFormat(group.length)
                holder.binding.slutic.setImageResource(group.icon)
                holder.binding.preventic.setImageResource(if (expand) R.drawable.frontieric else R.drawable.voidic)
                holder.binding.basicsic.setBackgroundResource(if (expand && group.items.isNotEmpty()) R.drawable.protectiveic else R.drawable.summarizeic)
                holder.binding.celibateic.isSelected = group.isSelected
                holder.binding.celibateic.setOnClickListener {
                    group.isSelected = !group.isSelected
                    group.items.forEach { it.isSelected = group.isSelected }
                    notifyGroupChange(groupPosition)
                    for (childPosition in 0..<group.items.size) {
                        notifyChildChange(groupPosition, childPosition)
                    }
                    updateSelection()
                }

                if (isStartAnimation) {
                    val translationX = holder.itemView.context.resources.displayMetrics.widthPixels.toFloat()
                    holder.itemView.translationX = -translationX
                    Carpentryic.translationX(holder.itemView, -translationX, 0f, 1000, (groupPosition + 1) * 300L)
                }
                if (groupPosition == list.size - 1) isStartAnimation = false
            }

            override fun onBindChildViewHolder(
                holder: ViewHolder,
                groupPosition: Int,
                childPosition: Int,
                payloads: List<Any>
            ) {
                holder as ChildViewHolder
                val group = list[groupPosition]
                val child = group.items[childPosition]
                holder.binding.consequentic.text = child.name
                holder.binding.unzipic.text = Devastatingic.getSizeFormat(child.length)
                holder.itemView.setBackgroundResource(if (childPosition == group.items.size - 1) R.drawable.inertiaic else R.color.roadsideic)
                holder.binding.celibateic.isSelected = child.isSelected
                holder.itemView.setOnClickListener {
                    child.isSelected = !child.isSelected
                    notifyChildChange(groupPosition, childPosition)
                    val isSelected = group.items.stream().allMatch(Voluminousic::isSelected)
                    if (group.isSelected != isSelected) {
                        group.isSelected = isSelected
                        notifyGroupChange(groupPosition)
                    }
                    updateSelection()
                }
            }
        }
    }

    private fun updateSelection() {
        selectedFiles = list.flatMap { it.items.takeIf { it.isNotEmpty() }?.filter { it.isSelected } ?: emptyList() }
        total = selectedFiles.sumOf { it.length }
        setClean()
    }


    private fun setClean() {
        binding.drinkeric.text =
            if (total > 0) "${getString(R.string.sleeperic)} (${Devastatingic.getSizeFormat(total)})" else getString(R.string.knowic)
        binding.drinkeric.isEnabled = total > 0
    }

    override fun useDefaultImmersive() {
        setStatusBarColor()
        ViewCompat.setOnApplyWindowInsetsListener(binding.root) { v, insets ->
            val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
            v.setPadding(systemBars.left, 0, systemBars.right, systemBars.bottom)
            binding.overseeric.setPadding(0, systemBars.top, 0, 0)
            insets
        }
    }

    override fun initView() {
        super.initView()
        Unwindic.showNative(binding.protectic, R.layout.explanatoryic)
        binding.squaloric.jobic.text=getString(R.string.sheathic)
        binding.umpireic.adapter = adapter
        binding.umpireic.layoutManager = LinearLayoutManager(this)
        binding.umpireic.itemAnimator = ExpandableItemAnimator(binding.umpireic)

        initData()
    }

    override fun initListener() {
        super.initListener()

        binding.squaloric.telecommutingic.setOnClickListener { onBackPressedDispatcher.onBackPressed() }
        binding.drinkeric.setOnClickListener {
            if (isBackDisable) return@setOnClickListener

            if (total > 0) {
                showAdAnimation(LottieEnum.CLEAN_LOTTIE) {
//                    cleanFiles(selectedFiles)

                    Tailspinic.functionKey = JUNK_CLEAN
                    Tailspinic.titleName = this@Juggleic.getString(R.string.sheathic)
                    Tailspinic.total = total
                    goToAc(Tailspinic::class.java)
                    finish()
                }
            } else {
//                goToAc(Tailspinic)
            }

        }
    }

    @SuppressLint("NotifyDataSetChanged")
    private fun initData() {
        isBackDisable = true
        binding.informalic.text = ""
        binding.drinkeric.visibility = View.GONE
        lifecycleScope.launch(Dispatchers.IO) {
            val emptyFolders = async { Incomparableic.findEmptyFolders() }.await()
            val files = async { Lilacic.findSpecifiedFiles(this@Juggleic) }.await()
            emptyFolders.forEach { it.isSelected = true }
            files.forEach { it.isSelected = true }

            val apkFiles = files.filter { file ->
                Townhouseic.apks.any { suffix -> file.name.endsWith(suffix, true) }
            }.toMutableList()
            val tempFiles = files.filter { file ->
                Townhouseic.temps.any { suffix -> file.name.endsWith(suffix, true) }
            }.toMutableList()
            val logsFiles = files.filter { file ->
                Townhouseic.logs.any { suffix -> file.name.endsWith(suffix, true) }
            }.toMutableList()

            list = getGroupData()
            list[0].length = emptyFolders.sumOf { it.length }
            list[1].length = apkFiles.sumOf { it.length }
            list[2].length = tempFiles.sumOf { it.length }
            list[3].length = logsFiles.sumOf { it.length }
            list[0].items = emptyFolders
            list[1].items = apkFiles
            list[2].items = tempFiles
            list[3].items = logsFiles
            total = list.sumOf { it.length }
            val childData = mutableListOf<Voluminousic>().apply {
                addAll(emptyFolders)
                addAll(apkFiles)
                addAll(tempFiles)
                addAll(logsFiles)
            }
            val list = childData.sortedByDescending { it.length }
            val totalSize = list.sumOf { it.length }
            val random = Random.nextLong(2500, 3000)
            launch(Dispatchers.Main) {
                Carpentryic.progress(binding.schoolingic, 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 (data in list) {
                if (binding.schoolingic.progress == 100) break
                withContext(Dispatchers.Main) {
                    binding.informalic.text = data.path
                }
            }
            delay(random)
            launch(Dispatchers.Main) {
                scanComplete()
                adapter.notifyDataSetChanged()
            }
        }
    }

    private fun getGroupData(): MutableList<Voluminousic> {
        return mutableListOf(
            Voluminousic(getString(R.string.pasteic), icon = R.drawable.poweric, isSelected = true),
            Voluminousic(getString(R.string.pontificalic), icon = R.drawable.crampic, isSelected = true),
            Voluminousic(getString(R.string.rainyic), icon = R.drawable.oddsic, isSelected = true),
            Voluminousic(getString(R.string.teeic), icon = R.drawable.caviaric, isSelected = true),
        )
    }

    private fun scanComplete() {
        isBackDisable = false
        binding.umpireic.visibility = View.VISIBLE
        binding.drinkeric.visibility = View.VISIBLE
        binding.informalic.text = getString(R.string.carbohydrateic)
        updateSelection()
    }

    private fun setSize(size: Long) {
        val values = Devastatingic.getSizeArray(size)
        binding.unzipic.text = values[0]
        binding.wharvesic.text = values[1]
    }

}