package com.ydl.ydlcommon.utils

import android.Manifest
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.provider.Settings
import androidx.core.content.FileProvider
import com.tbruyelle.rxpermissions2.RxPermissions
import com.ydl.ydlcommon.bean.VersionData
import com.yidianling.common.tools.ToastUtil
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.net.HttpURLConnection
import java.net.MalformedURLException
import java.net.URL

/**
 * apk安装工具类
 */
class ApkInstallTool {

    private var activity : Activity? = null

    private var listener: UpdateProgressListener? = null

    private var updateData: VersionData? = null

    private var isDownload = true

    fun start(activity : Activity?, version: VersionData?, listener: UpdateProgressListener?){
        this.activity = activity
        this.listener = listener
        this.updateData = version

        checkIsAndroidO(activity)
    }

    interface UpdateProgressListener {
        fun progress(progress: Int)

        fun startLoad()
    }

    /**
     * 判断是否是8.0,8.0需要处理未知应用来源权限问题,否则直接安装
     */
     private fun checkIsAndroidO(context: Activity?) {
        if (context == null) return
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val b = context.packageManager.canRequestPackageInstalls()
            if (b) {
                startDownload()//安装应用的逻辑
            } else {
                //请求安装未知应用来源的权限
                context.runOnUiThread {
                    RxPermissions(context)
                        .requestEach(Manifest.permission.REQUEST_INSTALL_PACKAGES)
                        .subscribe { permission ->
                            if (permission.granted) {
                                    startDownload()
                                } else if (permission.shouldShowRequestPermissionRationale) {
                                    checkIsAndroidO(context)
                                } else {
                                    ToastUtil.toastLong(context, "在线更新，请允许开启系统未知来源安装")
                                    val intent = Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES)
                                    context.startActivity(intent)
                                }
                            }
                }
            }
        } else {
            startDownload()
        }

    }

    /**
     * 开始下载
     */
    fun startDownload(){
        DownloadApkThread().start()
        listener?.startLoad()
    }

    companion object{
        /**
         * 通过隐式意图调用系统安装程序安装APK
         * 兼容7.0
         */
        fun installApk(filePath : String,context: Context?) {

            setPermission(filePath)
            val file = File(filePath)
            val intent = Intent(Intent.ACTION_VIEW)
            // 由于没有在Activity环境下启动Activity,设置下面的标签
            intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //判读版本是否在7.0以上
                //参数1 上下文, 参数2 Provider主机地址 和配置文件中保持一致   参数3  共享的文件
                val apkUri = context?.let {
                    FileProvider.getUriForFile(
                        it,
                        "${it.applicationContext.packageName}.fileprovider",
                        file
                    )
                }
                //添加这一句表示对目标应用临时授权该Uri所代表的文件
                intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
                intent.setDataAndType(apkUri, "application/vnd.android.package-archive")
            } else {
                intent.setDataAndType(
                    Uri.fromFile(file),
                    "application/vnd.android.package-archive"
                )
            }
            context?.startActivity(intent)
        }

        /**
         * 提升读写权限
         * @param filePath 文件路径
         * @return
         * @throws IOException
         */
        private fun setPermission(filePath: String) {
            val command = "chmod 777 $filePath"
            val runtime = Runtime.getRuntime()
            try {
                runtime.exec(command)
            } catch (e: IOException) {
                e.printStackTrace()
            }

        }
    }

    fun cancleDown(){
        isDownload = false
        listener = null
    }

    /**
     * 下载文件线程
     */
    inner class DownloadApkThread : Thread() {
        override fun run() {
            try {
                // 判断SD卡是否存在
                if (FileUtil2.ExistSDCard()) {
                    // 获得存储卡的路径
                    var downloadPath = FileUtil2.getLocalStorePath("download")
                    val url = URL(updateData?.installLink)
                    //URL url = new URL("http://d2.eoemarket.com/app0/16/16371/apk/1353803.apk");
                    // 创建连接
                    val conn = url.openConnection() as HttpURLConnection
                    conn.connect()
                    // 获取文件大小
                    val length = conn.contentLength
                    // 创建输入流
                    val `is` = conn.inputStream

                    val file = File(downloadPath)
                    // 判断文件目录是否存在
                    if (!file.exists()) {
                        file.mkdir()
                    }

                    var apkName = "ydl-user-" + updateData?.ver + ".apk"
                    val apkFile = File(downloadPath, apkName)
                    val fos = FileOutputStream(apkFile)
                    var count = 0
                    // 缓存
                    val buf = ByteArray(1024)
                    // 写入到文件中
                    do {
                        val numread = `is`.read(buf)
                        count += numread
                        // 计算进度条位置
                        val progress = (count.toFloat() / length * 100).toInt()
                        // 更新进度
                        listener?.progress(progress)
                        if (numread <= 0 && listener!=null) {
                            // 下载完成
                            installApk(
                                apkFile.absolutePath,
                                activity
                            )
                            listener?.progress(100)
                            break
                        }
                        // 写入文件
                        fos.write(buf, 0, numread)
                    } while (isDownload)// 点击取消就停止下载.
                    fos.close()
                    `is`.close()
                }
            } catch (e: MalformedURLException) {
                e.printStackTrace()
            } catch (e: IOException) {
                e.printStackTrace()
            }
        }
    }

}
