package com.zxhl.cms.utils

import android.app.AppOpsManager
import android.app.NotificationManager
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.provider.Settings
import androidx.annotation.RequiresApi
import androidx.core.app.NotificationManagerCompat
import java.lang.reflect.InvocationTargetException

class NotificationAccess {

    companion object {

        @JvmStatic
        fun isNotificationEnabled(context: Context): Boolean {
            NotificationManagerCompat.from(context).areNotificationsEnabled()
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
                return true
            }
            return if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
                isEnableV19(context)
            } else {
                isEnableV26(context)
            }
        }

        @RequiresApi(api = Build.VERSION_CODES.KITKAT)
        private fun isEnableV19(context: Context): Boolean {
            val mAppOps = context.getSystemService(Context.APP_OPS_SERVICE) as AppOpsManager
            val appInfo = context.applicationInfo
            val pkg = context.applicationContext.packageName
            val uid = appInfo.uid
            var appOpsClass: Class<*>? = null
            try {
                appOpsClass = Class.forName(AppOpsManager::class.java.name)
                val checkOpNoThrowMethod = appOpsClass.getMethod(
                    CHECK_OP_NO_THROW,
                    Integer.TYPE,
                    Integer.TYPE,
                    String::class.java
                )
                val opPostNotificationValue = appOpsClass.getDeclaredField(OP_POST_NOTIFICATION)
                val value = opPostNotificationValue[Int::class.java] as Int
                return checkOpNoThrowMethod.invoke(
                    mAppOps,
                    value,
                    uid,
                    pkg
                ) as Int == AppOpsManager.MODE_ALLOWED
            } catch (e: ClassNotFoundException) {
                e.printStackTrace()
            } catch (e: NoSuchMethodException) {
                e.printStackTrace()
            } catch (e: NoSuchFieldException) {
                e.printStackTrace()
            } catch (e: InvocationTargetException) {
                e.printStackTrace()
            } catch (e: IllegalAccessException) {
                e.printStackTrace()
            }
            return false
        }

        private fun isEnableV26(context: Context): Boolean {
            val appInfo = context.applicationInfo
            val pkg = context.applicationContext.packageName
            val uid = appInfo.uid
            return try {
                val notificationManager =
                    context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
                val sServiceField = notificationManager.javaClass.getDeclaredMethod("getService")
                sServiceField.isAccessible = true
                val sService = sServiceField.invoke(notificationManager)
                val method = sService.javaClass.getDeclaredMethod(
                    "areNotificationsEnabledForPackage", String::class.java, Integer.TYPE
                )
                method.isAccessible = true
                method.invoke(sService, pkg, uid) as Boolean
            } catch (e: Exception) {
                true
            }
        }

        /**
         * 去设置里手动打开Notification权限
         *
         * @param context
         */
        @JvmStatic
        fun toNotificationSetting(context: Context) {
            val localIntent = Intent()
            ///< 直接跳转到应用通知设置的代码
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                localIntent.action = Settings.ACTION_APP_NOTIFICATION_SETTINGS
                localIntent.putExtra(Settings.EXTRA_APP_PACKAGE, context.packageName)
            } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP &&
                Build.VERSION.SDK_INT < Build.VERSION_CODES.O
            ) {
                localIntent.action = "android.settings.APP_NOTIFICATION_SETTINGS"
                localIntent.putExtra("app_package", context.packageName)
                localIntent.putExtra("app_uid", context.applicationInfo.uid)
            } else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT) {
                localIntent.action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS
                localIntent.addCategory(Intent.CATEGORY_DEFAULT)
                localIntent.data = Uri.parse("package:" + context.packageName)
            } else {
                ///< 4.4以下没有从app跳转到应用通知设置页面的Action，可考虑跳转到应用详情页面,
                localIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                if (Build.VERSION.SDK_INT >= 9) {
                    localIntent.action = "android.settings.APPLICATION_DETAILS_SETTINGS"
                    localIntent.data = Uri.fromParts("package", context.packageName, null)
                } else if (Build.VERSION.SDK_INT <= 8) {
                    localIntent.action = Intent.ACTION_VIEW
                    localIntent.setClassName(
                        "com.android.settings",
                        "com.android.setting.InstalledAppDetails"
                    )
                    localIntent.putExtra(
                        "com.android.settings.ApplicationPkgName",
                        context.packageName
                    )
                }
            }
            context.startActivity(localIntent)
        }


        private const val CHECK_OP_NO_THROW = "checkOpNoThrow"

        private const val OP_POST_NOTIFICATION = "OP_POST_NOTIFICATION"
    }
}