import android.util.Log
import com.billbook.lib.downloader.Download
import com.billbook.lib.downloader.Downloader
import com.xhly.corelib.Const
import com.xhly.corelib.utils.LogShow
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.cancel
import kotlinx.coroutines.launch
import java.util.LinkedList
import java.util.Queue

object DownLoadUtils {
    val queue: Queue<DownloadItem> = LinkedList()
    var callbackList = mutableListOf<DownloadCallback>()
    var isRunning = false
    var coroutineScope:CoroutineScope? =null
    fun isEmpty(): Boolean {
        return queue.isEmpty()
    }

    /**
     * 页面启动 添加回调
     */
    fun addCallback(callback: DownloadCallback) {
        callbackList.add(callback)
    }


    /**
     * 页面关闭 删除回调
     */
    fun removeCallback(callback: DownloadCallback) {
        callbackList.remove(callback)
    }


    /**
     * 下载文件
     */
    fun addDownload(url: String, tag: String, savepath: String,pkgName: String,appName:String) {
        LogShow("添加下载任务"+savepath)
        var isHave = false
        for (element in queue) {
            if (element.tag === tag) {
                isHave = true
            }
        }
        if (!isHave) {
            queue.add(DownloadItem(url, tag, savepath, 0,pkgName,appName))
        } else {
            for (downloadCallback in callbackList) {
                downloadCallback.onFailure(DownloadItem(url, tag, savepath, 0,pkgName,appName), "已经在下载队列")
            }
        }
        downloadAction()
    }

    private fun downloadAction() {
        if (isRunning) {
            return
        }
        if (coroutineScope==null){
            coroutineScope = CoroutineScope(Dispatchers.IO)
        }
        coroutineScope?.launch {
            while (queue.size > 0) {
                isRunning = true
                val downItem = queue.peek()
                downItem?.let {
                    try {
                        val downloader = Downloader.Builder().build()
                        val request = Download.Request.Builder()
                            .url(Const.URL1 +it.url)
                            .into(it.savepath)
                            .build()
                        val call = downloader.newCall(request)
                        call.execute(object : Download.Callback {
                            override fun onStart(call: Download.Call) {
                                LogShow("开始下载"+downItem.savepath)
                                for (downloadCallback in callbackList) {
                                    downloadCallback.onStart(downItem)
                                }
                            }

                            override fun onSuccess(call: Download.Call, response: Download.Response) {
                                LogShow("下载成功"+downItem.savepath)
                                queue.poll()
                                for (downloadCallback in callbackList) {
                                    downloadCallback.onSuccess(downItem)
                                }
                            }

                            override fun onFailure(call: Download.Call, response: Download.Response) {
                                LogShow("下载失败"+response.message)
                                queue.poll()
                                for (downloadCallback in callbackList) {
                                    downloadCallback.onFailure(downItem, response.message!!)
                                }
                            }

                            override fun onLoading(call: Download.Call, current: Long, total: Long) {
                                val progress = (current * 100 / total).toInt()
                               // LogShow("下载进度"+progress)
//                                Log.i("详情", "$progress ${downItem.progress} ${callbackList.size}")
                                if (progress != downItem.progress) {
                                    for (downloadCallback in callbackList) {
                                        downItem.progress = progress
                                        downloadCallback.onLoading(downItem)
                                    }
                                }
                            }
                        })
                    } catch (e: Exception) {
                        queue.poll()
                        for (downloadCallback in callbackList) {
                            downloadCallback.onFailure(downItem, e.toString())
                        }
                    }
                }

            }
            isRunning = false
        }

    }

    fun destroyDownLoad(){
        coroutineScope?.cancel()
        isRunning=false
        queue.clear()
    }
}

data class DownloadItem(val url: String, val tag: String, val savepath: String, var progress: Int,var pkgName:String,var appName:String)

interface DownloadCallback {
    fun onStart(downItem: DownloadItem)
    fun onSuccess(downItem: DownloadItem)
    fun onFailure(downItem: DownloadItem, errMsg: String)
    fun onLoading(downItem: DownloadItem)
}
