package com.fq.channel.sdk.base.utils;

import android.annotation.SuppressLint;
import android.app.ActivityManager;
import android.app.Application;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.support.annotation.ColorRes;
import android.support.annotation.DimenRes;
import android.support.annotation.IntegerRes;
import android.support.annotation.NonNull;
import android.support.annotation.StringRes;
import android.support.v4.content.ContextCompat;
import android.text.TextUtils;

import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Enumeration;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 获取上下文的工具类
 * Created by Ethan on 2017/6/14.
 */

public class Utils {
    @SuppressLint("StaticFieldLeak")
    private static Context sContext;

    //SDK版本号
    public static String FQSDK_VERSION = "2.0.0";

    /**
     * 初始化 Utils
     *
     * @param context 上下文
     */
    public static void init(@NonNull Context context) {
        sContext = context.getApplicationContext();
    }


    /**
     * 获取 ApplicationContext
     *
     * @return ApplicationContext
     */
    public static Context getContext() {
        if (sContext != null) return sContext;
        throw new NullPointerException("please invoke the init method first");
    }

    /**
     * 判断传入的对象是否为空
     *
     * @param reference
     * @param <T>
     * @return 返回传入的非空对象
     */
    public static <T> T checkNotNull(T reference) {
        if (reference == null) {
            throw new NullPointerException();
        } else {
            return reference;
        }
    }

    /**
     * 获取values/strings中的string值
     *
     * @param resId 资源标识符
     * @return
     */
    public static String getString(@StringRes int resId) {
        return getContext().getString(resId);
    }

    /**
     * 获取values/strings中的可格式化的string值
     *
     * @param resId
     * @param formatArgs
     * @return
     */
    public static String getString(@StringRes int resId, Object... formatArgs) {
        return getContext().getString(resId, formatArgs);
    }

    /**
     * 获取values/integers中的int值
     *
     * @param resId 资源标识符
     * @return
     */
    public static int getInt(@IntegerRes int resId) {
        return getContext().getResources().getInteger(resId);
    }

    /**
     * 获取values/dimens中的dimen值
     *
     * @param resId 资源标识符
     * @return
     */
    public static float getDimen(@DimenRes int resId) {
        return getContext().getResources().getDimension(resId);
    }

    /**
     * 获取values/colors中的color值
     *
     * @param resId 资源标识符
     * @return
     */
    public static int getColor(@ColorRes int resId) {
        return ContextCompat.getColor(getContext(), resId);
    }


    /**
     * Return a resource identifier for the given resource name
     *
     * @param name
     * @param defType
     * @return
     */
    public static int getIdentifier(String name, String defType) {
        return sContext.getResources().getIdentifier(name, defType, sContext.getPackageName());
    }

    /**
     * 判断是否是手机号码
     * <p>
     * 1开头,总共11位数字
     */
    public static boolean isMobile(@NonNull String number) {

        String num = "^(1)\\d{10}$";
        if (TextUtils.isEmpty(number)) {
            return false;
        } else {
            //matches():字符串是否在给定的正则表达式匹配
            return number.matches(num);
        }
    }

    /**
     * 调用系统的拨号界面
     *
     * @param phoneNumber 拨号界面显示的号码
     */
    public static void callPhone(String phoneNumber) {
        Intent intent = new Intent(Intent.ACTION_DIAL);
        intent.setData(Uri.parse("tel:" + phoneNumber));
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        Utils.getContext().startActivity(intent);
    }


    /**
     * 进行URLDecoder
     *
     * @param text 要Decoder的text
     * @return
     */
    public static String decodeText(String text) {

        try {
            return URLDecoder.decode(text, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return "";
    }


    /**
     * 进行URLEncoder
     *
     * @param text 要Encode的text
     * @return
     */
    private String encoderText(String text) {
        try {
            return URLEncoder.encode(text, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return "";
    }



    /**
     * 判断使用是否位于前台
     *
     * @return
     */
    public static boolean isAppForeground() {

        //获取Android设备中所有正在运行的App
        ActivityManager am = (ActivityManager) Utils.getContext()
                .getSystemService(Application.ACTIVITY_SERVICE);
        List<ActivityManager.RunningAppProcessInfo> appProcesses = am.getRunningAppProcesses();

        //应用包名
        String packgameName = Utils.getContext().getPackageName();

        if (appProcesses == null
                || appProcesses.isEmpty()) {
            return false;
        }

        for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
            if (appProcess.processName.equals(packgameName)
                    && ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND == appProcess.importance) {
                return true;
            }
        }
        return false;
    }

    /**
     * 判断是否匹配对应的正则表达式
     *
     * @return
     */
    public static boolean isMatcher(String txt) {

        //编译正则表达式
        Pattern pattern = Pattern.compile(getString(getIdentifier("regex", "string")));
        Matcher matcher = pattern.matcher(txt);
        return matcher.matches();
    }

    /**
     * 读简单的文件
     *
     * @param is
     *            文件流
     * @return 字符
     */
    public static String readSimplelyFile(InputStream is) {
        if (is == null) {
            return null;
        }
        ByteArrayOutputStream baos = null;
        try {
            baos = new ByteArrayOutputStream(4096);
            byte[] b = new byte[1024];
            int a = -1;
            while ((a = is.read(b)) != -1) {
                baos.write(b, 0, a);
            }
            return baos.toString();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (null != is) {
                try {
                    is.close();

                } catch (IOException e) {
                }
            }
            if (baos != null) {
                try {
                    baos.close();
                } catch (IOException e) {
                }
            }
        }
        return null;
    }

    /**
     * 将Object对象里面的属性和值转化成Map对象
     *
     * @param obj
     * @return
     * @throws IllegalAccessException
     */

    public static Map<String, Object> getObjectToMap(Object obj) throws IllegalAccessException {
        Map<String, Object> map = new LinkedHashMap<String, Object>();
        Class<?> clazz = obj.getClass();
        System.out.println(clazz);
        for (Field field : clazz.getDeclaredFields()) {
            field.setAccessible(true);
            String fieldName = field.getName();
            Object value = field.get(obj);
            if (value == null) {
                value = "";
            }
            map.put(fieldName, value);
        }
        return map;

    }

    /**
     * 将Map转Object对象
     *
     * @param map
     * @return obj
     * @throws IllegalAccessException
     */
    public static Object mapToObject(Map<Object, Object> map, Class<?> beanClass) throws Exception {
        if (map == null)
            return null;
        Object obj = beanClass.newInstance();
        Field[] fields = obj.getClass().getDeclaredFields();
        for (Field field : fields) {
            int mod = field.getModifiers();
            if (Modifier.isStatic(mod) || Modifier.isFinal(mod)) {
                continue;
            }
            field.setAccessible(true);
            if (map.containsKey(field.getName())) {
                field.set(obj, map.get(field.getName()));
            }
        }
        return obj;
    }

    /**
     * 获取IP地址
     * <p>需添加权限 {@code <uses-permission android:name="android.permission.INTERNET"/>}</p>
     *
     * @param useIPv4 是否用IPv4
     * @return IP地址
     */
    public static String getIPAddress(final boolean useIPv4) {
        try {
            for (Enumeration<NetworkInterface> nis = NetworkInterface.getNetworkInterfaces(); nis.hasMoreElements(); ) {
                NetworkInterface ni = nis.nextElement();
                // 防止小米手机返回10.0.2.15
                if (!ni.isUp()) continue;
                for (Enumeration<InetAddress> addresses = ni.getInetAddresses(); addresses.hasMoreElements(); ) {
                    InetAddress inetAddress = addresses.nextElement();
                    if (!inetAddress.isLoopbackAddress()) {
                        String hostAddress = inetAddress.getHostAddress();
                        boolean isIPv4 = hostAddress.indexOf(':') < 0;
                        if (useIPv4) {
                            if (isIPv4) return hostAddress;
                        } else {
                            if (!isIPv4) {
                                int index = hostAddress.indexOf('%');
                                return index < 0 ? hostAddress.toUpperCase() : hostAddress.substring(0, index).toUpperCase();
                            }
                        }
                    }
                }
            }
        } catch (SocketException e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 判断是否是WiFi链接
     * <p>需添加权限 {@code <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>}</p>
     *
     * @return
     */
    public static boolean isWifi() {

        ConnectivityManager manager = (ConnectivityManager) Utils.getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo info = manager.getActiveNetworkInfo();
        if (info != null
                && ConnectivityManager.TYPE_WIFI == info.getType()) {
            return true;
        }
        return false;
    }

}
