package ran.quzitech.rnutils.manager;

import android.content.Context;
import android.util.Log;

import com.alibaba.fastjson.JSON;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.ReadableNativeMap;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeSet;

import ran.quzitech.rnutils.MsgCode;
import ran.quzitech.rnutils.http.IHandler;
import ran.quzitech.rnutils.http.Request;
import ran.quzitech.rnutils.http.ResponseMessage;
import ran.quzitech.rnutils.utils.NetworkUtils;
import ran.quzitech.rnutils.utils.SpUtils;


/**
 * Created by Administrator on 2016/12/2 0002.
 */
public class NetworkManager extends ReactContextBaseJavaModule {

    private Context context;
    private ReactContext reactContext;
    private final String userPrefix = "user_";
    private final String requestPrefix = "request_";
    private final String request_id = "request_id";

    @Override
    public String getName() {
        return "NetworkManager";
    }

    public NetworkManager(ReactApplicationContext reactContext) {
        super(reactContext);
        context = reactContext;
        this.reactContext = reactContext;


    }

    @ReactMethod
    public void get(String url, final Callback callback) {
        if (NetworkUtils.isNetworkAvailable(context)) {
            Request.getInstance(context).get(url, new IHandler<Boolean>() {
                @Override
                public void getResponse(boolean notTimeOut, Boolean aBoolean, ResponseMessage message, String content) {
                    if (notTimeOut) {
                        if (aBoolean) {
                            //成功
                            Log.d("reactnative ANDROID GET", "SUCCESS");
                            callback.invoke(null, content);
                        } else {
                            //失败code！=0
                            Log.d("reactnative ANDROID GET", "FAILURE");
                            callback.invoke(content);
                        }
                    } else {
                        //超时
                        Log.d("reactnative ANDROID GET", "TIMEOUT");
                    }
                }
            });

        } else {
            //没网络

        }
    }

    @ReactMethod
    public void patch(String url, ReadableMap map, final Callback callback) {
        if (NetworkUtils.isNetworkAvailable(context)) {
            Request.getInstance(context).patch(url, JSON.toJSONString(((ReadableNativeMap) map).toHashMap()), new IHandler<Boolean>() {
                @Override
                public void getResponse(boolean notTimeOut, Boolean aBoolean, ResponseMessage message, String content) {
                    if (notTimeOut) {
                        if (aBoolean) {
                            //成功
                            callback.invoke(null, content);
                        } else {
                            //失败code！=0
                            callback.invoke(content);
                        }
                    } else {
                        //超时
                    }
                }
            });

        } else {
            //没网络

        }
    }

    @ReactMethod
    public void post(String url, ReadableMap map, final Callback callback) {
        if (NetworkUtils.isNetworkAvailable(context)) {
            Request.getInstance(context).post(url, JSON.toJSONString(((ReadableNativeMap) map).toHashMap()), new IHandler<Boolean>() {
                @Override
                public void getResponse(boolean notTimeOut, Boolean aBoolean, ResponseMessage message, String content) {
                    if (notTimeOut) {
                        if (aBoolean) {
                            //成功
                            callback.invoke(null, content);
                        } else {
                            //失败code！=0
                            callback.invoke(content);
                        }
                    } else {
                        //超时
                    }
                }
            });

        } else {
            //没网络

        }
    }

    /**
     * upload data of race
     *
     * @param url      to url to upload
     * @param map      data of race
     * @param method   post
     * @param callback
     */
    @ReactMethod
    public void requestWith(final String url, final ReadableMap map, final String method, final Callback callback) {
        if (method.toLowerCase().trim().equals("post")) {
            if (NetworkUtils.isNetworkAvailable(context)) {
                Request.getInstance(context).requestWith(url, JSON.toJSONString(((ReadableNativeMap) map).toHashMap()), new IHandler<Boolean>() {
                    @Override
                    public void getResponse(boolean notTimeOut, Boolean aBoolean, ResponseMessage message, String content) {
                        if (notTimeOut) {
                            if (aBoolean) {
                                //成功
                                if (callback != null) {
                                    callback.invoke(null, content);
                                }
                            } else {
                                //失败code！=0
                                if (callback != null) {
                                    callback.invoke(content);
                                }
                            }
                        } else {
                            //超时
                            saveSyncData(url, JSON.toJSONString(((ReadableNativeMap) map).toHashMap()), method);
                        }
                    }
                });

            } else {
                //没网络
                saveSyncData(url, JSON.toJSONString(((ReadableNativeMap) map).toHashMap()), method);
            }
        } else {
            callback.invoke(MsgCode.getErrorMap(MsgCode.Unsupport_Request_method).toString());
        }

    }

    /**
     * init networkmanager to upload saved race data
     *
     * @param callback
     */
    @ReactMethod
    public void initWithCallback(Callback callback) {
        List<Integer> requestIds = getRequestIdList();
        for (int i = 0; i < requestIds.size(); i++) {
            String mapStr = (String) SpUtils.get(context, requestPrefix + requestIds.get(i), "");
            Map requestMap = (Map) JSON.parseObject(mapStr);
            subDataInSp((String) requestMap.get("url"), (String) requestMap.get("params"), (String) requestMap.get("method"), requestIds.get(i));
        }
        callback.invoke();
    }

    private void subDataInSp(final String url, final String params, final String method, final int requestId) {
        if (NetworkUtils.isNetworkAvailable(context)) {
            Request.getInstance(context).requestWith(url, params, new IHandler<Boolean>() {
                @Override
                public void getResponse(boolean notTimeOut, Boolean aBoolean, ResponseMessage message, String content) {
                    if (notTimeOut) {
                        if (aBoolean) {
                            //成功
                            removeSyncData(requestId);
                        }
                    }
                }

            });
        }
    }


    private void saveSyncData(String url, String paramsMap, String method) {
        Map map = new HashMap();
        map.put("url", url);
        map.put("params", paramsMap);
        map.put("method", method);
        //保存新的数据
        SpUtils.put(context, requestPrefix + getRequestId(), JSON.toJSONString(map));
        //保存新的数据的对应id
        // SpUtils.put(context, request_id, (strSet2intSet((Set<String>) SpUtils.get(context, request_id, new HashSet()))).add(getRequestId()));
        saveRequestId();

    }


    private void removeSyncData(int removedId) {
        //删除保存的id
        //      SpUtils.put(context, request_id, (strSet2intSet((Set<String>) SpUtils.get(context, request_id, new HashSet()))).remove(removedId));
        removeRequestId(removedId);
        //删除保存的对应id的数据
        SpUtils.remove(context, requestPrefix + removedId);
    }

    private void removeRequestId(Object removeId) {

        List<Integer> strlist = getRequestIdList();
        boolean removeflag = strlist.remove((Integer) removeId);
        boolean ifnull = (strlist == null);
        int size = strlist.size();
        boolean isempty = (strlist.isEmpty());

        if (strlist.size() == 0) {
            SpUtils.put(context, request_id, "");
        } else if (strlist.size() == 1) {
            SpUtils.put(context, request_id, strlist.get(0) + "");
        } else {
            StringBuilder sb = new StringBuilder();
            for (int j = 0; j < strlist.size(); j++) {
                if (j == 0) {
                    sb.append(strlist.get(0) + "");
                } else {
                    sb.append(":" + strlist.get(j) + "");
                }
            }
            SpUtils.put(context, request_id, sb.toString());
        }
    }

    private synchronized void saveRequestId() {

        List<Integer> strlist = getRequestIdList();
        if (strlist == null || strlist.size() == 0) {
            SpUtils.put(context, request_id, "1");
        } else {
            SpUtils.put(context, request_id, (String) SpUtils.get(context, request_id, "") + ":" + getRequestId());
        }
    }

    private  List<Integer> getRequestIdList() {
        List<String> strlist = Arrays.asList(((String) SpUtils.get(context, request_id, "")).split(":"));
        List<Integer> intList = new ArrayList<Integer>();

        if (strlist != null && strlist.size() > 0) {
            for (int i = 0; i < strlist.size(); i++) {
                if (!strlist.get(i).equals("")) {
                    intList.add(Integer.parseInt(strlist.get(i)));
                }

            }
        }
        return intList;
    }

    private synchronized int getRequestId() {
        TreeSet<Integer> set2 = new TreeSet<Integer>(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o1.compareTo(o2);
            }
        });
        set2.addAll(getRequestIdList());
        if (!set2.isEmpty()) {
            return set2.last() + 1;
        }
        return 1;
    }

    @ReactMethod
    public void uploadWith(String url, ReadableMap params, String filePath, final Callback callback) {
        Log.d("reactnative ANDROID", "url:" +url);
        Log.d("reactnative ANDROID", "params:" +params);
        Log.d("reactnative ANDROID", "filePath:" +filePath);
        if (NetworkUtils.isNetworkAvailable(context)) {
            Log.d("reactnative ANDROID", "NetworkUtils.isNetworkAvailable");
            Request.getInstance(context).uploadWith(url, JSON.toJSONString(((ReadableNativeMap) params).toHashMap()), filePath, new IHandler<Boolean>() {
                @Override
                public void getResponse(boolean notTimeOut, Boolean aBoolean, ResponseMessage message, String content) {
                    Log.d("reactnative ANDROID", "getResponse");

                    if (notTimeOut) {
                        if (aBoolean) {
                            //成功
                            Log.d("reactnative ANDROID", "SUCCESS");
                            callback.invoke(null, content);
                        } else {
                            //失败code！=0
                            Log.d("reactnative ANDROID", "FAIL");
                            callback.invoke(content);
                        }
                    } else {
                        //超时
                        Log.d("reactnative ANDROID", "TIMEOUT");
                    }
                }
            });
        }
    }

}
