package com.lukouguoji.module_base.update

import android.content.Context
import android.os.Environment
import com.lukouguoji.module_base.ktx.loge
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import okhttp3.OkHttpClient
import okhttp3.Request
import okio.buffer
import okio.sink
import java.io.File
import kotlin.math.roundToInt

class DownloadManager(
    private val context: Context,
    private val notificationUtil: NotificationUtil
) {
    private var currentJob: Job? = null
    private var isDownloading = false
    fun downloadFile(
        url: String,
        fileName: String,
        onProgress: (Int) -> Unit,
        onComplete: (File) -> Unit,
        onError: (String) -> Unit
    ) {
        if (isDownloading) return
        isDownloading = true
        currentJob = CoroutineScope(Dispatchers.IO).launch {
            try {
                val client = OkHttpClient()
                val request = Request.Builder().url(url).build()
                val response = client.newCall(request).execute()

                if (!response.isSuccessful) {
                    withContext(Dispatchers.Main) { onError("网络请求失败") }
                    return@launch
                }
                val downloadDir = context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)
                if(downloadDir==null){
                    loge("无法访问下载目录")
                }
                val outputFile = File(downloadDir, fileName)
                client.newCall(request).execute().use { response ->
                    if (!response.isSuccessful) {
                        loge("HTTP错误: ${response.code}")
                    }

                    response.body?.use { body ->
                        val source = body.source()
                        val sink = outputFile.sink().buffer()

                        val contentLength = body.contentLength()
                        var bytesRead = 0L
                        var lastProgress = -1

                        var lastTime = System.currentTimeMillis()
                        var lastBytes = 0L
                        while (true) {
                            val read = source.read(sink.buffer, 8192L)
                            if (read == -1L) break
                            bytesRead += read
                            sink.emit()

                            val progress = ((bytesRead.toFloat() / contentLength) * 100).roundToInt()
                            if(System.currentTimeMillis() - lastTime >1000){
                                lastTime = System.currentTimeMillis()
                                val usedMem = (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / 1024 / 1024
                                val speed = (bytesRead - lastBytes) / 1024
                                lastBytes = bytesRead
                                loge( "已用内存: ${usedMem}MB  当前下载进度 $progress  下载速度 $speed KB/s")
                            }
                            if (progress != lastProgress) {
                                lastProgress = progress
                                withContext(Dispatchers.Main) {
                                    onProgress(progress)
                                    notificationUtil.updateProgress(progress)
                                }
                            }
                        }
                        sink.flush()
                    }
                }

                withContext(Dispatchers.Main) {
                    isDownloading = false
                    onComplete(outputFile)
                    notificationUtil.showDownloadComplete(outputFile)
                }
            } catch (e: Exception) {
                isDownloading = false
                withContext(Dispatchers.Main) { onError(e.message ?: "未知错误") }
            }
        }
    }

    fun cancelDownload() {
        currentJob?.cancel()
        isDownloading = false
    }
}