package com.android.launcher3.util;

import android.Manifest;
import android.app.Activity;
import android.app.AppOpsManager;
import android.app.NotificationManager;
import android.app.admin.DevicePolicyManager;
import android.content.ActivityNotFoundException;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.Color;
import android.net.Uri;
import android.os.Binder;
import android.os.Build;
import android.os.PowerManager;
import android.os.Process;
import android.os.UserHandle;
import android.provider.Settings;
import android.text.TextUtils;
import android.view.View;
import android.view.WindowManager;

import com.android.launcher3.BuildConfig;
import com.android.launcher3.accessibility.AppManagerAccessiblityService;
import com.android.launcher3.accessibility.DeviceReceiver;
import com.android.launcher3.compat.LauncherAppsCompat;

import java.lang.reflect.Method;
import java.util.List;

import androidx.core.app.NotificationManagerCompat;
import androidx.core.content.PermissionChecker;

public class PermissionUtil {

    private static final String TAG = "PermissionUtil";

    public static boolean isAdminDevice = false;

    public static boolean isBatterySaveClose = false;

    public static boolean isAccessibilitySettingsOn(Context mContext) {
        int accessibilityEnabled = 0;
        // TestService为对应的服务
        final String service = mContext.getPackageName() + "/" + AppManagerAccessiblityService.class.getCanonicalName();
        // com.z.buildingaccessibilityservices/android.accessibilityservice.AccessibilityService
        try {
            accessibilityEnabled = Settings.Secure.getInt(mContext.getApplicationContext().getContentResolver(),
                    android.provider.Settings.Secure.ACCESSIBILITY_ENABLED);

        } catch (Settings.SettingNotFoundException e) {

        }
        TextUtils.SimpleStringSplitter mStringColonSplitter = new TextUtils.SimpleStringSplitter(':');

        if (accessibilityEnabled == 1) {

            String settingValue = Settings.Secure.getString(mContext.getApplicationContext().getContentResolver(),
                    Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
            // com.z.buildingaccessibilityservices/com.z.buildingaccessibilityservices.TestService
            if (settingValue != null) {
                mStringColonSplitter.setString(settingValue);
                while (mStringColonSplitter.hasNext()) {
                    String accessibilityService = mStringColonSplitter.next();

                    if (accessibilityService.equalsIgnoreCase(service)) {
                        return true;
                    }
                }
            }
        } else {
        }

        return false;
    }


    public static boolean checkPermissionOpen(Context context, String permission) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            return PermissionChecker.checkSelfPermission(context, permission) == PermissionChecker.PERMISSION_GRANTED;
        }
        return true;
    }


    public static boolean hasPermission(Context context) {
        if (hasPermissionBelowMarshmallow(context, 24)) {
            return hasOverLayerPermission(context);
        } else {
            return false;
        }
    }


    /**
     * 6.0以下判断是否有权限
     * 理论上6.0以上才需处理权限，但有的国内rom在6.0以下就添加了权限
     * 其实此方式也可以用于判断6.0以上版本，只不过有更简单的canDrawOverlays代替
     */
    public static boolean hasPermissionBelowMarshmallow(Context context, int opType) {
        try {
            AppOpsManager manager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
            Method dispatchMethod = AppOpsManager.class.getMethod("checkOp", int.class, int.class, String.class);
            //AppOpsManager.OP_SYSTEM_ALERT_WINDOW = 24
            return AppOpsManager.MODE_ALLOWED == (Integer) dispatchMethod.invoke(
                    manager, opType, Binder.getCallingUid(), context.getApplicationContext().getPackageName());
        } catch (Exception e) {
            return false;
        }
    }


    /**
     * 检测设备管理器权限
     *
     * @param context
     * @return
     */
    public static boolean checkDeviceAdminPermission(Context context) {

        ComponentName componentName = new ComponentName(context, DeviceReceiver.class);
//        ((DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE)).
        boolean isActive = ((DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE)).isAdminActive(componentName) || isAdminDevice;
        Logger.e(TAG, "checkDeviceAdminPermission\t" + isActive);
        return isActive;
    }

    /**
     * 跳转设备管理器权限
     *
     * @param context
     */
    public static void gotoDeviceAdminPermissionSetting(Context context) {

        //打开DevicePolicyManager管理器，授权页面
        Intent intent = new Intent();
        String targetActivity = "";
        if (SystemUtils.isMIUI()) {
//            targetActivity = "com.android.settings.SubSettings";
//            intent.setAction();
            intent.setAction(Settings.ACTION_SETTINGS);

//            ComponentName cm = new ComponentName("com.android.settings",
//                    "com.android.settings.MiuiSettings");
//
//            intent.setComponent(cm);
        } else {


            targetActivity = "com.android.settings.DeviceAdminSettings";

            ComponentName cm = new ComponentName("com.android.settings",
                    targetActivity);

            intent.setComponent(cm);

            intent.setAction("android.intent.action.VIEW");
        }


        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        //设置 提示语--可不添加
//        intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, "DevicePolicyManager涉及的管理权限,一次性激活!");
        context.startActivity(intent);

    }

    /**
     * 判断是否有自启动权限
     * @param context
     * @return
     */
    public static boolean checkAutoStartUp(Context context) {

        PackageManager pm=context.getPackageManager();
        boolean haveStartup = false;
        try {
            PackageInfo pkgInfo = pm
                    .getPackageInfo(context.getPackageName(), PackageManager.GET_RECEIVERS
                            | PackageManager.GET_META_DATA);// 通过包名，返回包信息
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        haveStartup = pm.checkPermission(
                "android.permission.RECEIVE_BOOT_COMPLETED", context.getPackageName()) == PackageManager.PERMISSION_GRANTED;
        return haveStartup;

    }


    public static void gotoAutoStartUpSettings(Context context) {


        Intent intent = new Intent();
        ComponentName componentName = null;
        if (SystemUtils.isHW() || SystemUtils.isHONOR()) {
            componentName = new ComponentName("com.huawei.systemmanager", "com.huawei.systemmanager.startupmgr.ui.StartupNormalAppListActivity");
            intent.setComponent(componentName);
        } else if (SystemUtils.isSAMSUNG()) {
            intent = getLauncherAppIntent(context, "com.samsung.android.sm_cn");
        } else if (SystemUtils.isMEIZU()) {
            intent = getLauncherAppIntent(context, "com.meizu.safe");
//            componentName = new ComponentName("com.meizu.safe", "com.meizu.safe.SecurityMainActivity");
//            intent.setComponent(componentName);
        } else if (SystemUtils.isNOKIA()) {
            componentName = new ComponentName("com.evenwell.powersaving.g3", "com.evenwell.powersaving.g3.exception.PowerSaverExceptionActivity");
            intent.setComponent(componentName);
        } else if (SystemUtils.isMIUI()) {

            if (context instanceof Activity) {
                intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
//            componentName = new ComponentName("com.miui.securitycenter", "com.miui.permcenter.permissions.AppPermissionsEditorActivity");
//            intent.setComponent(componentName);
                intent.setData(Uri.parse("package:" + context.getPackageName()));
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                context.startActivity(intent);


                return;
            }

        } else if (SystemUtils.isOPPO()) {


            intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
//            componentName = new ComponentName("com.miui.securitycenter", "com.miui.permcenter.permissions.AppPermissionsEditorActivity");
//            intent.setComponent(componentName);
            intent.setData(Uri.parse("package:" + context.getPackageName()));
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(intent);

        }

        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

        try {
            context.startActivity(intent);
        } catch (Exception e) {//抛出异常就直接打开设置页面
            intent = new Intent(Settings.ACTION_SETTINGS);
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(intent);
            Logger.e(TAG, "gotoBatteryOptimize\t" + e.getMessage());
        }

    }





    public static void gotoBatteryOptimize(Context context) {
        requestIgnoreBatteryOptimizations(context);
    }


    public static void requestIgnoreBatteryOptimizations(Context context) {
        try {
            Intent intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
            intent.setData(Uri.parse("package:" + context.getPackageName()));
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(intent);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 检测电池优化是否开启 三星不支持
     *
     * @param context
     * @return
     */
    public static boolean checkBatteryOptimize(Context context) {

        boolean isIgnoring = false;
        PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
        if (powerManager != null) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                isIgnoring = powerManager.isIgnoringBatteryOptimizations(context.getPackageName());

                isIgnoring = isIgnoring || PermissionUtil.isBatterySaveClose;
                Logger.e(TAG, "checkBatteryOptimize\t" + isIgnoring);
            } else {
                isIgnoring = true;
            }
        }
        return isIgnoring;

    }


    /**
     * 判断是否开启use调试
     *
     * @param context
     * @return
     */
    public static boolean enAbleADB(Context context) {
        boolean enableAdb = (Settings.Secure.getInt(context.getContentResolver(), Settings.Secure.ADB_ENABLED, 0) > 0);

        Logger.e(TAG, "enAbleADB\t" + enableAdb);
        return enableAdb;
    }


    public static boolean checkAppUsagePermission(Context context) {
        boolean checkAppUsagePermission = hasPermissionBelowMarshmallow(context, 43);
        Logger.e(TAG, "checkAppUsagePermission\t" + checkAppUsagePermission);
        return checkAppUsagePermission;
    }

    public static void gotoAppUsagePermission(Context context) {

        Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(intent);

        Logger.e(TAG, "gotoAppUsagePermission");

    }


    private static final String ENABLED_NOTIFICATION_LISTENERS = "enabled_notification_listeners";


    /**
     * 检测是否有通知栏监听权限
     *
     * @param context
     * @return
     */
    public static boolean isNotificationListenersEnabled(Context context) {
        String pkgName = context.getPackageName();
        boolean enable = false;

        enable = NotificationManagerCompat.getEnabledListenerPackages(context).contains(pkgName);
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
            enable = true;
        }
        Logger.e(TAG, "isNotificationListenersEnabled\t" + enable);
        return enable;
    }


    public static void goToNotificationAccessSetting(Context context) {
        try {
            Intent intent = new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS");
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(intent);

        } catch (ActivityNotFoundException e) {//普通情况下找不到的时候需要再特殊处理找一次
            try {
                Intent intent = new Intent();
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                ComponentName cn = new ComponentName("com.android.settings", "com.android.settings.Settings$NotificationAccessSettingsActivity");
                intent.setComponent(cn);
                intent.putExtra(":settings:show_fragment", "NotificationAccessSettings");
                context.startActivity(intent);

            } catch (Exception e1) {
                e1.printStackTrace();
            }

        }
    }

    /**
     * 跳转辅助功能
     *
     * @param context
     */
    public static void jumpAccessiblityService(Context context) {
        Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);
        context.startActivity(intent);
    }


    /**
     * 跳转系统设置
     *
     * @param context
     */
    public static void jumpSystemSettings(Context context) {
        Intent intent = new Intent(Settings.ACTION_SETTINGS);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

        context.startActivity(intent);

    }

    public static void setDefaultL(Context context) {
        Intent intent = new Intent();

        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        //这里就是为了处置华为手机

        Logger.e(TAG, "setDefaultL");

        if (SystemUtils.isHONOR() || SystemUtils.isHW()) {
            try {
                //华为手机
                startHuaweiSettingActOfDefLauncher(context);//开启桌面设置
            } catch (Exception e1) {
                try {
                    //华为手机
                    intent.setAction(Settings.ACTION_SETTINGS);

                    context.startActivity(intent);
                } catch (Exception e2) {
                    try {
                        intent.setAction(Intent.ACTION_MAIN);
                        intent.addCategory("android.intent.category.HOME");
                        intent.setComponent(new ComponentName("android", "com.android.internal.app.ResolverActivity"));

                        context.startActivity(intent);

                        Logger.e(TAG, e2.getMessage());
                    } catch (Exception e3) {
                        Logger.e(TAG, e3.getMessage());
                    }

                }
            }
        } else {

            if (SystemUtils.isSAMSUNG() && Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
                intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
//            componentName = new ComponentName("com.miui.securitycenter", "com.miui.permcenter.permissions.AppPermissionsEditorActivity");
//            intent.setComponent(componentName);
                intent.setData(Uri.parse("package:" + context.getPackageName()));
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                context.startActivity(intent);
                return;
            }


            if (SystemUtils.isVIVO()) {
                intent.setAction(Settings.ACTION_SETTINGS);
                context.startActivity(intent);
                return;
            }

            intent.setAction(Intent.ACTION_MAIN);
            intent.addCategory("android.intent.category.HOME");
            intent.setComponent(new ComponentName("android", "com.android.internal.app.ResolverActivity"));

            context.startActivity(intent);
        }
//        }


    }

    /**
     * 设置为华为手机
     */
    private static void startHuaweiSettingActOfDefLauncher(Context activity) {
        IntentFilter localIntentFilter = new IntentFilter();
        localIntentFilter.addAction(Intent.ACTION_MAIN);//"android.intent.action.MAIN"
        localIntentFilter.addCategory(Intent.CATEGORY_HOME);//"android.intent.category.HOME"
        Intent localIntent3 = new Intent(localIntentFilter.getAction(0));
        localIntent3.addCategory(localIntentFilter.getCategory(0));
        Intent localIntent4 = new Intent();
        localIntent4.setClassName("com.android.settings", "com.android.settings.Settings$PreferredSettingsActivity");
        localIntent4.putExtra("preferred_app_package_name", activity.getPackageName());
        localIntent4.putExtra("preferred_app_class_name", activity.getClass().getName());
        localIntent4.putExtra("is_user_confirmed", true);
        localIntent4.putExtra("preferred_app_intent", localIntent3);
        localIntent4.putExtra("preferred_app_intent_filter", localIntentFilter);
        localIntent4.putExtra("preferred_app_label", "默认桌面设置");
        activity.startActivity(localIntent4);
        Logger.e(TAG, "setDefaultL1");
    }

    /**
     * 判断自己的应用程序是否为默认桌面
     */
    public static boolean isDefaultHome(Context context) {
        Intent intent = new Intent(Intent.ACTION_MAIN);//Intent.ACTION_VIEW
        intent.addCategory("android.intent.category.HOME");
        intent.addCategory("android.intent.category.DEFAULT");
        PackageManager pm = context.getPackageManager();
        ResolveInfo info = pm.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
        boolean isDefault = context.getPackageName().equals(info.activityInfo.packageName);

        Logger.e(TAG, "isDefaultHome\t" + isDefault);
        return isDefault || SystemUtils.isMIUI();
    }

    /**
     * 跳转开发者模式
     *
     * @param context
     */
    public static void gotoDeveloperChoice(Context context) {
        try {
            Intent intent = new Intent(Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(intent);
        } catch (Exception e) {
            try {
                ComponentName componentName = new ComponentName("com.android.settings", "com.android.settings.DevelopmentSettings");
                Intent intent = new Intent();
                intent.setComponent(componentName);
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                intent.setAction("android.intent.action.View");
                context.startActivity(intent);
            } catch (Exception e1) {
                try {
                    Intent intent = new Intent("com.android.settings.APPLICATION_DEVELOPMENT_SETTINGS");//部分小米手机采用这种方式跳转
                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    context.startActivity(intent);
                } catch (Exception e2) {
                    Logger.e(TAG, "gotoDeveloperChoice failed");
                }

            }

        }
    }

    public static Intent getLauncherAppIntent(Context context, String targetPackageName) {
        PackageManager manager = context.getPackageManager();
        // 指定入口,启动类型,包名
        Intent intent = new Intent(Intent.ACTION_MAIN);//入口Main
        intent.addCategory(Intent.CATEGORY_LAUNCHER);// 启动LAUNCHER,跟MainActivity里面的配置类似
        intent.setPackage(targetPackageName);//包名
        //查询要启动的Activity
        List<ResolveInfo> apps = manager.queryIntentActivities(intent, 0);
        Logger.e(TAG, "getLauncherAppIntent\t" + apps.size());
        if (apps.size() > 0) {//如果包名存在
            ResolveInfo ri = apps.get(0);
            // //获取包名
            String packageName = ri.activityInfo.packageName;
            //获取app启动类型
            String className = ri.activityInfo.name;
            //组装包名和类名
            ComponentName cn = new ComponentName(packageName, className);
            //设置给Intent
            intent.setComponent(cn);
            //根据包名类型打开Activity
            return intent;
        }
        return null;
    }

    /**
     * 判断当前应用是否分身
     *
     * @return
     */
    public static boolean isDualApk(Context context) {
        boolean isDualApk = false;

        isDualApk = checkPkg(context);


        Logger.e(TAG, "isDualApk\t" + isDualApk);
        return isDualApk;
    }

    private static boolean checkPkg(Context context) {
        try {
            if (context == null) {
                return false;
            }
            int count = 0;
            String packageName = context.getPackageName();
            PackageManager pm = context.getPackageManager();
            List<PackageInfo> pkgs = pm.getInstalledPackages(0);
            for (PackageInfo info : pkgs) {
                if (packageName.equals(info.packageName)) {
                    count++;
                }
            }
            return count > 1;
        } catch (Exception ignore) {
        }
        return false;
    }


    private static boolean hasIntent(Context context, Intent intent) {
        return !context.getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY).isEmpty();
    }

    public static void gotoSystemSetting(Context context) {
        Intent intent = new Intent(Settings.ACTION_SETTINGS);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

        context.startActivity(intent);

    }

    /**
     * 跳转vivo i管家
     *
     * @param context
     */
    public static void startVIVOManager(Context context) {
        Intent intent = new Intent();
        intent.setClassName("com.iqoo.secure", "com.iqoo.secure.MainActivity");
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(intent);
    }

    public static boolean hasOverLayerPermission(Context context) {
        boolean result = false;

        try {
            WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
            View view = new View(context);
            WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams();
            layoutParams.width = 1;
            layoutParams.height = 1;
            view.setBackgroundColor(Color.RED);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                layoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
            } else {
                layoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
            }

            windowManager.addView(view, layoutParams);

            windowManager.removeView(view);

            result = true;
        } catch (Exception e) {
            result = false;
        }

        return result;

    }
}
