package com.tgv.malware.ui.largefile

import android.annotation.SuppressLint
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.appcompat.widget.AppCompatImageView
import androidx.appcompat.widget.AppCompatTextView
import androidx.core.content.ContextCompat
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.isVisible
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.tgv.malware.R
import com.tgv.malware.base.BaseActivity
import com.tgv.malware.base.LottieEnum
import com.tgv.malware.base.cleanFileBeans
import com.tgv.malware.bean.FeatureBean.Companion.LARGE_FILE_CLEAN
import com.tgv.malware.bean.FileBean
import com.tgv.malware.business.ads.AdsMgr
import com.tgv.malware.business.ads.AdsShowCallBack
import com.tgv.malware.databinding.ActivityLargeFileCleanBinding
import com.tgv.malware.databinding.ItemLargeFileCleanBinding
import com.tgv.malware.databinding.ItemLargeFileCleanTabBinding
import com.tgv.malware.ui.cleanresult.CleanResultActivity
import com.tgv.malware.ui.dialog.ConfirmDialog
import com.tgv.malware.utils.MediaUtils
import com.tgv.malware.utils.MineTypeUtils
import com.tgv.malware.utils.Utils
import com.bumptech.glide.Glide
import com.bumptech.glide.load.resource.bitmap.CenterCrop
import com.bumptech.glide.load.resource.bitmap.RoundedCorners
import com.bumptech.glide.request.RequestOptions
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.launch
import java.util.Calendar


class LargeFileCleanActivity : BaseActivity<ActivityLargeFileCleanBinding>(ActivityLargeFileCleanBinding::inflate) {

    private val LARGE_FILE_SIZE: Long = 1024 * 1024 * 10
    private val typeList by lazy {
        listOf(
            FileBean(getString(R.string.all_types), isSelected = true),
            FileBean(getString(R.string.image)),
            FileBean(getString(R.string.video)),
            FileBean(getString(R.string.audio)),
            FileBean(getString(R.string.document)),
            FileBean(getString(R.string.apk)),
            FileBean(getString(R.string.other_types)),
        )
    }
    private val sizeList by lazy {
        listOf(
            FileBean(getString(R.string.mb_10), isSelected = true),
            FileBean(getString(R.string.mb_20)),
            FileBean(getString(R.string.mb_50)),
            FileBean(getString(R.string.mb_100)),
            FileBean(getString(R.string.mb_500)),
        )
    }
    private val timeList by lazy {
        listOf(
            FileBean(getString(R.string.all_time), isSelected = true),
            FileBean(getString(R.string.week_1)),
            FileBean(getString(R.string.month_1)),
            FileBean(getString(R.string.month_3)),
            FileBean(getString(R.string.month_6)),
            FileBean(getString(R.string.year_1)),
        )
    }

    private var typePosition = 0
    private var sizePosition = 0
    private var timePosition = 0
    private var total: Long = 0
    private var allData = mutableListOf<FileBean>()
    private var list = mutableListOf<FileBean>()
    private val adapter by lazy {
        class ViewHolder(val binding: ItemLargeFileCleanBinding) : RecyclerView.ViewHolder(binding.root)

        object : RecyclerView.Adapter<ViewHolder>() {
            override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
                val binding = ItemLargeFileCleanBinding.inflate(LayoutInflater.from(parent.context), parent, false)
                return ViewHolder(binding)
            }

            override fun getItemCount(): Int = list.size

            override fun onBindViewHolder(holder: ViewHolder, position: Int) {
                val item = list[position]
                holder.binding.ivVideo.isVisible = MineTypeUtils.isVideo(item.mineType)
                if (MineTypeUtils.isImage(item.mineType) || MineTypeUtils.isVideo(item.mineType)) {
                    val round = resources.getDimensionPixelSize(R.dimen.dp_4)
                    val options = RequestOptions().transform(CenterCrop(), RoundedCorners(round))
                    Glide.with(holder.itemView.context)
                        .load(item.path)
                        .apply(options)
                        .into(holder.binding.ivIcon)
                } else if (MineTypeUtils.isAudio(item.mineType)) {
                    holder.binding.ivIcon.setImageResource(R.drawable.icon_yinping)
                } else if (MineTypeUtils.isApk(item.mineType)) {
                    holder.binding.ivIcon.setImageResource(R.drawable.icon_app_file_cleaner)
                } else if (MineTypeUtils.isDoc(item.mineType)) {
                    holder.binding.ivIcon.setImageResource(R.drawable.icon_wenjianx)
                } else {
                    holder.binding.ivIcon.setImageResource(R.drawable.icon_qita_file_cleaner)
                }

                holder.binding.tvName.text = item.name
                holder.binding.tvLength.text = Utils.getSizeFormat(item.length)
                holder.binding.ivSelect.isSelected = item.isSelected
                holder.binding.viewLine.visibility = if (position == itemCount - 1) View.GONE else View.VISIBLE
                holder.itemView.setOnClickListener {
                    item.isSelected = !item.isSelected
                    notifyItemChanged(position)
                    updateView()
                }
            }
        }
    }

    private var tabType = 0
    private val tabList = mutableListOf<FileBean>()
    private val tabAdapter by lazy {
        class ViewHolder(val binding: ItemLargeFileCleanTabBinding) : RecyclerView.ViewHolder(binding.root)

        object : RecyclerView.Adapter<ViewHolder>() {
            override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
                val binding = ItemLargeFileCleanTabBinding.inflate(LayoutInflater.from(parent.context), parent, false)
                return ViewHolder(binding)
            }

            override fun getItemCount(): Int = tabList.size

            override fun onBindViewHolder(holder: ViewHolder, position: Int) {
                val item = tabList[position]
                holder.binding.tvName.text = item.name
                holder.binding.tvName.setTextColor(getColor(if (item.isSelected) R.color.colorPrimary else R.color.color_666666))
                holder.binding.viewLine.visibility = if (position == itemCount - 1) View.GONE else View.VISIBLE
                holder.binding.ivSelect.isSelected = item.isSelected
                holder.itemView.setOnClickListener {
                    tabList.forEach { it.isSelected = false }
                    item.isSelected = !item.isSelected
                    handleTab(item, position)
                }
            }
        }
    }

    private fun updateView() {
        total = list.filter { it.isSelected }.sumOf { it.length }
        setTextSize(binding.tvDelete, getString(R.string.delete), total)
        binding.tvDelete.isEnabled = total > 0
        if (binding.tvDelete.isEnabled == true) {
            binding.tvDelete.setTextColor(ContextCompat.getColor(this, R.color.white))
        } else {
            binding.tvDelete.setTextColor(ContextCompat.getColor(this, R.color.colorPrimary))
        }
    }

    private fun handleTab(item: FileBean, position: Int) {
        binding.clTab.visibility = View.GONE
        var textView: AppCompatTextView = binding.tvTime
        when (tabType) {
            1 -> {
                textView = binding.tvType
                typePosition = position
            }

            2 -> {
                textView = binding.tvSize
                sizePosition = position
            }

            3 -> {
                textView = binding.tvTime
                timePosition = position
            }
        }
        textView.text = item.name
        binding.tvDelete.text = getString(R.string.delete)
        filterData()
        clearTab()
    }

    fun setTextSize(view: TextView, content: String, total: Long) {
        view.text = if (total > 0) "$content (${Utils.getSizeFormat(total)})" else content
    }

    @SuppressLint("NotifyDataSetChanged")
    private fun filterData() {
        allData.forEach { it.isSelected = false }
        var data = filterType(allData, typePosition)
        data = filterSize(data, sizePosition)
        data = filterTime(data, timePosition)
        list = data.toMutableList()
        adapter.notifyDataSetChanged()
        binding.rvLargeFile.visibility = if (list.isEmpty()) View.GONE else View.VISIBLE
        binding.ivEmpty.visibility = if (list.isEmpty()) View.VISIBLE else View.GONE
        binding.tvDelete.visibility = if (list.isEmpty()) View.GONE else View.VISIBLE
    }

    private fun filterType(list: List<FileBean>, position: Int): List<FileBean> {
        return when (position) {
            1 -> list.filter { MineTypeUtils.isImage(it.mineType) }
            2 -> list.filter { MineTypeUtils.isVideo(it.mineType) }
            3 -> list.filter { MineTypeUtils.isAudio(it.mineType) }
            4 -> list.filter { MineTypeUtils.isDoc(it.mineType) }
            5 -> list.filter { MineTypeUtils.isApk(it.mineType) }
            6 -> list.filterNot { file ->
                MineTypeUtils.mineTypes.any { mimeType -> file.mineType.startsWith(mimeType) }
            }

            else -> {
                list
            }
        }
    }

    private fun filterSize(list: List<FileBean>, position: Int): List<FileBean> {
        return when (position) {
            1 -> list.filter { it.length >= LARGE_FILE_SIZE * 2 }
            2 -> list.filter { it.length >= LARGE_FILE_SIZE * 5 }
            3 -> list.filter { it.length >= LARGE_FILE_SIZE * 10 }
            4 -> list.filter { it.length >= LARGE_FILE_SIZE * 50 }
            else -> {
                list.filter { it.length >= LARGE_FILE_SIZE }
            }
        }
    }


    private fun filterTime(list: List<FileBean>, position: Int): List<FileBean> {
        return when (position) {
            1 -> list.filter { it.lastModified > Calendar.getInstance().apply { add(Calendar.WEEK_OF_YEAR, -1) }.timeInMillis }
            2 -> list.filter { it.lastModified > Calendar.getInstance().apply { add(Calendar.MONTH, -1) }.timeInMillis }
            3 -> list.filter { it.lastModified > Calendar.getInstance().apply { add(Calendar.MONTH, -3) }.timeInMillis }
            4 -> list.filter { it.lastModified > Calendar.getInstance().apply { add(Calendar.MONTH, -6) }.timeInMillis }
            5 -> list.filter { it.lastModified > Calendar.getInstance().apply { add(Calendar.YEAR, -1) }.timeInMillis }
            else -> {
                list
            }
        }
    }

    private fun clearTab() {
        binding.llTab.setBackgroundResource(R.color.color_f7fafa)
        binding.tvDelete.isEnabled = false
        binding.llType.setBackgroundResource(R.drawable.tab_large_file)
        binding.llSize.setBackgroundResource(R.drawable.tab_large_file)
        binding.llTime.setBackgroundResource(R.drawable.tab_large_file)
        binding.ivType.isSelected = false
        binding.ivSize.isSelected = false
        binding.ivTime.isSelected = false
        binding.tvType.setTextColor(getColor(R.color.color_181b1f))
        binding.tvSize.setTextColor(getColor(R.color.color_181b1f))
        binding.tvTime.setTextColor(getColor(R.color.color_181b1f))
        binding.ivTypeArrow.setImageResource(R.drawable.icon_jiantou_down_small)
        binding.ivSizeArrow.setImageResource(R.drawable.icon_jiantou_down_small)
        binding.ivTimeArrow.setImageResource(R.drawable.icon_jiantou_down_small)
        binding.llType.isSelected = false
        binding.llSize.isSelected = false
        binding.llTime.isSelected = false
    }


    private fun setTab(
        view: View,
        textView: AppCompatTextView,
        imageView: AppCompatImageView
    ) {
        if (view.isSelected) {
            hiddenTab()
            return
        }
        clearTab()
        view.isSelected = true
        view.setBackgroundResource(R.drawable.bg_btn_50)
        imageView.setImageResource(R.drawable.icon_jiantou_up_small)
        textView.setTextColor(getColor(R.color.white))
        binding.llTab.setBackgroundResource(R.color.white)
        when (view) {
            binding.llType -> {
                binding.ivType.isSelected = true
                binding.tvOtherThan.visibility = View.GONE
                showTab(1, typeList)
            }

            binding.llSize -> {
                binding.ivSize.isSelected = true
                binding.tvOtherThan.text = getString(R.string.larger_than)
                binding.tvOtherThan.visibility = View.VISIBLE
                showTab(2, sizeList)
            }

            binding.llTime -> {
                binding.ivTime.isSelected = true
                binding.tvOtherThan.text = getString(R.string.other_types)
                binding.tvOtherThan.visibility = View.VISIBLE
                showTab(3, timeList)
            }
        }
    }

    @SuppressLint("NotifyDataSetChanged")
    private fun showTab(type: Int, list: List<FileBean>) {
        binding.clTab.visibility = View.VISIBLE
        tabType = type
        tabList.clear()
        tabList.addAll(list)
        tabAdapter.notifyDataSetChanged()
    }

    private fun hiddenTab() {
        binding.clTab.visibility = View.GONE
        binding.llType.isSelected = false
        binding.llSize.isSelected = false
        binding.llTime.isSelected = false
        clearTab()
    }

    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.clTop.setPadding(0, systemBars.top, 0, 0)
            insets
        }
    }

    override fun initView() {
        super.initView()
        binding.rvTab.adapter = tabAdapter
        binding.rvTab.layoutManager = LinearLayoutManager(this)
        binding.rvLargeFile.adapter = adapter
        binding.rvLargeFile.layoutManager = LinearLayoutManager(this)
        initData()
        showAdAnimation(LottieEnum.LARGE_FILE_LOTTIE) {
            AdsMgr.showNative(binding.flAd, R.layout.layout_admob_native_custom)
        }
    }

    private fun initData() {
        lifecycleScope.launch(Dispatchers.IO) {
            allData = async { MediaUtils.findFiles(this@LargeFileCleanActivity, LARGE_FILE_SIZE) }.await()
            launch(Dispatchers.Main) { filterData() }
        }
    }

    override fun initListener() {
        super.initListener()
        binding.ivBack.setOnClickListener { onBackPressedDispatcher.onBackPressed() }
        binding.llType.setOnClickListener {
            setTab(it, binding.tvType, binding.ivTypeArrow)
        }
        binding.llSize.setOnClickListener {
            setTab(it, binding.tvSize, binding.ivSizeArrow)
        }
        binding.llTime.setOnClickListener {
            setTab(it, binding.tvTime, binding.ivTimeArrow)
        }
        binding.clTab.setOnClickListener {
            hiddenTab()
        }
        binding.tvDelete.setOnClickListener {
            if (total <= 0) return@setOnClickListener
            val dialog = ConfirmDialog(this)
            dialog.action = {
                cleanFileBeans(list)
                AdsMgr.showInsert(this, showCallBack = object : AdsShowCallBack() {
                    override fun next() {
                        CleanResultActivity.functionKey = LARGE_FILE_CLEAN
                        CleanResultActivity.total = total
                        CleanResultActivity.titleName = getString(R.string.large_file_clean)
                        goToAc(CleanResultActivity::class.java)
                    }
                })
            }
            dialog.showDialog("delete")
        }
    }

}