package tech.starwin.utils.context_utils;

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AppOpsManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.provider.Settings;
import android.provider.Telephony;
import android.support.annotation.RequiresApi;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.content.PermissionChecker;
import android.telecom.TelecomManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;

import com.common.toolbox.tracker.TrackEvent;
import com.tbruyelle.rxpermissions2.Permission;
import com.tbruyelle.rxpermissions2.RxPermissions;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

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

import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import tech.starwin.BuildConfig;
import tech.starwin.LibConfig;
import tech.starwin.utils.LogUtils;
import tech.starwin.utils.PreferencesManager;
import tech.starwin.utils.TrackEventHelper;
import tech.starwin.utils.ui_utils.DialogFactory;

/**
 * Created by SiKang on 2018/9/20.
 * 权限管理
 */
public class PermissionsHelper {
    /**
     * 需要收集隐私数据时的必要权限
     */
    public static String[] MUST_PERMISSIONS = new String[]{

            Manifest.permission.READ_CONTACTS,
            Manifest.permission.READ_CALL_LOG,
            Manifest.permission.READ_SMS,
//            Manifest.permission.READ_EXTERNAL_STORAGE,
//            Manifest.permission.WRITE_EXTERNAL_STORAGE
            Manifest.permission.ACCESS_COARSE_LOCATION,//粗精度定位
            Manifest.permission.ACCESS_FINE_LOCATION//卫星定位
//            Manifest.permission.READ_PHONE_STATE
    };

    /**
     * 不需要申请隐私数据时的必要权限
     */
    public static String[] MUST_WHITOUT_LOG = new String[]{
            Manifest.permission.READ_CONTACTS,
//            Manifest.permission.READ_CALL_LOG,
//            Manifest.permission.READ_SMS,
//            Manifest.permission.READ_EXTERNAL_STORAGE,
//            Manifest.permission.WRITE_EXTERNAL_STORAGE
            Manifest.permission.ACCESS_COARSE_LOCATION,//粗精度定位
            Manifest.permission.ACCESS_FINE_LOCATION//卫星定位
//            Manifest.permission.READ_PHONE_STATE
    };

    /**
     * 不需要申请隐私数据时的必要权限
     */
    public static String[] CAMERA = new String[]{
            Manifest.permission.CAMERA
//            Manifest.permission.RECORD_AUDIO
    };

    /**
     * 摄像头权限
     */
    public static void checkCameraPermission(FragmentActivity activity, OnPermissionListener listener) {
        if (activity != null) {
            checkPermission(activity, CAMERA, listener);
        }
    }

    /**
     * 所有权限
     */
    public static void getAllPermissions(FragmentActivity activity, OnPermissionListener listener) {
        checkPermission(activity, new String[]{Manifest.permission.READ_CONTACTS,
                Manifest.permission.READ_CALL_LOG,
                Manifest.permission.READ_SMS,
                Manifest.permission.ACCESS_COARSE_LOCATION,//粗精度定位
                Manifest.permission.ACCESS_FINE_LOCATION,//卫星定位
                Manifest.permission.READ_PHONE_STATE, Manifest.permission.CAMERA,
                Manifest.permission.READ_EXTERNAL_STORAGE,
                Manifest.permission.WRITE_EXTERNAL_STORAGE,
                Manifest.permission.RECORD_AUDIO}, listener);
    }

    /**
     * 检查权限
     */
    public static void checkPermission(FragmentActivity activity, String[] permissions, final OnPermissionListener listener) {
        getPermission(new RxPermissions(activity),permissions , listener);
    }

    public static void checkPermission(Fragment fragment, String[] permissions, final OnPermissionListener listener) {
        getPermission(new RxPermissions(fragment), permissions, listener);
    }

    @SuppressLint("CheckResult")
    private static void getPermission(RxPermissions rxPermissions, final String[] permissions, final OnPermissionListener listener) {
        rxPermissions
                .requestEach(permissions)
                .subscribe(new Consumer<Permission>() {
                    List<Permission> allowed = new ArrayList<>();
                    List<Permission> refused = new ArrayList<>();
                    List<Permission> neverAsk = new ArrayList<>();

                    @Override
                    public void accept(Permission permission) throws Exception {
                        if (permission.granted) {
                            allowed.add(permission);
                            listener.onAllow(permission);
                            TrackEventHelper.logEvent(TrackEvent.Click.ALLOW_PERMISSION + "-" + permission.name);
                        } else if (permission.shouldShowRequestPermissionRationale) {
                            refused.add(permission);
                            listener.onRefuse(permission);
                            TrackEventHelper.logEvent(TrackEvent.Click.REFUSE_PERMISSION + "-" + permission.name);
                        } else {
                            neverAsk.add(permission);
                            listener.onRefuseAndNeverAskAgain(permission);
                            TrackEventHelper.logEvent(TrackEvent.Click.REFUSE_PERMISSION + "-" + permission.name);
                        }

                        if (allowed.size() + refused.size() + neverAsk.size() == permissions.length) {
                            listener.onFinish(allowed.toArray(new Permission[allowed.size()]),
                                    refused.toArray(new Permission[refused.size()]),
                                    neverAsk.toArray(new Permission[neverAsk.size()]));
                        }
                    }
                });
    }


    /**
     * 申请将指定包设置为默认短信应用（无Dialog提示）
     */
    public static void resetDefaultSms(Context context) {
        try {
            String defaultPkg = PreferencesManager.get().getDefaultSmsPackage();
            if (!TextUtils.isEmpty(defaultPkg)) {
                Class<?> smsClass = Class.forName("com.android.internal.telephony.SmsApplication");
                Method method = smsClass.getMethod("setDefaultApplication", String.class, Context.class);
                method.invoke(null, defaultPkg, context);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 申请将指定包设置为默认短信应用
     */
    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    public static void setDefaultSmsApp(FragmentActivity activity, EasyActivityResult.OnResultListener listener) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            String defaultPkg = Telephony.Sms.getDefaultSmsPackage(activity);
            if (!defaultPkg.equals(activity.getPackageName())) {
                PreferencesManager.get().saveDefaultSmsPackage(defaultPkg);
                Intent intent = new Intent(Telephony.Sms.Intents.ACTION_CHANGE_DEFAULT);
                intent.putExtra(Telephony.Sms.Intents.EXTRA_PACKAGE_NAME, activity.getPackageName());
                new EasyActivityResult(activity).startForResult(intent, 0, listener);
            } else {
                listener.onActivityResult(0, Activity.RESULT_OK, null);
            }
        }
    }

    /**
     * 申请将指定包设置为默认电话应用
     */
    @RequiresApi(api = Build.VERSION_CODES.M)
    public static void setDefaultPhoneCallApp(FragmentActivity activity, EasyActivityResult.OnResultListener listener) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            TelecomManager tm = (TelecomManager) activity.getSystemService(Activity.TELECOM_SERVICE);
            if (!tm.getDefaultDialerPackage().equals(activity.getPackageName())) {
                Intent intent = new Intent(TelecomManager.ACTION_CHANGE_DEFAULT_DIALER);
                intent.putExtra(TelecomManager.EXTRA_CHANGE_DEFAULT_DIALER_PACKAGE_NAME, activity.getPackageName());
                new EasyActivityResult(activity).startForResult(intent, 0, listener);
            } else {
                listener.onActivityResult(0, Activity.RESULT_OK, null);
            }
        }
    }


//    /**
//     * 去系统设置中设置权限
//     */
//    public static void toSystemSetting(Context context) {
//        Intent localIntent = new Intent();
//        localIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//        if (Build.VERSION.SDK_INT >= 9) {
//            localIntent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
//            localIntent.setData(Uri.fromParts("package", context.getPackageName(), null));
//        } else if (Build.VERSION.SDK_INT <= 8) {
//            localIntent.setAction(Intent.ACTION_VIEW);
//
//            localIntent.setClassName("com.android.settings",
//                    "com.android.settings.InstalledAppDetails");
//
//            localIntent.putExtra("com.android.settings.ApplicationPkgName",
//                    context.getPackageName());
//        }
//        context.startActivity(localIntent);
//    }

    /**
     * 是否开启了通知权限
     */
    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    public static boolean isNotificationEnabled(Context context) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
            return false;
        }
        AppOpsManager mAppOps =
                (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);

        ApplicationInfo appInfo = context.getApplicationInfo();
        String pkg = context.getApplicationContext().getPackageName();
        int uid = appInfo.uid;
        Class appOpsClass = null;

        try {
            appOpsClass = Class.forName(AppOpsManager.class.getName());

            Method checkOpNoThrowMethod =
                    appOpsClass.getMethod("checkOpNoThrow",
                            Integer.TYPE, Integer.TYPE, String.class);

            Field opPostNotificationValue = appOpsClass.getDeclaredField("OP_POST_NOTIFICATION");
            int value = (Integer) opPostNotificationValue.get(Integer.class);

            return ((Integer) checkOpNoThrowMethod.invoke(mAppOps, value, uid, pkg) ==
                    AppOpsManager.MODE_ALLOWED);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    public static String[] getPermissionStr(Permission... permissions) {
        String[] permissionStr = new String[permissions.length];
        for (int i = 0; i < permissions.length; i++) {
            permissionStr[i] = permissions[i].name;
        }
        return permissionStr;
    }


    public static void gotoPermissionSetting(Context context) {
        try {
            Intent intent = null;
            switch (Build.MANUFACTURER.toUpperCase()) {
                case "HUAWEI":
                    intent = new Intent();
                    intent.setComponent(new ComponentName("com.huawei.systemmanager", "com.huawei.permissionmanager.ui.MainActivity"));
                    break;
                case "XIAOMI":
                    intent = new Intent("miui.intent.action.APP_PERM_EDITOR");
                    intent.setComponent(new ComponentName("com.miui.securitycenter", "com.miui.permcenter.permissions.AppPermissionsEditorActivity"));
                    break;
                case "SONY":
                    intent = new Intent();
                    intent.setComponent(new ComponentName("com.sonymobile.cta", "com.sonymobile.cta.SomcCTAMainActivity"));
                    break;
                case "OPPO":
                    intent = new Intent();
                    intent.setComponent(new ComponentName("com.color.safecenter", "com.color.safecenter.permission.PermissionManagerActivity"));
                    break;
                case "LG":
                    intent = new Intent("android.intent.action.MAIN");
                    intent.setComponent(new ComponentName("com.android.settings", "com.android.settings.Settings$AccessLockSummaryActivity"));
                    break;

                case "LETV":
                    intent = new Intent();
                    intent.setComponent(new ComponentName("com.letv.android.letvsafe", "com.letv.android.letvsafe.PermissionAndApps"));
                    break;
                case "360":
                case "QIKU":
                    intent = new Intent("android.intent.action.MAIN");
                    ComponentName comp = new ComponentName("com.qihoo360.mobilesafe", "com.qihoo360.mobilesafe.ui.index.AppEnterActivity");
                    intent.setComponent(comp);
                    break;
//                case "ZTE":
//
//                    break;
//                case "LENOVO":
//
//                    break;
//                case "VIVO":
//
//                    break;
//                case "SAMSUNG":
//
//                    break;
                case "MEIZU":
                    intent = new Intent("com.meizu.safe.security.SHOW_APPSEC");
                    intent.addCategory(Intent.CATEGORY_DEFAULT);
                    break;
                default:
                    intent = new Intent(Settings.ACTION_SETTINGS);
                    break;
            }

            intent.putExtra("packageName", BuildConfig.APPLICATION_ID);
            context.startActivity(intent);

        } catch (Exception e) {
            context.startActivity(new Intent(Settings.ACTION_SETTINGS));
        }

    }


    /**
     * 是否同意了某个权限
     */
    public static boolean isGranted(Context ctx, String permission) {
        if (permission == null) {
            return false;
        }
        return Build.VERSION.SDK_INT < 23 || PermissionChecker.checkSelfPermission(ctx, permission) == PackageManager.PERMISSION_GRANTED;
    }


    /**
     * 权限是否全部获取
     */
    public static boolean isGranted(Context ctx, String... permissions) {
        if (permissions == null || permissions.length == 0) {
            return false;
        }
        for (String permission : permissions) {
            boolean isGranted = Build.VERSION.SDK_INT < 23 || PermissionChecker.checkSelfPermission(ctx, permission) == PackageManager.PERMISSION_GRANTED;
            if (!isGranted) {
                return false;
            }
        }
        return true;
    }


//    public interface OnDefaultAppResult {
//        void onAllow();
//
//        void onRefuse();
//    }

    public interface OnPermissionListener {
        /**
         * 允许权限
         */
        void onAllow(Permission permission);

        /**
         * 拒绝权限，下次再问
         */
        void onRefuse(Permission permission);

        /**
         * 拒绝权限，且不要再问
         */
        void onRefuseAndNeverAskAgain(Permission permission);

        /**
         * 操作结束
         *
         * @param allowed  被授权的权限
         * @param refused  被拒绝的权限
         * @param neverAsk 被拒绝且选中不要再问的权限
         */
        void onFinish(Permission[] allowed, Permission[] refused, Permission[] neverAsk);
    }

    public abstract static class OnSimplePermissionListener implements OnPermissionListener {
        @Override
        public void onAllow(Permission permission) {

        }

        @Override
        public void onRefuse(Permission permission) {

        }

        @Override
        public void onRefuseAndNeverAskAgain(Permission permission) {

        }
    }
}
