package com.dumpster.cleaner.ui.recovery

import android.annotation.SuppressLint
import android.content.Context
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.ViewHolder
import com.dumpster.cleaner.R
import com.dumpster.cleaner.bean.recovery.FolderBean
import com.dumpster.cleaner.bean.recovery.RecoveryBean
import com.dumpster.cleaner.databinding.ItemDocumentBinding
import com.dumpster.cleaner.databinding.ItemTimeMediaBinding
import com.dumpster.cleaner.ui.recovery.FileScanResultActivity.Companion.SCAN_AUDIOS
import com.dumpster.cleaner.ui.recovery.FileScanResultActivity.Companion.SCAN_DOCUMENTS
import com.bumptech.glide.Glide
import java.io.File
import java.text.SimpleDateFormat
import java.util.Locale

class FileTimeColumnsAdapter(
    val scanType: Int,
    val select: (all: Boolean, size: Int) -> Unit,
) : RecyclerView.Adapter<FileTimeColumnsAdapter.MCV>() {

    private val beanList = arrayListOf<FolderBean>()
    private var hideThumbnails: Boolean = false
    private var columns: Int = 2

    class MCV(view: View) : ViewHolder(view)

    fun Int.inflate(parent: ViewGroup, attachToRoot: Boolean = false): View {
        return LayoutInflater.from(parent.context).inflate(this, parent, attachToRoot)
    }

    fun Context.dpToPx(dps: Int): Int {
        return Math.round(resources.displayMetrics.density * dps)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MCV {
        return MCV(R.layout.item_time_media.inflate(parent))
    }

    override fun getItemCount(): Int {
        return beanList.size
    }

    override fun onBindViewHolder(holder: MCV, position: Int) {
        val binding = ItemTimeMediaBinding.bind(holder.itemView)
        val context = holder.itemView.context
        val bean = beanList[position]
        val file = File(bean.recoveryList.first().path)
        val time = SimpleDateFormat("yyyy-MMM-dd", Locale.getDefault()).format(file.lastModified())
        binding.tvTime.text = time
        binding.ivSelector.isSelected = bean.isSelect


        val subAdapter = MediaColumnsAdapter()

        if (scanType == SCAN_DOCUMENTS || scanType == SCAN_AUDIOS) {
            binding.rvMediaColumns.layoutManager = LinearLayoutManager(context)
        } else {
            binding.rvMediaColumns.layoutManager = GridLayoutManager(context, columns)
            binding.rvMediaColumns.layoutParams =
                LinearLayout.LayoutParams(RecyclerView.LayoutParams.WRAP_CONTENT, RecyclerView.LayoutParams.WRAP_CONTENT).apply {
                    topMargin = context.resources.getDimensionPixelOffset(R.dimen.dp_8)
                    gravity = Gravity.CENTER_HORIZONTAL
                }
        }
        binding.rvMediaColumns.adapter = subAdapter
        val list = if (hideThumbnails) bean.recoveryList.filter { !it.isThumbnails } else bean.recoveryList
        if (list.isEmpty()) {
            binding.flTittle.visibility = View.GONE
        } else {
            binding.flTittle.visibility = View.VISIBLE
            subAdapter.setData(list)
        }

        binding.ivSelector.setOnClickListener {
            bean.isSelect = !bean.isSelect
            binding.ivSelector.isSelected = bean.isSelect
            notifyItemChanged(position)
            itemClick(bean.isSelect, subAdapter)
        }
    }

    @SuppressLint("NotifyDataSetChanged")
    fun setData(data: List<FolderBean>) {
        beanList.clear()
        beanList.addAll(data)
        notifyDataSetChanged()
    }

    inner class MediaColumnsAdapter : RecyclerView.Adapter<MediaColumnsAdapter.CS>() {
        private val list = arrayListOf<RecoveryBean>()

        inner class CS(view: View) : ViewHolder(view) {
            val iv = view.findViewById<ImageView>(R.id.iv)
            val ivSelector = view.findViewById<ImageView>(R.id.iv_selector)
            val tvSize = view.findViewById<TextView>(R.id.tv_size)
        }

        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CS {
            var layout = when (columns) {
                2 -> R.layout.item_media_columns2
                3 -> R.layout.item_media_columns3
                4 -> R.layout.item_media_columns4
                else -> R.layout.item_media_columns2
            }
            if ((scanType == SCAN_DOCUMENTS) || (scanType == SCAN_AUDIOS)) {
                layout = R.layout.item_document
            }
            return CS(layout.inflate(parent))
        }

        override fun getItemCount(): Int {
            return list.size
        }

        override fun onBindViewHolder(holder: CS, position: Int) {
        }

        override fun onBindViewHolder(holder: CS, position: Int, payloads: MutableList<Any>) {

            val context = holder.itemView.context
            val data = list[position]

            if ((scanType == SCAN_DOCUMENTS) or (scanType == SCAN_AUDIOS)) {
                if (payloads.isEmpty()) {
                    val binding = ItemDocumentBinding.bind(holder.itemView)
                    binding.ivSelector.isSelected = data.isSelect
                    val icon = when (data.type) {
                        "PDF" -> R.drawable.pdf
                        "DOC" -> R.drawable.doc
                        "XLS" -> R.drawable.xls
                        "PPT" -> R.drawable.ppt
                        "MP3" -> R.drawable.mp3
                        "WAV" -> R.drawable.wav
                        "FLAC" -> R.drawable.flac
                        else -> 0
                    }
                    binding.ivType.setImageResource(icon)
                    val file = File(data.path)
                    binding.tvName.text = file.name
                    val time = SimpleDateFormat("MMM-dd-yyyy", Locale.getDefault()).format(file.lastModified())
                    val size = file.length().toFormatSize()
                    val info = "$time $size"
                    binding.tvInfo.text = info
                    binding.root.setOnClickListener {
                        data.isSelect = !data.isSelect
                        holder.ivSelector.isSelected = data.isSelect
                        notifyItemChanged(position, "asdada")
                        subItemClick(data)
                    }
                } else {
                    holder.ivSelector.isSelected = data.isSelect
                    super.onBindViewHolder(holder, position, payloads)
                }

            } else {
                if (payloads.isEmpty()) {
                    Glide.with(context).asBitmap().load(data.path).centerCrop().into(holder.iv)
                    holder.ivSelector.isSelected = data.isSelect
                    holder.itemView.setOnClickListener {
                        data.isSelect = !data.isSelect
                        holder.ivSelector.isSelected = data.isSelect
                        notifyItemChanged(position, "changeIv")

                        subItemClick(data)
                    }
                    val file = File(data.path)
                    holder.tvSize.text = file.length().toFormatSize()
                } else {
                    holder.ivSelector.isSelected = data.isSelect
                    super.onBindViewHolder(holder, position, payloads)
                }
            }

        }

        @SuppressLint("NotifyDataSetChanged")
        fun setData(bean: List<RecoveryBean>) {
            list.clear()
            list.addAll(bean)
            notifyDataSetChanged()
        }

        @SuppressLint("NotifyDataSetChanged")
        fun toggleSelect(select: Boolean) {
            list.forEach {
                it.isSelect = select
            }
            notifyDataSetChanged()
        }


    }

    @SuppressLint("NotifyDataSetChanged")
    fun subItemClick(data: RecoveryBean) {
        val folderBean = beanList.find { it.recoveryList.contains(data) }

        folderBean?.let { folder ->
            val select = folder.recoveryList.all { it.isSelect }
            if (folder.isSelect != select) {
                folder.isSelect = select
                notifyDataSetChanged()
            }
        }
        val all = beanList.all { it.isSelect }
        val size = beanList.sumOf { it.recoveryList.filter { bean -> bean.isSelect }.size }
        select.invoke(all, size)
    }

    private fun itemClick(isSelect: Boolean, subAdapter: MediaColumnsAdapter) {
        subAdapter.toggleSelect(isSelect)

        val all = beanList.all { it.isSelect }
        val size = beanList.sumOf { it.recoveryList.filter { bean -> bean.isSelect }.size }
        select.invoke(all, size)
    }

    @SuppressLint("NotifyDataSetChanged")
    fun toggleThumbnails(hideThumbnails: Boolean) {
        this.hideThumbnails = hideThumbnails
        notifyDataSetChanged()
    }

    @SuppressLint("NotifyDataSetChanged")
    fun toggleAllSelect(selected: Boolean) {
        beanList.forEach {
            it.isSelect = selected
            it.recoveryList.forEach { bean -> bean.isSelect = selected }
        }
        notifyDataSetChanged()
        val all = beanList.all { it.isSelect }
        val size = beanList.sumOf { it.recoveryList.filter { bean -> bean.isSelect }.size }
        select.invoke(all, size)
    }

    @SuppressLint("NotifyDataSetChanged")
    fun changeColumns(columns: Int) {
        this.columns = columns
        notifyDataSetChanged()
    }

    fun getSelectData(): List<RecoveryBean> {
        return beanList.flatMap { it.recoveryList }.filter { it.isSelect }
    }

    fun Number.toFormatSize(count: Int = 1): String {
        var suffix = "B"
        var fSize = this.toDouble()
        if (fSize > 1024) {
            suffix = "KB"
            fSize /= 1024.0
        }
        if (fSize > 1024) {
            suffix = "MB"
            fSize /= 1024.0
        }
        if (fSize > 1024) {
            suffix = "GB"
            fSize /= 1024.0
        }
        return String.format("%.${count}f %s", fSize, suffix)
    }
}