package com.yidian.common.utils;

import android.Manifest;
import android.app.NotificationManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.Paint;
import android.location.LocationManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.Settings;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.WindowManager;

import com.hjq.permissions.XXPermissions;
import com.yidian.common.AppConfig;
import com.yidian.common.YacBaseApplication;
import com.yidian.utils.DensityUtil;
import com.yidian.yac.ftdevicefinger.core.FtDeviceFinger;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.NetworkInterface;
import java.util.Enumeration;
import java.util.List;
import java.util.Locale;
import java.util.UUID;

public class SystemUtil {
    final static String TAG = "SystemManagers";

    static TelephonyManager telephony;
    WifiManager wifi;
    ConnectivityManager connectivity;
    LocationManager locationManager;
    private boolean mExternalStorageAvailable = false;
    private boolean mExternalStorageWriteable = false;
    DisplayMetrics displayMetrics;
    String appId;
    private static int ftdevicefingerStatus = 0;//0: 未初始化, -1: 初始化失败 1:初始化成功


    public NotificationManager getNotificationManager(Context context) {
        return (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
    }

    public DisplayMetrics getDisplayMetrics() {
        return displayMetrics;
    }

    private void checkExternalStorage() {
        String state = Environment.getExternalStorageState();
        if (Environment.MEDIA_MOUNTED.equals(state)) {
            //read and write
            this.mExternalStorageAvailable = this.mExternalStorageWriteable = true;
        } else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
            //only read
            this.mExternalStorageAvailable = true;
            this.mExternalStorageWriteable = false;
        } else {
            this.mExternalStorageAvailable = this.mExternalStorageWriteable = false;
        }
    }

//    public File getNotifyCacheFile() {
//
//        File dir = null;
//        if (mExternalStorageAvailable && mExternalStorageWriteable) {
//            dir = Environment.getExternalStoragePublicDirectory("cutt");
//        } else {
//            dir = context.getCacheDir();
//        }
//        File zhiyueNotifyFile = new File(dir, ".zhiyue-json");
//        if (!zhiyueNotifyFile.exists())
//            try {
//                zhiyueNotifyFile.createNewFile();
//            } catch (IOException e) {
//                e.printStackTrace();
//                ZhiyueEventTrace.foundWriteProviderIOException("notify");
//            }
//        return zhiyueNotifyFile;
//    }

    public static String getMacAddress() {
        try {
            Log.i(TAG, "getMacAddress");
            String mac = getMac(YacBaseApplication.context);
            Log.i(TAG, "getMacAddress mac : "+mac);
            if (TextUtils.isEmpty(mac)) {
                return "";
            }
            return MD5String.getMD5(mac);
        }catch (Throwable e){
            Log.e(TAG,"getMacAddress error ",e);
        }
        return "";
    }

    public boolean isWifiConnected(Context context) {
        NetworkInfo.State state = getConnectivityManager(context).getNetworkInfo(ConnectivityManager.TYPE_WIFI).getState();
        return state.equals(NetworkInfo.State.CONNECTED);
    }

    public LocationManager getLocationManager(Context context) {
        if (locationManager == null)locationManager = (LocationManager) getManager(Context.LOCATION_SERVICE,context);
        return locationManager;
    }

    public boolean netWorkable(Context context) {
        NetworkInfo info = getConnectivityManager(context).getActiveNetworkInfo();
        return info != null && info.isAvailable() && info.isConnected();
    }

    public static TelephonyManager getTelephonyManager(Context context) {
        if (telephony == null){
            telephony = (TelephonyManager) getManager(Context.TELEPHONY_SERVICE,context);
        }
        return telephony;
    }

    public WifiManager getWifiManager(Context context) {
        if (wifi == null)wifi = (WifiManager) getManager(Context.WIFI_SERVICE,context);
        return wifi;
    }

    public ConnectivityManager getConnectivityManager(Context context) {
        if (connectivity == null)connectivity = (ConnectivityManager) getManager(Context.CONNECTIVITY_SERVICE,context);
        return connectivity;
    }

    public static String getVerName(Context context) {
        try {
            String packageName = context.getPackageName();
            if (StringUtils.isNotBlank(packageName)) {
                PackageInfo packageInfo = context.getPackageManager().getPackageInfo(packageName, PackageManager.GET_CONFIGURATIONS);
                return packageInfo.versionName;
            }
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }


    public static int getVerCode(Context context) {
        int code = -1;
        try {
            String packageName = context.getPackageName();
            if (StringUtils.isNotBlank(packageName)) {
                code = context.getPackageManager().getPackageInfo(packageName, 0).versionCode;
            }
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        return code;
    }

//    public boolean isMobileConnected() {
//        NetworkInfo activeNetworkInfo = connectivity.getActiveNetworkInfo();
//        return activeNetworkInfo != null && activeNetworkInfo.isAvailable() && activeNetworkInfo.getType() == ConnectivityManager.TYPE_MOBILE && activeNetworkInfo.isConnected();
//    }

    public boolean is3GConnected(Context context) {
        NetworkInfo activeNetworkInfo = getConnectivityManager(context).getActiveNetworkInfo();
        if (activeNetworkInfo != null && activeNetworkInfo.isAvailable() && activeNetworkInfo.getType() == ConnectivityManager.TYPE_MOBILE && activeNetworkInfo.isConnected()) {
            int subtype = activeNetworkInfo.getSubtype();
            return subtype == TelephonyManager.NETWORK_TYPE_EVDO_0
                    || subtype == TelephonyManager.NETWORK_TYPE_EVDO_A
                    || subtype == TelephonyManager.NETWORK_TYPE_HSDPA
                    || subtype == TelephonyManager.NETWORK_TYPE_UMTS;

        }
        return false;
    }

    public static Object getManager(String name,Context context) {
        return context != null ? context.getSystemService(name) : null;
    }

    //小视频缓存路径 videocache StorageUtils保持一致
    public synchronized File getCacheDirectory(Context context, boolean preferExternal) {
//        File appCacheDir = null;
//        if(preferExternal && mExternalStorageAvailable && mExternalStorageWriteable) {
//            appCacheDir = getExternalCacheDir(context);
//        }
//
//        if(appCacheDir == null) {
//            appCacheDir = context.getCacheDir();
//        }
//
//        if(appCacheDir == null) {
//            String cacheDirPath = "/data/data/" + context.getPackageName() + "/cache/";
//            L.w("Can\'t define system cache directory! \'%s\' will be used.", new Object[]{cacheDirPath});
//            appCacheDir = new File(cacheDirPath);
//        }
//        return appCacheDir;
        return getAppCacheDir(context);
    }
    //小视频缓存路径 videocache StorageUtils保持一致
//    private File getExternalCacheDir(Context context) {
//        File dataDir = new File(new File(Environment.getExternalStorageDirectory(), "Android"), "data");
//        File appCacheDir = new File(new File(dataDir, context.getPackageName()), "cache");
//        if(!appCacheDir.exists()) {
//            if(!appCacheDir.mkdirs()) {
//                L.w("Unable to create external cache directory", new Object[0]);
//                return null;
//            }
//
//            try {
//                (new File(appCacheDir, ".nomedia")).createNewFile();
//            } catch (IOException var4) {
//                L.i("Can\'t create \".nomedia\" file in application external cache directory", new Object[0]);
//            }
//        }
//
//        return appCacheDir;
//    }

    public synchronized File getAppCacheDir(Context context) {
        File appCacheRootDir = null;
        //use external storage first
        if (XXPermissions.isGranted(context, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE})) {
            if (mExternalStorageAvailable && mExternalStorageWriteable) {
                File cacheRootDir = Environment.getExternalStoragePublicDirectory("cutt");
                appCacheRootDir = new File(cacheRootDir, "com.cutt.zhiyue.android.app"+appId);
            } else {
                appCacheRootDir = context.getCacheDir();
            }
        }else {
            if (mExternalStorageAvailable && mExternalStorageWriteable) {
                appCacheRootDir = context.getExternalCacheDir();
            }else {
                appCacheRootDir = context.getCacheDir();
            }
        }

        if (appCacheRootDir != null) {
            if (!appCacheRootDir.exists())
                appCacheRootDir.mkdirs();
            else {
                if (!appCacheRootDir.isDirectory()) {
                    appCacheRootDir.delete();
                    appCacheRootDir.mkdirs();
                }
            }
        }
        return appCacheRootDir;
    }


//    public long getAppCacheUsageSize() {
//        return FileUtils.getLength(getAppCacheDir()) + FileUtils.getLength(getCacheDirectory(context, true));
//    }
//
//    public File getAppGalleryDir() {
//        return getDir(AppSettings.CONTRIB_GALLERY_DIR);
//    }
//
//    public File getAppVideoDir() {
//        return getDir(AppSettings.CONTRIB_VIDEO_DIR);
//    }
//
//    public File getAppImageDir() {
//        return getDir(AppSettings.CACHE_IMAGE_DIR);
//    }
//    public File getAppAudioDir() {
//        return getDir(AppSettings.CACHE_AUDIO_DIR);
//    }
//
//    public File getDownloadDir() {
//        return getDir(AppSettings.CACHE_DOWNLOAD_DIR);
//    }

    public int getStatBarHeight(Context context) {
        try {
            Class c = Class.forName("com.android.internal.R$dimen");
            Object obj = c.newInstance();
            Field field = c.getField("status_bar_height");
            int x = Integer.parseInt(field.get(obj).toString());
            return context.getResources().getDimensionPixelSize(x);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return (int) Math.ceil(25 * displayMetrics.density);
    }

    public int getUserFrameHeight(Context context) {
        return fixScreenHeightPixel(context, displayMetrics.heightPixels) - getStatBarHeight(context);
    }


    public static int getDimensionPixelSize(Context context, int dimResId) {
        return context.getResources().getDimensionPixelSize(dimResId);
    }

    public static int getTextHeight(String str, float fontSize, int textColor) {
        Paint paint = new Paint();
        paint.setTextSize(fontSize);
        paint.setColor(textColor);
        paint.measureText(str);
        Paint.FontMetricsInt fontMetrics = paint.getFontMetricsInt();

//        Log.d(TAG, "fontMetrics.top = " + fontMetrics.top);
//        Log.d(TAG, "fontMetrics.ascent = " + fontMetrics.ascent);
//        Log.d(TAG, "fontMetrics.descent = " + fontMetrics.descent);
//        Log.d(TAG, "fontMetrics.bottom = " + fontMetrics.bottom);
//        Log.d(TAG, "fontMetrics.leading = " + fontMetrics.leading);

        return fontMetrics.bottom - fontMetrics.top + fontMetrics.leading;
    }

    public static int getTextLength(String str, int fontSize, int textColor) {
        Paint paint = new Paint();
        paint.setTextSize(fontSize);
        paint.setColor(textColor);
        return (int) paint.measureText(str);
    }

    public static boolean intentCanBeHandled(Context context, Intent intent) {
        PackageManager packageManager = context.getPackageManager();
        List<ResolveInfo> resolveInfos = packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
        return resolveInfos != null && resolveInfos.size() > 0;
    }

    public static int sdkVersion() {
        final String SDK = Build.VERSION.SDK;
        int version = -1;
        try {
            version = Integer.parseInt(SDK);
        } catch (Exception e) {
        }

        return version;
    }

    /**
     * Get visible/touchable/usable screen height from display metrics.
     * For some specific model of phone.
     * <p/>
     * Meizu, Flyme 2.0 - this mod includes a fixed height smartbar on bottom of the screen.
     *
     * @param context
     * @param screenHeight
     * @return new height of screen
     */
    public static int fixScreenHeightPixel(Context context, int screenHeight) {
        int delta = 0;
        if (Build.DISPLAY.contains("Flyme")) {
            try {
                // TODO - 48dp fixed height smartbar - need to check Meizu SDK to confirm
                final int meizu_flyme2_smartbar_height_dp = 48;

                String[] temp = Build.DISPLAY.trim().split(" ");
                temp = temp[1].split("\\.");
                if (Integer.parseInt(temp[0]) >= 2) delta = DensityUtil.dp2px(meizu_flyme2_smartbar_height_dp);
            } catch (Exception e) {
            }
        }

        return screenHeight - delta;
    }

    public static String getSerialNumber() {
        String serial = null;
        try {
            Class<?> c = Class.forName("android.os.SystemProperties");
            Method get = c.getMethod("get", String.class);
            serial = (String) get.invoke(c, "ro.serialno");
        } catch (Exception ignored) {
        }
        return serial;
    }

    private final static String errorDeviceId = "errorDeviceId";
    private final static String errorDeviceId2 = "DeviceId";

    public static String calcDeviceId(Context context) {

        String deviceId = null;
        if(XXPermissions.isGranted(context, Manifest.permission.READ_PHONE_STATE)) {
            TelephonyManager telephonyManager = getTelephonyManager(context);
            if (telephonyManager != null) {
                deviceId = telephonyManager.getDeviceId();
            }
        }

        if (invalidDeviceId(deviceId)) {
            deviceId = getSerialNumber();
            if (invalidDeviceId(deviceId)) {
                deviceId = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
                if (invalidDeviceId(deviceId)) {
                    deviceId = trimMacAddress(getMacAddress());
                    if (invalidDeviceId(deviceId)) {
                        deviceId = UUID.randomUUID().toString().replace("-", "");
                    }
                }
            }
        }
        return deviceId;
    }

    public static String getPhoneIMEI(Context context) {
        try {
            if (XXPermissions.isGranted(context, Manifest.permission.READ_PHONE_STATE)) {
                TelephonyManager telephonyManager = getTelephonyManager(context);
                if (telephonyManager != null) {
                    String imei = telephonyManager.getDeviceId();
                    return imei == null ? "" : imei;
                }
            }
        } catch (Exception e) {
            Log.e(TAG,"getPhoneIMEI error ",e);
        }
        return "";
    }


    public static String getAndroidID(Context context) {
        try {
            String androidID = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
            return androidID == null ? "" : androidID;
        } catch (Exception e) {
            Log.e(TAG,"getAndroidID error ",e);
        }
        return "";
    }

    private static String trimMacAddress(String macAddress) {
        if (macAddress == null) return null;
        return macAddress.replace(":", "");
    }

    private static boolean invalidDeviceId(String deviceId) {
        if (deviceId == null || deviceId.length() < 8 || deviceId.equals(errorDeviceId) || deviceId.equals(errorDeviceId2)) {
            return true;
        }

        if(deviceId.indexOf("unknow") == 0)
            return true;

        char firstChar = deviceId.charAt(0);
        for (int i = 0; i < deviceId.length(); ++i) {
            if (deviceId.charAt(i) != '0' && deviceId.charAt(i) != firstChar) return false;
        }
        return true;
    }

    public static String getPortalDeviceId(String portalAppId, String deviceId) {
        return "P_" + portalAppId + "_" + deviceId;
    }

    // 获取ApiKey
    public static String getMetaValue(Context context, String metaKey) {
        Bundle metaData = null;
        String apiKey = null;
        if (context == null || metaKey == null) {
            return null;
        }
        try {
            ApplicationInfo ai = context.getPackageManager()
                    .getApplicationInfo(context.getPackageName(),
                            PackageManager.GET_META_DATA);
            if (null != ai) {
                metaData = ai.metaData;
            }
            if (null != metaData) {
                apiKey = metaData.getString(metaKey);
            }
        } catch (PackageManager.NameNotFoundException e) {

        }
        return apiKey;
    }

    /**********************参照umeng获取Mac方法**************************/

    public static String getMac(Context var0) {
        String var1 = "";
            if (var0 == null) {
                return var1;
            }
            if (Build.VERSION.SDK_INT < 23) {
                var1 = getMacBySystemInterface(var0);
            } else if (Build.VERSION.SDK_INT == 23) {
                var1 = getMacByJavaAPI();
                if (TextUtils.isEmpty(var1)) {
                    var1 = getMacShell();
                    if (TextUtils.isEmpty(var1)) {
                        var1 = getMacBySystemInterface(var0);
                    }
                }
            } else {
                var1 = getMacByJavaAPI();
                if (TextUtils.isEmpty(var1)) {
                    var1 = getMacBySystemInterface(var0);
                }
            }
        return var1;
    }

    private static String getMacByJavaAPI() {
        try {
            Enumeration var0 = NetworkInterface.getNetworkInterfaces();

            NetworkInterface var1;
            do {
                if (!var0.hasMoreElements()) {
                    return null;
                }

                var1 = (NetworkInterface)var0.nextElement();
            } while(!"wlan0".equals(var1.getName()) && !"eth0".equals(var1.getName()));

            byte[] var2 = var1.getHardwareAddress();
            if (var2 != null && var2.length != 0) {
                StringBuilder var3 = new StringBuilder();
                byte[] var4 = var2;
                int var5 = var2.length;

                for(int var6 = 0; var6 < var5; ++var6) {
                    byte var7 = var4[var6];
                    var3.append(String.format("%02X:", var7));
                }

                if (var3.length() > 0) {
                    var3.deleteCharAt(var3.length() - 1);
                }

                return var3.toString().toLowerCase(Locale.getDefault());
            }

            return null;
        } catch (Throwable var8) {
        }

        return null;
    }

    private static String getMacShell() {
        try {
            String[] var0 = new String[]{"/sys/class/net/wlan0/address", "/sys/class/net/eth0/address", "/sys/devices/virtual/net/wlan0/address"};

            for(int var2 = 0; var2 < var0.length; ++var2) {
                try {
                    String var1 = reaMac(var0[var2]);
                    if (var1 != null) {
                        return var1;
                    }
                } catch (Throwable var4) {
                }
            }
        } catch (Throwable var5) {
        }
        return null;
    }

    private static String reaMac(String var0) {
        String var1 = null;
        try {
            FileReader var2 = new FileReader(var0);
            BufferedReader var3 = null;
            if (var2 != null) {
                try {
                    var3 = new BufferedReader(var2, 1024);
                    var1 = var3.readLine();
                } finally {
                    if (var2 != null) {
                        try {
                            var2.close();
                        } catch (Throwable var14) {
                            ;
                        }
                    }

                    if (var3 != null) {
                        try {
                            var3.close();
                        } catch (Throwable var13) {
                            ;
                        }
                    }

                }
            }
        } catch (Throwable var16) {
        }
        return var1;
    }

    private static String getMacBySystemInterface(Context var0) {
        if (var0 == null) {
            return "";
        } else {
            try {
                WifiManager var1 = (WifiManager) var0.getSystemService("wifi");
                if (checkPermission(var0, "android.permission.ACCESS_WIFI_STATE")) {
                    if (var1 != null) {
                        WifiInfo var2 = var1.getConnectionInfo();
                        return var2.getMacAddress();
                    } else {
                        return "";
                    }
                } else {
                    return "";
                }
            } catch (Throwable var3) {
                return "";
            }
        }
    }

    public static boolean checkPermission(Context var0, String var1) {
        boolean var2 = false;
        if (var0 == null) {
            return var2;
        } else {
            if (Build.VERSION.SDK_INT >= 23) {
                try {
                    Class var3 = Class.forName("android.content.Context");
                    Method var4 = var3.getMethod("checkSelfPermission", String.class);
                    int var5 = (Integer)var4.invoke(var0, var1);
                    if (var5 == 0) {
                        var2 = true;
                    } else {
                        var2 = false;
                    }
                } catch (Throwable var6) {
                    var2 = false;
                }
            } else {
                PackageManager var7 = var0.getPackageManager();
                if (var7.checkPermission(var1, var0.getPackageName()) == 0) {
                    var2 = true;
                }
            }

            return var2;
        }
    }






    public static String calFtDeviceFinger(Context context) {
        if (ftdevicefingerStatus == 0) {
            try {
                FtDeviceFinger.getINSTANCE().init(YacBaseApplication.context);
                ftdevicefingerStatus = 1;
            }/* catch(java.lang.UnsatisfiedLinkError e) {
            }*/ catch (Throwable e) {
                ftdevicefingerStatus = -1;
                Log.e(TAG, "calFtDeviceFinger: init failed", e);
            }
        }
        if (ftdevicefingerStatus == 1) {
            try {
                String ftDeviceFinger = FtDeviceFinger.getINSTANCE().getDeviceFinger();
                Log.d(TAG, "ftdf: " + ftDeviceFinger);
                return ftDeviceFinger;
            } catch (Throwable e) {
                Log.e(TAG, "calFtDeviceFinger: getDeviceFinger failed", e);
            }
        } else {
            Log.d(TAG, "calFtDeviceFinger: ftDeviceFinger init failed");
        }
        return null;
    }
}