package com.base.browserwhite.ui.activity.download

import android.annotation.SuppressLint
import android.content.Context
import android.view.View
import android.view.ViewGroup
import androidx.core.view.isVisible
import androidx.recyclerview.widget.RecyclerView.ViewHolder
import com.base.browserwhite.R
import com.base.browserwhite.bean.DownloadBean
import com.base.browserwhite.databinding.ItemDownloadBinding
import com.base.browserwhite.databinding.ItemDownloadCardBinding
import com.base.browserwhite.databinding.ItemDownloadTimeBinding
import com.base.browserwhite.ui.activity.download.DownloadDialog.showDownloadConfirmDialog
import com.base.browserwhite.utils.DownloadHelper.getDownloadPath
import com.base.browserwhite.utils.KotlinExt.toFormatSize
import com.base.browserwhite.utils.KotlinExt.toFormatTime
import com.base.browserwhite.utils.LogEx
import com.base.browserwhite.utils.XmlEx.inflate
import com.bumptech.glide.Glide
import com.chad.library.adapter4.BaseQuickAdapter
import com.liulishuo.filedownloader.BaseDownloadTask
import com.liulishuo.filedownloader.FileDownloadListener
import com.liulishuo.filedownloader.FileDownloader
import com.liulishuo.filedownloader.model.FileDownloadStatus
import kotlin.math.abs


@Suppress("ControlFlowWithEmptyBody")
class DownloadAdapter : BaseQuickAdapter<DownloadBean, DownloadAdapter.DownloadViewHolder>() {

    private val TAG = "DownloadAdapter"

    inner class DownloadViewHolder(view: View) : ViewHolder(view)

    var downloadAction: (() -> Unit)? = null
    var moreAction: ((archView: View, item: DownloadBean) -> Unit)? = null
    var itemClick: ((path: String) -> Unit)? = null

    override fun onBindViewHolder(holder: DownloadViewHolder, position: Int, item: DownloadBean?) {


        if (item == null) return

        when {
            item.isTime -> {
                val binding = ItemDownloadTimeBinding.bind(holder.itemView)
                binding.tvTime.text = item.time.toFormatTime()
            }

            item.uiType == 1 -> {
                bindType1(holder, position, item, null)
            }

            item.uiType == 2 -> {
                bindType2(holder, position, item, null)
            }
        }


    }

    override fun onBindViewHolder(holder: DownloadViewHolder, position: Int, item: DownloadBean?, payloads: List<Any>) {

        if (item == null) return

        when {
            item.isTime -> {
                val binding = ItemDownloadTimeBinding.bind(holder.itemView)
                binding.tvTime.text = item.time.toFormatTime()
            }

            item.uiType == 1 -> {
                bindType1(holder, position, item, payloads)
            }

            item.uiType == 2 -> {
                bindType2(holder, position, item, payloads)
            }
        }

    }

    private fun bindType1(holder: DownloadViewHolder, position: Int, item: DownloadBean, payloads: List<Any>?) {
        val binding = ItemDownloadBinding.bind(holder.itemView)

        if (payloads.isNullOrEmpty()) {
            Glide.with(context).load(item.url).centerCrop().into(binding.iv)
            binding.tvName.text = item.name
            binding.tvSize.text = item.size.toFormatSize()
            when (item.status) {
                FileDownloadStatus.completed -> {
                    binding.flMore.visibility = View.VISIBLE
                    binding.flDownload.visibility = View.GONE
                }

                FileDownloadStatus.paused -> {
                    binding.flMore.visibility = View.GONE
                    binding.flDownload.visibility = View.VISIBLE
                    binding.circularProgressBar.progress = item.progress.toFloat()
                    binding.ivXiazaiZantin.setImageResource(R.mipmap.zanting_download)
                }

                FileDownloadStatus.progress -> {
                    binding.flMore.visibility = View.GONE
                    binding.flDownload.visibility = View.VISIBLE
                    binding.circularProgressBar.progress = item.progress.toFloat()
                    binding.ivXiazaiZantin.setImageResource(R.mipmap.xiazhaiz_download)
                    replaceListener(item, position)
                }
            }
            binding.flDownload.setOnClickListener {
                pauseResumeDownload(item, position)
            }
            binding.flMore.setOnClickListener {
                moreAction?.invoke(it, item)
            }
            binding.root.setOnClickListener {
                if (item.status != FileDownloadStatus.completed) {
                    return@setOnClickListener
                }
                itemClick?.invoke(item.path)
            }
        } else {
            when (item.status) {
                FileDownloadStatus.completed -> {
                    binding.flMore.visibility = View.VISIBLE
                    binding.flDownload.visibility = View.GONE
                }

                FileDownloadStatus.paused -> {
                    binding.flMore.visibility = View.GONE
                    binding.flDownload.visibility = View.VISIBLE
                    binding.circularProgressBar.progress = item.progress.toFloat()
                    binding.ivXiazaiZantin.setImageResource(R.mipmap.zanting_download)
                }

                FileDownloadStatus.progress -> {
                    binding.flMore.visibility = View.GONE
                    binding.flDownload.visibility = View.VISIBLE
                    binding.circularProgressBar.progress = item.progress.toFloat()
                    binding.ivXiazaiZantin.setImageResource(R.mipmap.xiazhaiz_download)
                    replaceListener(item, position)
                }
            }
            super.onBindViewHolder(holder, position, item, payloads)
        }
    }

    private fun bindType2(holder: DownloadViewHolder, position: Int, item: DownloadBean, payloads: List<Any>?) {

        val binding = ItemDownloadCardBinding.bind(holder.itemView)
        if (payloads.isNullOrEmpty()) {
            Glide.with(context).load(item.url).centerCrop().into(binding.iv)
            binding.tvName.text = item.name.ifEmpty { item.url.split("/").last() }
            binding.tvSize.text = item.size.toFormatSize()

            var status = item.status
//            LogEx.logDebug(TAG, "status=${item.status} path=${item.path} progress=${item.progress}")
            if (item.progress == 100) {
                status = FileDownloadStatus.completed
            }

            binding.ivDownload.isVisible = status == FileDownloadStatus.pending
            binding.flDownload.isVisible = !binding.ivDownload.isVisible
            binding.ivFinish.isVisible = false

            when (status) {
                FileDownloadStatus.paused -> {
                    binding.ivXiazaiZantin.setImageResource(R.mipmap.zanting_download)
                    binding.circularProgressBar.progress = item.progress.toFloat()
                }

                FileDownloadStatus.progress -> {
                    binding.ivXiazaiZantin.setImageResource(R.mipmap.xiazhaiz_download)
                    binding.circularProgressBar.progress = item.progress.toFloat()
                    replaceListener(item, position)
                }

                FileDownloadStatus.completed -> {
                    binding.flDownload.isVisible = false
                    binding.ivFinish.isVisible = true
                }

                else -> {

                }
            }

            binding.ivDownload.setOnClickListener {
                downloadAction?.invoke()
                context.showDownloadConfirmDialog(item) {
                    downloadItem(context, item, position)
                }
            }
            binding.flDownload.setOnClickListener {
                pauseResumeDownload(item, position)
            }
        } else {
            var status = item.status
//            LogEx.logDebug(TAG, "status=${item.status} path=${item.path} progress=${item.progress}")
            if (item.progress == 100) {
                status = FileDownloadStatus.completed
            }

            binding.ivDownload.isVisible = status == FileDownloadStatus.pending
            binding.flDownload.isVisible = !binding.ivDownload.isVisible
            binding.ivFinish.isVisible = false

            when (status) {
                FileDownloadStatus.paused -> {
                    binding.ivXiazaiZantin.setImageResource(R.mipmap.zanting_download)
                    binding.circularProgressBar.progress = item.progress.toFloat()
                }

                FileDownloadStatus.progress -> {
                    binding.ivXiazaiZantin.setImageResource(R.mipmap.xiazhaiz_download)
                    binding.circularProgressBar.progress = item.progress.toFloat()
                    replaceListener(item, position)
                }

                FileDownloadStatus.completed -> {
                    binding.flDownload.isVisible = false
                    binding.ivFinish.isVisible = true
                }

                else -> {

                }
            }

        }
    }

    private fun pauseResumeDownload(item: DownloadBean, position: Int) {
        if (item.status == FileDownloadStatus.progress) {
            FileDownloader.getImpl().pause(item.downloadId)
            LogEx.logDebug(TAG, "pause  downloadId=${item.downloadId}")
            return
        }

        if (item.status == FileDownloadStatus.paused) {
            downloadItem(context, item, position)
            LogEx.logDebug(TAG, "start")
            return
        }
        LogEx.logDebug(TAG, "有问题")
    }

    override fun getItemViewType(position: Int, list: List<DownloadBean>): Int {
        val bean = list[position]
        return if (bean.isTime) 0 else bean.uiType

    }

    override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): DownloadViewHolder {
        val layout = when (viewType) {
            0 -> R.layout.item_download_time
            1 -> R.layout.item_download
            2 -> R.layout.item_download_card
            else -> 0
        }
        return DownloadViewHolder(layout.inflate(parent))
    }

    @SuppressLint("NotifyDataSetChanged")
    fun downloadItem(context: Context, item: DownloadBean, position: Int) {

        item.path = context.getDownloadPath(item)
        LogEx.logDebug(TAG, "downloadItem ${item.path}")

        item.fileDownloadListener = createNewLister(item, "downloadItem", position)

        val downloadTask = FileDownloader.getImpl().create(item.url)
            .setPath(item.path)
            .setCallbackProgressMinInterval(500)
            .setListener(item.fileDownloadListener)
        downloadTask.start()
        item.downloadId = downloadTask.id
    }

    private fun replaceListener(item: DownloadBean, position: Int) {
        if (item.fileDownloadListener == null) {
            item.fileDownloadListener = createNewLister(item, "replaceListener", position)
            FileDownloader.getImpl().replaceListener(item.downloadId, item.fileDownloadListener)
        }
    }


    private fun createNewLister(item: DownloadBean, tag: String = "", position: Int): FileDownloadListener {
        return object : FileDownloadListener() {
            override fun pending(task: BaseDownloadTask?, soFarBytes: Int, totalBytes: Int) {
                LogEx.logDebug(TAG, "pending tag=$tag item=${item.downloadId} ${task?.id} ${item.url}")
            }

            override fun progress(task: BaseDownloadTask?, soFarBytes: Int, totalBytes: Int) {
                val percent = soFarBytes * 100 / totalBytes
                LogEx.logDebug(TAG, "progress tag=$tag item=${item.downloadId} percent=$percent ${item.path}")
                if (percent < 0) return
                item.progress = percent
                item.status = FileDownloader.getImpl().getStatus(item.url, item.path)
                notifyItemChanged(position, "aaa")
            }

            override fun completed(task: BaseDownloadTask?) {
                LogEx.logDebug(TAG, "completed tag=$tag item=${item.downloadId} ${item.path}")
                item.progress = 100
                item.status = FileDownloader.getImpl().getStatus(item.url, item.path)
                item.time = System.currentTimeMillis()
                notifyItemChanged(position, "aaa")
            }

            override fun paused(task: BaseDownloadTask?, soFarBytes: Int, totalBytes: Int) {
                LogEx.logDebug(TAG, "paused tag=$tag item=${item.downloadId}")
                val percent = soFarBytes * 100 / totalBytes
                item.progress = abs(percent)
                item.status = FileDownloadStatus.paused
                item.time = System.currentTimeMillis()
                notifyItemChanged(position, "aaa")
            }

            override fun error(task: BaseDownloadTask?, e: Throwable?) {
                LogEx.logDebug(TAG, "error ${task?.id} $e")
            }

            override fun warn(task: BaseDownloadTask?) {
            }

            override fun connected(task: BaseDownloadTask?, etag: String?, isContinue: Boolean, soFarBytes: Int, totalBytes: Int) {
                super.connected(task, etag, isContinue, soFarBytes, totalBytes)
                LogEx.logDebug(TAG, "connected tag=$tag item=${item.downloadId} isContinue=$isContinue")
                if (isContinue) {

                }
            }
        }
    }

}