package com.gh.gamecenter.common.utils

import android.Manifest
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.content.pm.PermissionInfo
import android.net.Uri
import android.os.Build
import android.provider.Settings
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.fragment.app.FragmentActivity
import com.alibaba.android.arouter.launcher.ARouter
import com.gh.gamecenter.common.R
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.core.AppExecutor
import com.gh.gamecenter.core.provider.IActivationProvider
import com.gh.gamecenter.core.provider.IAppProvider
import com.gh.gamecenter.core.provider.IDirectProvider
import com.gh.gamecenter.core.utils.EmptyCallback
import com.gh.gamecenter.core.utils.SPUtils
import com.tbruyelle.rxpermissions2.RxPermissions

object PermissionHelper {

    const val INSTALL_PERMISSION_CODE = 100

    const val PERMISSION_GET_INSTALLED_LIST = "com.android.permission.GET_INSTALLED_APPS"

    private const val HINT_CHECK_USAGE = "查看权限应用场景"

    /**
     * 在执行 emptyCallback 的 action 前先判断是否有获取已安装列表的权限
     */
    @SuppressLint("CheckResult")
    @JvmStatic
    fun checkGetInstalledAppsListBeforeAction(
        context: Context,
        emptyCallback: EmptyCallback
    ) {
        if (context is AppCompatActivity && isGetInstalledListPermissionDisabled(context)) {
            showDialogBeforeRequestingGetInstalledListDialog(context, emptyCallback)
        } else {
            emptyCallback.onCallback()
        }
    }

    /**
     * 请求获取已安装列表权限
     */
    @SuppressLint("CheckResult")
    fun requestGetInstalledAppsListPermission(context: FragmentActivity, emptyCallback: EmptyCallback) {
        tryWithDefaultCatch {
            val rxPermission = RxPermissions(context)
            rxPermission
                .requestEachCombined(PERMISSION_GET_INSTALLED_LIST)
                .subscribe { permission ->
                    when {
                        permission.granted -> {
                            emptyCallback.onCallback()
                        }
                        permission.shouldShowRequestPermissionRationale -> {
                            // do nothing
                        }
                        else -> {
                            val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
                            intent.data = Uri.parse("package:" + context.packageName)
                            context.startActivity(intent)
                        }
                    }
                }
        }
    }

    @SuppressLint("CheckResult")
    @JvmStatic
    fun checkStoragePermissionBeforeAction(context: Context, emptyCallback: EmptyCallback) {
        if (context is FragmentActivity) {
            if (context.checkCallingOrSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
                && context.checkCallingOrSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
            ) {
                emptyCallback.onCallback()
                SPUtils.setBoolean(Constants.SP_USER_HAS_PERMANENTLY_DENIED_STORAGE_PERMISSION, false)
            } else {
                showDialogBeforeRequestingStorageDialog(context, emptyCallback)
            }
        }
    }

    @SuppressLint("CheckResult")
    private fun checkStoragePermissionBeforeAction(context: FragmentActivity, emptyCallback: EmptyCallback) {
        tryWithDefaultCatch {
            val rxPermission = RxPermissions(context)
            rxPermission
                .requestEachCombined(
                    Manifest.permission.WRITE_EXTERNAL_STORAGE,
                    Manifest.permission.READ_EXTERNAL_STORAGE
                )
                .subscribe { permission ->
                    when {
                        permission.granted -> {
                            // 获得存储权限后刷新 gid 避免下载仍需实名
                            (ARouter.getInstance().build(RouteConsts.provider.app).navigation() as? IAppProvider)?.refreshGid()

                            // 延迟 100ms 确保能够正常获取到 gid
                            AppExecutor.uiExecutor.executeWithDelay({
                                emptyCallback.onCallback()
                            }, 100)
                            SPUtils.setBoolean(Constants.SP_USER_HAS_PERMANENTLY_DENIED_STORAGE_PERMISSION, false)
                        }
                        permission.shouldShowRequestPermissionRationale -> {
                            // do nothing
                        }
                        else -> {
                            if (SPUtils.getBoolean(Constants.SP_USER_HAS_PERMANENTLY_DENIED_STORAGE_PERMISSION)) {
                                val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
                                intent.data = Uri.parse("package:" + context.packageName)
                                context.startActivity(intent)
                            } else {
                                SPUtils.setBoolean(Constants.SP_USER_HAS_PERMANENTLY_DENIED_STORAGE_PERMISSION, true)
                            }
                        }
                    }
                }
        }
    }

    @SuppressLint("CheckResult")
    @JvmStatic
    fun checkReadPhoneStateAndStoragePermissionBeforeAction(context: Context, emptyCallback: EmptyCallback) {
        if (context is FragmentActivity) {
            if (context.checkCallingOrSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
                && context.checkCallingOrSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
            ) {
                emptyCallback.onCallback()
            } else {
                val rxPermission = RxPermissions(context)

                tryWithDefaultCatch {
                    rxPermission
                        .requestEachCombined(
                            Manifest.permission.WRITE_EXTERNAL_STORAGE,
                            Manifest.permission.READ_EXTERNAL_STORAGE
                        )
                        .subscribe { permission ->
                            when {
                                permission.granted -> {
                                    emptyCallback.onCallback()

                                    val provider = ARouter.getInstance().build(RouteConsts.provider.activation)
                                        .navigation() as? IActivationProvider
                                    provider?.sendActivationInfo()
                                }
                                permission.shouldShowRequestPermissionRationale -> {
                                    // do nothing
                                }
                                else -> {
                                    val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
                                    intent.data = Uri.parse("package:" + context.getPackageName())
                                    context.startActivity(intent)
                                }
                            }
                        }
                }
            }
        }
    }

    @SuppressLint("CheckResult")
    @JvmStatic
    fun checkReadPhoneStatePermissionBeforeAction(context: Context, emptyCallback: EmptyCallback) {
        emptyCallback.onCallback()
//        if (context is FragmentActivity) {
//
//            if (context.checkCallingOrSelfPermission(Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) {
//                emptyCallback.onCallback()
//            } else {
//                val rxPermission = RxPermissions(context)
//
//                tryWithDefaultCatch {
//                    rxPermission
//                        .requestEachCombined(Manifest.permission.READ_PHONE_STATE)
//                        .subscribe { permission ->
//                            when {
//                                permission.granted -> {
//                                    emptyCallback.onCallback()
//                                    val provider = ARouter.getInstance().build(RouteConsts.provider.activation).navigation() as? IActivationProvider
//                                    provider?.sendActivationInfo()
//                                }
//                                permission.shouldShowRequestPermissionRationale -> {
//                                    // do nothing
//                                }
//                                else -> {
//                                    val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
//                                    intent.data = Uri.parse("package:" + context.getPackageName())
//                                    context.startActivity(intent)
//                                }
//                            }
//                        }
//                }
//            }
//        }
    }

    /**
     * 跳转到权限设置
     *
     * @param activity
     */
    @JvmStatic
    fun toPermissionSetting(activity: Activity) {
        if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP_MR1) {
            toSystemConfig(activity)
        } else {
            try {
                toApplicationInfo(activity)
            } catch (e: Exception) {
                e.printStackTrace()
                toSystemConfig(activity)
            }

        }
    }

    /**
     * 应用信息界面
     *
     * @param activity
     */
    private fun toApplicationInfo(activity: Activity) {
        val localIntent = Intent()
        localIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
        localIntent.action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS
        localIntent.data = Uri.fromParts("package", activity.packageName, null)
        activity.startActivity(localIntent)
    }

    /**
     * 系统设置界面
     *
     * @param activity
     */
    private fun toSystemConfig(activity: Activity) {
        try {
            val intent = Intent(Settings.ACTION_SETTINGS)
            activity.startActivity(intent)
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    private fun showDialogBeforeRequestingStorageDialog(context: FragmentActivity, emptyCallback: EmptyCallback) {
        // 是否点击外部区域触发弹窗消失
        var isCanceledByClickingOutside = true

        NewFlatLogUtils.logExternalStoragePermissionDialogAppearance()
        DialogHelper.showDialog(
            context,
            title = "权限申请",
            content = "光环助手将向您申请开启设备的存储权限，以保证能正常使用相关功能。拒绝授权将无法正常使用部分功能。",
            cancelText = "放弃",
            confirmText = "去授权",
            cancelClickCallback = {
                isCanceledByClickingOutside = false
                NewFlatLogUtils.logExternalStoragePermissionDialogAction("放弃")
            },
            confirmClickCallback = {
                isCanceledByClickingOutside = false
                checkStoragePermissionBeforeAction(context, emptyCallback)
                NewFlatLogUtils.logExternalStoragePermissionDialogAction("去授权")
            },
            extraConfig = DialogHelper.Config(hint = HINT_CHECK_USAGE),
            uiModificationCallback = {
                it.hintTv.setTextColor(ContextCompat.getColor(context, R.color.theme_font))
                it.hintTv.setOnClickListener {
                    val provider =
                        ARouter.getInstance().build(RouteConsts.provider.directUtils).navigation() as? IDirectProvider
                    provider?.directToWebView(context, Constants.PERMISSION_SCENARIO_ADDRESS, "(权限弹窗)")
                    NewFlatLogUtils.logExternalStoragePermissionDialogAction(HINT_CHECK_USAGE)
                }
                it.contentTv.setTextColor(ContextCompat.getColor(context, R.color.text_title))
            }
        )?.setOnDismissListener {
            if (isCanceledByClickingOutside) {
                NewFlatLogUtils.logExternalStoragePermissionDialogAction("点击弹窗以外空白区域")
            }
        }
    }

    private fun showDialogBeforeRequestingGetInstalledListDialog(
        context: FragmentActivity,
        emptyCallback: EmptyCallback
    ) {
        DialogHelper.showDialog(
            context,
            title = "权限申请",
            content = "光环助手将向您申请开启设备的应用列表权限，以保证能正常使用相关功能。拒绝授权将无法正常使用部分功能。",
            cancelText = "放弃",
            confirmText = "去授权",
            cancelClickCallback = null,
            confirmClickCallback = { requestGetInstalledAppsListPermission(context, emptyCallback) },
            extraConfig = DialogHelper.Config(hint = HINT_CHECK_USAGE),
            uiModificationCallback = {
                it.hintTv.setTextColor(ContextCompat.getColor(context, R.color.theme_font))
                it.hintTv.setOnClickListener {
                    val provider =
                        ARouter.getInstance().build(RouteConsts.provider.directUtils).navigation() as? IDirectProvider
                    provider?.directToWebView(context, Constants.PERMISSION_SCENARIO_ADDRESS, "(权限弹窗)")
                }
                it.contentTv.setTextColor(ContextCompat.getColor(context, R.color.text_title))
            }
        )
    }

    @JvmStatic
    fun isGetInstalledListPermissionDisabled(context: Context): Boolean {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) return false

        val permissionInfo: PermissionInfo?
        return try {
            permissionInfo = context.packageManager.getPermissionInfo(PERMISSION_GET_INSTALLED_LIST, 0)
            (permissionInfo != null
                    && permissionInfo.protectionLevel and PermissionInfo.PROTECTION_MASK_BASE == PermissionInfo.PROTECTION_DANGEROUS
                    && PackageManager.PERMISSION_GRANTED != context.checkSelfPermission(PERMISSION_GET_INSTALLED_LIST))
        } catch (e: Exception) {
            e.printStackTrace()
            false
        }
    }

    /**
     * 开启安装未知来源权限
     */
    fun toInstallPermissionSetting(activity: Activity) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
            toSystemConfig(activity)
        } else {
            val packageURI = Uri.fromParts("package", activity.packageName, null)
            val intent = Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, packageURI)
            activity.startActivityForResult(intent, INSTALL_PERMISSION_CODE)
        }
    }

    /**
     * 获取开启安装位置来源权限 Intent
     */
    fun getToInstallPermissionSettingIntent(context: Context): Intent {
        return if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
            Intent(Settings.ACTION_SETTINGS)
        } else {
            val packageURI = Uri.fromParts("package", context.packageName, null)
            Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, packageURI)
        }
    }

    /**
     * 检查添加到桌面快捷方式权限
     */
    @SuppressLint("CheckResult")
    @JvmStatic
    fun checkShortcutPermission(
        context: FragmentActivity,
        onGrantedCallback: EmptyCallback,
        onDeniedCallback: EmptyCallback
    ) {
        tryWithDefaultCatch {
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
                onGrantedCallback.onCallback()
                return
            }
            val rxPermission = RxPermissions(context)
            rxPermission
                .requestEachCombined(
                    Manifest.permission.INSTALL_SHORTCUT,
                    Manifest.permission.UNINSTALL_SHORTCUT,
                )
                .subscribe { permission ->
                    when {
                        permission.granted -> {
                            onGrantedCallback.onCallback()
                        }
                        permission.shouldShowRequestPermissionRationale -> {
                            // do nothing
                        }
                        else -> {
                            onDeniedCallback.onCallback()
                        }
                    }
                }
        }
    }

}