package com.sd.cavphmi.utils

import android.content.ContentValues
import android.content.Context
import android.graphics.Bitmap
import android.net.Uri
import android.os.Build
import android.os.Environment
import android.provider.MediaStore
import android.util.Log
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
import java.io.*
import java.math.BigDecimal


object FileIoUtils {

    /**
     * 读取asset 文件
     */
    suspend fun getAssetContent(context: Context, fileName: String):String {
       return withContext(Dispatchers.IO) {
            val assetManager = context.assets
            var stringBuilder = StringBuilder()
            var bf: BufferedReader? = null
            try {
                val inputReader = InputStreamReader(assetManager.open(fileName))
                bf = BufferedReader(inputReader)
                var line = ""
                while (!bf.run {
                        line = readLine()
                        return@run line
                    }.isNullOrEmpty()) {
                    stringBuilder.append(line)
                }
                bf?.close()
                return@withContext stringBuilder.toString()
            } catch (e: IOException) {
                e.printStackTrace()
            } finally {
                bf?.close()
//                assetManager.close()
            }
            return@withContext  ""
        }
    }


    suspend fun getAssetMock(context: Context, fileName: String, dst: MutableList<String>): Int {
        return withContext(Dispatchers.IO) {
            val assetManager = context.assets
            var bf: BufferedReader? = null
            try {
                val inputReader = InputStreamReader(assetManager.open(fileName))
                bf = BufferedReader(inputReader)
                var line = ""
                while (!bf.run {
                        line = readLine()
                        return@run line
                    }.isNullOrEmpty()) {
                    dst.add(line)
                }
                bf?.close()
                return@withContext 1
            } catch (e: IOException) {
                e.printStackTrace()
            } finally {
                bf?.close()
            }
            return@withContext 0
        }

    }

    /**
     * 读取asset 文件
     */
    fun getAsset(context: Context, fileName: String): String {
        val assetManager = context.assets
        var inputStream: InputStream? = null
        var str = ""
        try {
            inputStream = assetManager.open(fileName)
            val size = inputStream.available()
            val bytes = ByteArray(size)
            inputStream.read(bytes)
            str = String(bytes)
        } catch (e: IOException) {
            e.printStackTrace()
        } finally {
            inputStream?.close()
//            assetManager.close()
        }
        return str
    }

    //Uri获取真实路径转换成File的方法
    fun getAbsoluteImagePath(contentUri: Uri, context: Context): String { // can post image
        var res = ""
        val proj = arrayOf(MediaStore.Images.Media.DATA)
        val cursor = context.contentResolver.query(contentUri, proj, null, null, null)

        if (cursor!!.moveToFirst()) {
            val column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA)
            res = cursor.getString(column_index)
        }
        cursor.close()

        return res
    }

    /**
     * 把图片复制到应用缓存里
     */
    fun copyHeImgFileToPath(
        context: Context,
        fileName: String,
        source: File,
        isRemove: Boolean = true
    ): File? {
        try {
            var dir = File(context.externalCacheDir, "xunhepic")
            if (!dir.exists()) {
                dir.mkdirs()
            }
            var imgFile = File(dir, fileName)
            if (!dir.exists()) {
                imgFile.createNewFile()
            }
            var fosfrom = FileInputStream(source)
            var fosto = FileOutputStream(imgFile)

            var bt = ByteArray(1024)
            var c = 0
            while (fosfrom.run {
                    c = read(bt)
                    return@run c
                } > 0) {
                fosto.write(bt, 0, c) //将内容写到新文件当
            }
            if (isRemove) {
//                source.deleteOnExit()
            }
            fosfrom.close()
            fosto.close()
            return imgFile
        } catch (e: IOException) {
            return null
        }
    }


    //file文件读取成byte[]
    fun readFileToByte(file: File?): ByteArray? {
        val byte_size = 1024
        val b = ByteArray(byte_size)
        try {
            val fileInputStream = FileInputStream(file)
            val outputStream = ByteArrayOutputStream(
                byte_size
            )
            var length: Int
            while (fileInputStream.read(b).also { length = it } != -1) {
                outputStream.write(b, 0, length)
            }
            fileInputStream.close()
            outputStream.close()
            return outputStream.toByteArray()
        } catch (e: IOException) {
            e.printStackTrace()
        }
        return null
    }

    /**
     * 获取总共的缓存
     */
    fun getTotalCacheSize(context: Context): Long {
        var size: Long = 0
        return try {
            size = getFolderSize(context.cacheDir)
            size += getFolderSize(context.filesDir)
//            size += getFolderSize(context.externalCacheDir)
            size
        } catch (e: Exception) {
            e.printStackTrace()
            0
        }
    }

    /**
     * 获取文件夹大小
     */
    private fun getFolderSize(file: File?): Long {
        if (file == null) {
            return 0
        }

        var size: Long = 0
        try {
            val fileList = file!!.listFiles()
            for (i in fileList.indices) {
                // 如果下面还有文件
                size = if (fileList[i].isDirectory) {
                    size + getFolderSize(fileList[i])
                } else {
                    size + fileList[i].length()
                }
            }
        } catch (e: java.lang.Exception) {
            e.printStackTrace()
        }
        return size
    }

    /**
     * 删除总共的缓存
     */
    fun deleteTotalCacheSize(context: Context) {
        runBlocking {
            coroutineScope {
                withContext(Dispatchers.IO) {
                    context.cacheDir.deleteRecursively()
                    context.filesDir.deleteRecursively()
//                    if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
//                        context.externalCacheDir?.deleteRecursively()
//                    }
                }
            }
        }
    }

    /**
     * 格式化单位
     */
    fun getFormatSize(size: Double): String? {
        val kiloByte = size / 1024
        if (kiloByte < 1) {
            return size.toString() + "Byte"
        }
        val megaByte = kiloByte / 1024
        if (megaByte < 1) {
            val result1 = BigDecimal(kiloByte.toString())
            return result1.setScale(2, BigDecimal.ROUND_HALF_UP)
                .toPlainString().toString() + "KB"
        }
        val gigaByte = megaByte / 1024
        if (gigaByte < 1) {
            val result2 = BigDecimal(megaByte.toString())
            return result2.setScale(1, BigDecimal.ROUND_HALF_UP)
                .toPlainString().toString() + "MB"
        }
        val teraBytes = gigaByte / 1024
        if (teraBytes < 1) {
            val result3 = BigDecimal(gigaByte.toString())
            return result3.setScale(2, BigDecimal.ROUND_HALF_UP)
                .toPlainString().toString() + "GB"
        }
        val result4 = BigDecimal(teraBytes)
        return result4.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString()
            .toString() + "TB"
    }


    /**
     * 保存图片到本地相册
     */
    fun saveBitmapToGalley(context: Context, bitmap: Bitmap) {

        try {
            var parentDir: File
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
                    parentDir = context.getExternalFilesDir(Environment.DIRECTORY_DCIM)!!
                } else {
                    return
                }
            } else {
                parentDir =
                    Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM)
            }

            var fileName = "firend.jpg"
            var file = File(parentDir, fileName)
            val contentValues = ContentValues()
            contentValues.put(MediaStore.Images.Media.DISPLAY_NAME, fileName)
            contentValues.put(MediaStore.Images.Media.MIME_TYPE, "image/JPEG")
            //兼容Android Q和以下版本
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                //android Q中不再使用DATA字段，而用RELATIVE_PATH代替
                //RELATIVE_PATH是相对路径不是绝对路径
                //DCIM是系统文件夹，关于系统文件夹可以到系统自带的文件管理器中查看，不可以写没存在的名字
                contentValues.put(MediaStore.Images.Media.RELATIVE_PATH, Environment.DIRECTORY_DCIM)
                var uri = context.contentResolver.insert(
                    MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                    contentValues
                )
//                LogUtil.v("-------uri= " + uri)
                if (uri != null) {
                    //若生成了uri，则表示该文件添加成功
                    //使用流将内容写入该uri中即可
                    val outputStream = context.contentResolver.openOutputStream(uri)
                    if (outputStream != null) {
                        bitmap.compress(Bitmap.CompressFormat.JPEG, 90, outputStream)
                        outputStream.flush()
                        outputStream.close()
                    }
                }
            } else {
                contentValues.put(MediaStore.Images.Media.DATA, Environment.DIRECTORY_DCIM)
                MediaStore.Images.Media.insertImage(
                    context.contentResolver,
                    bitmap,
                    fileName,
                    null
                )

                var outputStream = FileOutputStream(file)
                if (file.exists()) {
                    file.delete()
                } else {
                    file.createNewFile()
                }
                bitmap.compress(Bitmap.CompressFormat.JPEG, 90, outputStream)
                outputStream.flush()
                outputStream.close()
            }
//            LogUtil.e("------ " + file?.toUri())

//            context.sendBroadcast(
//                Intent(
//                    Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,
//                    file?.toUri()
//                )
//            )
        } catch (e: java.lang.Exception) {
            e.printStackTrace()
        }
    }


    private var fileWriter: FileWriter? = null

    suspend fun writeToFile(message: String, fileName: String) {
        withContext(Dispatchers.IO) {
            try {
                val file = File(
                    Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS),
                    fileName
                )
                fileWriter = FileWriter(file, true) // true for append mode
                fileWriter!!.append("$message\n")
                fileWriter!!.flush() // Optional, to ensure immediate writing to file
            } catch (e: IOException) {
                Log.e("------writeToFile", "Error initializing log file", e)
            }
        }
    }


}