package com.duben.microtribe.manager

import android.app.Activity
import android.app.AlertDialog
import android.content.Context
import android.content.DialogInterface
import android.content.Intent
import android.content.pm.PackageManager
import android.content.pm.ResolveInfo
import android.net.Uri
import android.os.Build
import android.provider.Settings
import androidx.annotation.RequiresApi
import androidx.core.content.FileProvider
import com.downloader.Error
import com.downloader.OnDownloadListener
import com.downloader.PRDownloader
import com.duben.microtribe.MintsApplication
import com.duben.microtribe.R
import com.duben.microtribe.ui.widgets.DownloadProgressDialog
import com.duben.microtribe.utils.CacheUtil
import com.duben.microtribe.utils.FileUtils
import com.duben.microtribe.utils.MD5
import java.io.File

/**
 * apk下载管理
 */
class DownloadApkManager private constructor() {

    companion object {
        val instance: DownloadApkManager by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
            DownloadApkManager()
        }
    }

    private var downloadProgressDialog: DownloadProgressDialog? = null
    private var mDownloadListener: OnMyDownloadListener? = null
    private var mSpeedTestListener: OnSpeedTestListener? = null

    private var apkName = ""
    private var cachePath = MintsApplication.getContext().externalCacheDir?.path + "/Download/"
    private var canOnceInstallApk = false//8.0以上系统 防止首次授权时 未安装apk调用

    private var activity: Activity? = null

    /**
     * 下载apk
     *
     * url：下载地址
     */
    fun downloadApk(activity: Activity, url: String) {
        this.activity = activity
        apkName = MD5.GetMD5Code(
            System.currentTimeMillis().toString() + UserManager.getInstance().userID
        ) + ".apk"

        mDownloadListener?.onDownloadStart()
        this.download(url)
    }

    /**
     * 下载apk
     *
     * url：下载地址
     * name：应用名称
     */
    fun downloadApk(activity: Activity, url: String, name: String) {
        this.activity = activity
        if (name.contains(".apk")) {
            this.apkName = name
        } else {
            this.apkName = "$name.apk"
        }

        // 判断apk是否存在
        if (isFileExist("$name.apk")) {
            preInstallApk()
            return
        }

        mDownloadListener?.onDownloadStart()
        this.download(url)
    }

    private fun isFileExist(apkName: String): Boolean {
        val file = File(cachePath + apkName)
        return file.exists()
    }

    /**
     * 防止首次授权未知来源权限时 未安装apk调用
     */
    fun tryOnceInstallApk() {
        try {
            if (canOnceInstallApk && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                val context = MintsApplication.getContext()
                val haveInstallPermission = context.packageManager.canRequestPackageInstalls()
                if (haveInstallPermission) {
                    installApk()
                    canOnceInstallApk = false
                }
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    private fun download(url: String) {
        if (activity == null) return

        downloadProgressDialog = DownloadProgressDialog(activity!!)
        downloadProgressDialog!!.show()

        val context = MintsApplication.getContext()
        PRDownloader.download(url, cachePath, apkName)
            .build()
            .setOnProgressListener { progress ->
                if (activity != null && !activity!!.isFinishing) {
                    downloadProgressDialog?.setProgress(progress)
                }
            }
            .start(object : OnDownloadListener {
                override fun onDownloadComplete() {
                    if (activity != null && !activity!!.isFinishing) {
                        downloadProgressDialog?.dismiss()
                        try {
                            mDownloadListener?.onDownloadSuccess(cachePath + apkName)

                            preInstallApk()
                        } catch (e: Exception) {
                            e.printStackTrace()
                        }
                    }
                }

                override fun onError(error: Error) {
                    if (activity != null && !activity!!.isFinishing) {
                        downloadProgressDialog?.dismiss()
                        CacheUtil.clearAllCache()
                    }
                }
            })
    }

    fun speedTest(_activity: Activity, url: String) {
        this.activity = _activity
        this.apkName = "speedtest"

        mSpeedTestListener?.onSpeedTestStart()

        PRDownloader.download(url, cachePath, apkName)
            .build()
            .setOnProgressListener { progress ->
                mSpeedTestListener?.onProgress(progress.currentBytes)
            }
            .start(object : OnDownloadListener {
                override fun onDownloadComplete() {
                    mSpeedTestListener?.onSpeedTestOver()

                    FileUtils.deleteFile(cachePath, apkName)
                }

                override fun onError(error: Error) {
                    mSpeedTestListener?.onSpeedTestOver()
                }
            })
    }

    /**
     * 预安装，授权校验
     */
    private fun preInstallApk() {
        if (activity == null) return
        val context = MintsApplication.getContext()
        // 8.0以上系统设置安装未知来源权限
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val haveInstallPermission = context.packageManager.canRequestPackageInstalls()
            if (!haveInstallPermission) {
                showAlert(
                    activity!!, "安装权限", "需要打开允许来自此来源，请去设置中开启此权限"
                ) { _, _ ->
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                        //此方法需要API>=26才能使用
                        toInstallPermissionSettingIntent()
                    }
                }
                return
            }
        }

        installApk()
    }

    /**
     * 授权提示框
     */
    private fun showAlert(
        context: Context,
        title: String,
        message: String,
        listener: DialogInterface.OnClickListener?
    ) {
        val builder = AlertDialog.Builder(context)
        builder.setTitle(title)
        builder.setMessage(message)
        builder.setPositiveButton("确定", listener)
        builder.setCancelable(false)
        builder.setIcon(R.mipmap.ic_launcher_main)
        val dialog = builder.create()
        dialog.show()
    }

    /**
     * 跳转安装未知来源权限页面
     */
    @RequiresApi(api = Build.VERSION_CODES.O)
    private fun toInstallPermissionSettingIntent() {
        if (activity == null) return
        canOnceInstallApk = true
        val context = activity!!
        val packageURI = Uri.parse("package:" + context.packageName)
        val intent = Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, packageURI)
        context.startActivity(intent)
    }

    /**
     * 安装apk包
     */
    private fun installApk() {
        if (activity == null) return
        try {
            val context = activity!!
            val intent = Intent(Intent.ACTION_VIEW)
            val file = File(cachePath + apkName)
            intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
            val apkUri: Uri
            if (Build.VERSION.SDK_INT >= 24) {
                apkUri =
                    FileProvider.getUriForFile(context, context.packageName + ".fileprovider", file)
                intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
            } else {
                apkUri = Uri.fromFile(file)
            }
            intent.setDataAndType(apkUri, "application/vnd.android.package-archive")

            // 华为手机适配
            // 查询所有符合 intent 跳转目标应用类型的应用，注意此方法必须放置在 setDataAndType 方法之后
            val resolveLists: List<ResolveInfo> = context.packageManager.queryIntentActivities(
                intent,
                PackageManager.MATCH_DEFAULT_ONLY
            )
            // 然后全部授权
            for (resolveInfo in resolveLists) {
                val packageName = resolveInfo.activityInfo.packageName
                context.grantUriPermission(
                    packageName,
                    apkUri,
                    Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
                )
            }
            context.startActivity(intent)
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    fun destroy() {
        this.downloadProgressDialog = null
        this.mDownloadListener = null
        this.activity = null

        PRDownloader.cancelAll()
    }

    fun setOnMyDownloadListener(onMyDownloadListener: OnMyDownloadListener?) {
        this.mDownloadListener = onMyDownloadListener
    }

    fun setOnSpeedTestListener(onSpeedTestListener: OnSpeedTestListener?) {
        this.mSpeedTestListener = onSpeedTestListener
    }

    interface OnMyDownloadListener {
        fun onDownloadStart()
        fun onDownloadSuccess(path: String)
    }

    interface OnSpeedTestListener {
        fun onSpeedTestStart()
        fun onSpeedTestOver()
        fun onProgress(currentDownloadBytes: Long)
    }
}