package com.secspace.lib.common.function

import android.app.Activity
import android.content.Context
import android.content.pm.PackageManager
import android.os.Build
import android.os.Handler
import android.os.Looper
import android.os.SystemClock
import com.secspace.lib.common.R
import com.secspace.lib.common.dialog.LoadingDialog
import com.secspace.lib.common.env.SEnvironment
import com.secspace.lib.common.function.ActivationHelper.ActivationListener
import com.secspace.lib.common.function.ActivationHelper.active
import com.secspace.lib.common.function.DialogManager.MessageListener
import com.secspace.lib.common.function.DialogManager.showActivateLoseDialog
import com.secspace.lib.common.utils.*
import com.secspace.log.Log
import com.secspace.mdmengine.api.manager.MdmFactoryManager
import com.skr.activation.network.linstener.CheckActiveStatusListener
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import java.io.File

object WorkManager {
    private val TAG = "SecSpaceWorkManager"
    private lateinit var mContext: Context
    private val mHandler: Handler = Handler(Looper.getMainLooper(), Handler.Callback { true })
    private var mEnterTime: Long = 0
    private var isChecksCompleted = false

    fun enter(launcher: Activity?) {
        mContext = launcher!!.applicationContext
        val isMdmInitialized = Prefs.isMdmInitializedWhenEnter(mContext)
        if (isChecksCompleted && isMdmInitialized) {
            Log.i(TAG, "isMdmInitialized: $isMdmInitialized, isChecksCompleted:$isChecksCompleted")
            return
        }
        mEnterTime = SystemClock.uptimeMillis()
        //检查中间件是否是最新的
        if (!DpmHelper.getInstance(mContext).isMiddlewareLatest) {
            DialogManager.showInstallMiddleWare(launcher)
            return
        }

        DpmHelper.getInstance(mContext).initMiddleWare()

        //检查中间件是否激活
        if (!DpmHelper.getInstance(mContext).isMiddlewareDPMActived) {
            MdmFactoryManager.getInstance().deviceSettingsManager.setSilentActiveAdmin(DpmHelper.getInstance(mContext).middleWareAdmin)
            Log.i(TAG, "silent active middleware")
        }
        //安装耗时，检查是否都是最新的
        if (!DpmHelper.getInstance(mContext).isMiddlewareLatest) {
            Log.i(TAG, "will install delay")
            mHandler.postDelayed({ enter(launcher) }, 2000)
            return
        }
        LoadingDialog.getInstance(launcher).show("切换中")
        GlobalScope.launch(Dispatchers.IO) {
            openAccessibility(launcher)
            SwitchInMdm.onInit(launcher)
            activate(launcher)
//            checkLocalUpdateFile() //检查本地更新文件
            delay(5000)
            ActivationHelper.checkActivate(launcher, EduCheckActiveStatusListener(launcher))
        }
        isChecksCompleted = true
        Prefs.setMdmInitializedWhenEnter(mContext, true)
    }

    fun activate(activity: Activity) {
        active(activity, object : ActivationListener {
            override fun activationFailed() {
                showActivateLoseDialog(activity, activity.getString(R.string.common_remind)
                        , activity.getString(R.string.dialog_tip_activate_lose), object : MessageListener {
                    override fun onPositive() {
                        IntentUtil.startExitService(activity)
                    }

                    override fun onNegative() {}
                })
            }

            override fun activated() {}
        }, false)
    }

    fun exit(context: Context?) {
        GlobalScope.launch(Dispatchers.IO) {
            context?.let { SwitchOutMdm.onExit(it) }
        }
    }

    private fun hasPermissions(permissions: Array<String>, packageName: String): Boolean {
        if (Build.VERSION.SDK_INT < 23) {
            return true
        } else {
            val length = permissions.size
            for (i in 0 until length) {
                val permission = permissions[i]
                if (mContext.packageManager.checkPermission(permission, packageName) != PackageManager.PERMISSION_GRANTED) {
                    return false
                }
            }
            return true
        }
    }

    /**
     * 检查本地是否有更新文件，有且版本号高则更新
     */
    private fun checkLocalUpdateFile() {
        Log.d(TAG, "check local update file")
        val dir = File(mContext.getExternalFilesDir(""), "Download")
        if (!dir.exists()) {
            Log.i(TAG, "Download dir is not exist.")
            return
        }
        val files = dir.listFiles()
        if (files == null || files.size == 0) {
            Log.i(TAG, "No file")
            return
        }
        var updateFile: File? = null
        val currentVCode = PkgManager.getInstance(mContext).getVersionCodeFromPackage(mContext.packageName)
        var newVCode = -1
        for (file: File in files) {
            val fileCode = PkgManager.getInstance(mContext).getStorageApkVersionCode(file.absolutePath)
            if (newVCode < fileCode) {
                newVCode = fileCode
                updateFile = file
            }
        }
        if (updateFile == null) {
            Log.i(TAG, "No update file")
            return
        }
        Log.i(TAG, String.format("new version(%d),old version(%d)", newVCode, currentVCode))
        if (newVCode <= currentVCode) {
            Log.i(TAG, "No Update.")
            return
        }
        Log.i(TAG, "Will install update File: " + updateFile.absolutePath)
        ToastUtil.showShort(mContext, "更新中...")
        install(updateFile.absolutePath)
    }

    private fun pathFromAssets(name: String): String {
        return mContext.externalCacheDir.absolutePath + File.separator + name
    }

    private fun install(path: String) {
        PkgManager.getInstance(mContext).installByInstaller(path)
    }

    /**
     * 安装中间件
     */
    fun installMiddleWare(context: Context) {
        val path = pathFromAssets(SEnvironment.getMiddleWareNameForAssets())
        FileUtil.copyFileFromAssets(context, SEnvironment.getMiddleWareNameForAssets(), path)
        install(path)
    }

    fun removeForbidden(context: Context) {
        Prefs.setMdmInitializedWhenEnter(context, false)
        GlobalScope.launch(Dispatchers.IO) {
            SwitchOutMdm.onExit(context)
            UninstallUtil.removeForbidden(context)
        }
    }

    internal class EduCheckActiveStatusListener(var activity: Activity) : CheckActiveStatusListener {
        override fun needActivate() {
            GlobalScope.launch(Dispatchers.Main) {
                val isActivateLocal = ActivationHelper.isProbationFromLocal(activity)
                if (isActivateLocal) {
                    return@launch
                }
                DialogManager.showBuyCodeDialog(activity)
//                DialogManager.showActivateLoseDialog(activity, activity.getString(R.string.common_remind), activity.getString(R.string.dialog_tip_activate_lose), object : DialogManager.MessageListener {
//                    override fun onPositive() {
//                        IntentUtil.startExitService(activity)
//                        removeForbidden(activity)
//                    }
//
//                    override fun onNegative() {
//                        ActivationHelper.active(activity, object : ActivationHelper.ActivationListener {
//                            override fun activated() {
//                                IntentUtil.startEduLauncher(activity)
//                            }
//
//                            override fun activationFailed() {
//                                IntentUtil.startExitService(activity)
//                                removeForbidden(activity)
//                            }
//                        }, true)
//                        removeForbidden(activity)
//                    }
//                })
            }
        }

        override fun trialCodeWillPastDue() {
            Log.i(TAG, "trialCodeWillPastDue: ")
        }

        override fun hasActived() {
            Log.i(TAG, "hasActived: ")
        }

        override fun serverError() {
            Log.i(TAG, "serverError: ")
        }

        override fun onError(throwable: Throwable) {
            Log.i(TAG, "onError: ")
        }

    }
}