package com.ys.bdtp.adm.app.tools

import android.util.Log
import com.ys.bdtp.adm.app.tools.file.FileId
import com.ys.bdtp.adm.app.tools.file.FileInfo
import com.ys.bdtp.adm.mvvm.model.nt.Api
import com.ys.bdtp.adm.mvvm.model.nt.FailureResponse
import com.ys.bdtp.adm.mvvm.model.nt.SuccessResponse
import com.ys.bdtp.adm.mvvm.model.nt.request
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.RequestBody
import okhttp3.RequestBody.Companion.toRequestBody
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream

/**
 * 读取文件，返回字节数组
 */
fun File.toBytes(): ByteArray {
    val fis = FileInputStream(this)
    return fis.readBytes()
}

/**
 * 文件转换程 RequestBody
 */
fun File.toRequestBody(
    mediaType: String = "application/json;charset=utf-8"
): RequestBody {
    val bytes = this.toBytes()
    return bytes.toRequestBody(mediaType.toMediaType())
}

/**
 * 文件上传
 *
 * @author bai
 *
 * @param param
 *        mapOf(
 *            "appId" to "adm",
 *            "userId" to "",
 *            "groupCode" to "",
 *            "projectId" to ""
 *        )
 * @param file 要上传的文件, 确保文件存在
 *
 */
suspend fun fileUpload(api: Api, param: Map<String, String>, file: File) {
    val bytes = file.toBytes()
    val md5 = md5(bytes)
    val size = bytes.size
    val fileInfo = FileInfo(
        fileId = file.name, fileName = file.name, fileSize = size, fileMd5 = md5
    )
    when (val response = request { api.getFileUploadInfo(param, fileInfo) }) {
        is SuccessResponse -> {
            val data = response.data
            val url = data.content?.get(0)?.uploadUrl ?: ""
            if (url.isNotEmpty()) {
                val body = bytes.toRequestBody()
                val result = api.uploadFile(url, body)
                Log.d("fileUpload", "success: $result")
            } else {
                Log.d("fileUpload", "failure: no url to upload file")
            }
        }
        is FailureResponse -> {
            Log.d("fileUpload", "upload file has something error：${response.fail}")
        }
    }
}

/**
 * 下载文件
 *
 * @author bai
 *
 * @param param
 *        mapOf(
 *            "appId" to "adm",
 *            "userId" to "",
 *            "groupCode" to "",
 *            "projectId" to ""
 *        )
 * @param file 创建的空file, 存储下载的文件字节数组
 *        例：
 *        val path: File? = getExternalFilesDir("/img/png")
 *        if (path == null || !path.exists()) {
 *            path?.mkdirs()
 *        }
 *        val file = File(path, "download.png")
 * @param fileId 文件存储平台的 fileId
 *
 */
suspend fun fileDownload(api: Api, param: Map<String, String>, file: File, fileId: FileId) {
    when (val response = request { api.getFileDownloadInfo(param, fileId) }) {
        is SuccessResponse -> {
            val data = response.data
            val url = data.fileDownloadUrl ?: ""
            if (url.isNotEmpty()) {
                val bytes = api.downloadFile(url)
                val fos = withContext(Dispatchers.IO) {
                    FileOutputStream(file)
                }
                fos.use { out ->
                    out.write(bytes)
                }
                Log.d("fileDownload", "success")
            } else {
                Log.d("fileDownload", "failure: no url to download file")
            }
        }
        is FailureResponse -> {
            Log.d("fileDownload", "download file has something error：${response.fail}")
        }
    }
}
