package com.lukouguoji.module_base.handler

import android.text.TextUtils
import android.util.Log
import com.alibaba.fastjson.JSONObject
import com.lukouguoji.module_base.MyApplication
import com.lukouguoji.module_base.http.system.SystemServiceCreator
import com.lukouguoji.module_base.http.system.`interface`.SystemCommonService

import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import okhttp3.MediaType
import okhttp3.MultipartBody
import okhttp3.RequestBody
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import java.io.*
import java.util.*
import kotlin.coroutines.CoroutineContext

class MyCrashHandler : Thread.UncaughtExceptionHandler, CoroutineScope {
    private val job = Job()
    override val coroutineContext: CoroutineContext
        get() = Dispatchers.Main + job

    override fun uncaughtException(t: Thread, e: Throwable) {
        Log.e(
            "程序出现异常了", """
     Thread = ${t.name}
     Throwable = ${e.message}
     """.trimIndent()
        )
        val stackTraceInfo = getStackTraceInfo(e)
        Log.e("stackTraceInfo", stackTraceInfo)
        saveThrowableMessage(stackTraceInfo)
    }

    /**
     * 获取错误的信息
     *
     * @param throwable
     * @return
     */
    private fun getStackTraceInfo(throwable: Throwable): String {
        var pw: PrintWriter? = null
        val writer: Writer = StringWriter()
        try {
            pw = PrintWriter(writer)
            throwable.printStackTrace(pw)
        } catch (e: Exception) {
            return ""
        } finally {
            pw?.close()
        }
        return writer.toString()
    }

    private val logFilePath = rootPath
    private fun saveThrowableMessage(errorMessage: String) {
        if (TextUtils.isEmpty(errorMessage)) {
            return
        }
        val file = File(logFilePath)
        if (!file.exists()) {
            val mkdirs = file.mkdirs()
            if (mkdirs) {
                writeStringToFile(errorMessage, file)
            }
        } else {
            writeStringToFile(errorMessage, file)
        }
    }

    private fun writeStringToFile(errorMessage: String, file: File) {
        Thread {
            var outputStream: FileOutputStream? = null
            try {
                val inputStream = ByteArrayInputStream(errorMessage.toByteArray())
                var outFile = File(file, System.currentTimeMillis().toString() + ".txt")

                outputStream = FileOutputStream(outFile)
                var len = 0
                val bytes = ByteArray(1024)
                while (inputStream.read(bytes).also { len = it } != -1) {
                    outputStream.write(bytes, 0, len)
                }
                outputStream.flush()
                Log.e("程序出异常了", "写入本地文件成功：" + file.absolutePath)
//                sendCrashLog(outFile)

            } catch (e: FileNotFoundException) {
                e.printStackTrace()
            } catch (e: IOException) {
                e.printStackTrace()
            } finally {
                if (outputStream != null) {
                    try {
                        outputStream.close()
                    } catch (e: IOException) {
                        e.printStackTrace()
                    }
                }
            }
        }.start()
    }//用于获取SDCard/Android/data/你的应用的包名/files/ 目录

    //获取根目录
    private val rootPath: String
        private get() {
            //用于获取SDCard/Android/data/你的应用的包名/files/ 目录
            var externalFileRootDir = MyApplication.context.getExternalFilesDir(null)
            /*do {
                externalFileRootDir = Objects.requireNonNull(externalFileRootDir)!!.parentFile
            } while (Objects.requireNonNull(externalFileRootDir)!!.absolutePath.contains("/Android"))*/
            val saveDir = Objects.requireNonNull(externalFileRootDir)!!.absolutePath
            return "$saveDir/aerologic_error_log"
        }

    /**
     * 发送错误日志
     */
    /*private fun sendCrashLog(file: File) {
        var logBody = RequestBody.create(MediaType.parse("multipart/form-data"), file)

        val remark = "手机厂商：${android.os.Build.BRAND} \n 手机型号：${android.os.Build.MODEL}"

        var requestBody = MultipartBody.Builder().setType(MultipartBody.FORM)
            .addFormDataPart("versionNum", "${CommUtils.getVersionCode()}")
            .addFormDataPart("versionCode", CommUtils.getVersionName())
            .addFormDataPart("remark", remark)
            .addFormDataPart("type", "android")
            .addFormDataPart("file", file.name, logBody).build()

        val commonService = SystemServiceCreator.create<SystemCommonService>()
        commonService.upload(requestBody).enqueue(object : Callback<JSONObject> {
            override fun onResponse(
                call: Call<JSONObject>,
                response: Response<JSONObject>
            ) {
                val data = response.body()
                data?.get("status")?.let {
                    if (it == 200) {
                        Log.e("程序出异常了", "错误日志上传远程服务器成功！ 路径：" + file.absolutePath)
                    }
                }
            }

            override fun onFailure(call: Call<JSONObject>, t: Throwable) {
                t.printStackTrace()
            }
        })
    }*/
}