package com.xunao.effectdemo.net;

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

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.xunao.effectdemo.App;
import com.xunao.effectdemo.utils.EncryptUtil;
import com.zhy.http.okhttp.OkHttpUtils;
import com.zhy.http.okhttp.builder.PostStringBuilder;
import com.zhy.http.okhttp.callback.BitmapCallback;
import com.zhy.http.okhttp.callback.StringCallback;
import com.zhy.http.okhttp.cookie.CookieJarImpl;
import com.zhy.http.okhttp.cookie.store.PersistentCookieStore;

import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.TimeUnit;

import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;


public class ApiHttpClient {
    private static String API_URL = "";

    public static OkHttpClient client;
    public static HashMap<String, String> headers = new HashMap<>();
    public static HashMap<String, String> bodys = new HashMap<>();

    public static final String MEDIA_TYPE_JSON = "application/json; charset=utf-8";

    public static Context mContext;

    public ApiHttpClient() {

    }

    public static OkHttpClient getHttpClient() {
        return client;
    }

    public static void init() {
        mContext = App.getInstance();

        CookieJarImpl cookieJar = new CookieJarImpl(new PersistentCookieStore(mContext));
        OkHttpClient client = new OkHttpClient.Builder()
                .connectTimeout(30, TimeUnit.SECONDS)
                .writeTimeout(30, TimeUnit.SECONDS)
                .readTimeout(30, TimeUnit.SECONDS)
                .followRedirects(true)
                .cookieJar(cookieJar)
                .retryOnConnectionFailure(true)
                .build();
        OkHttpUtils.initClient(client);

        addHeader("Accept-Language", Locale.getDefault().toString());
        addHeader("Accept", MEDIA_TYPE_JSON);
    }

    public static String getAbsoluteApiUrl(String partUrl) {
//        String url = String.format(API_URL, partUrl);
        return partUrl;
    }

    public static String getAbsoluteApiUrl(String partUrl,Map<String, String> params) {
        String url = null;
        for (String key:params.keySet()){
            url = (url==null?"":(url+"&"))+key+"="+params.get(key);
        }
        Log.e("MyTag","路径:"+url);
        return partUrl+"?"+url;
    }

    public static void get(String partUrl, CSMHttpCallback callback) {
        OkHttpUtils
                .get()
                .url(getAbsoluteApiUrl(partUrl))
                .headers(headers)
                .build()
                .execute(callback);
    }

    public static void get(String partUrl, Map<String, String> params,CSMHttpCallback callback) {
        OkHttpUtils
                .get()
                .url(getAbsoluteApiUrl(partUrl,params))
                .headers(headers)
                .build()
                .execute(callback);
    }

    public static void post(String partUrl, CSMHttpCallback callback) {
        OkHttpUtils
                .post()
                .url(getAbsoluteApiUrl(partUrl))
                .headers(headers)
                .build()
                .execute(callback);
    }

    public static void post(String partUrl, Map<String, String> params, CSMHttpCallback callback) {
        try {
//            params.put("app_type","android");
//            params.put("app_version",BmonsterApplication.version);
            addHeader("param", generateSignStr(params));//
            String jsonParam = new Gson().toJson(params);
            params = new Gson().fromJson(jsonParam, new TypeToken<HashMap<String, String>>(){}.getType());
            OkHttpUtils
                    .post()
                    .url(getAbsoluteApiUrl(partUrl))
                    .headers(headers)
                    .params(params)
                    .build()
                    .execute(callback);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void post2(String partUrl, Map<String, String> params,Map<String,String> map, CSMHttpCallback callback) {
        try {
//            params.put("app_type","android");
//            params.put("app_version",BmonsterApplication.version);
//            addHeader("post", generateSignStr(params));//
            String jsonParam = new Gson().toJson(params);
            params = new Gson().fromJson(jsonParam, new TypeToken<HashMap<String, String>>(){}.getType());
            FormBody.Builder formBody = new FormBody.Builder();//创建表单请求体
//            formBody.add("username","zhangsan");//传递键值对参数
            OkHttpUtils
                    .post()
                    .url(getAbsoluteApiUrl(partUrl))
                    .headers(headers)
                    .params(params)
                    .build()
                    .execute(callback);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void postBody(String partUrl, Map<String, String> params, MapBodyBean bean, Callback callback){

        try {

            Gson gson = new Gson();
            //  转换层json字符串
            final String s = gson.toJson(bean);
            //  创建  RequestBody
            String msg = generateSignStr(params);

//            RequestBody requestBody = RequestBody.create(MediaType.parse("application/json"), s);
//            Request request = new Request.Builder().url(partUrl).header("param", msg)
//                    .post(requestBody).build();

            FormBody.Builder formBody = new FormBody.Builder();//创建表单请求体
            formBody.add("speed_list",bean.getSpeed_list());//传递键值对参数
            formBody.add("height_list",bean.getHeight_list());//传递键值对参数
            formBody.add("location_list",bean.getLocation_list());//传递键值对参数
            Request request = new Request.Builder()//创建Request 对象。
                    .url(partUrl)
                    .header("param", msg)
                    .post(formBody.build())//传递请求体
                    .build();

            OkHttpClient okHttpClient1 = OkHttpUtils.getInstance().getOkHttpClient();
            okHttpClient1.newCall(request).enqueue(callback);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }



    public static void post(String partUrl, Map<String, String> params, String fileParamName, File file, CSMHttpCallback callback) {
        try {
            OkHttpUtils
                    .post()
                    .url(getAbsoluteApiUrl(partUrl))
                    .headers(headers)
                    .params(params)
                    .addFile(fileParamName, file.getName(), file)
                    .build()
                    .execute(callback);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void postJson(String partUrl, String json, CSMHttpCallback callback) {

        OkHttpUtils
                .postString()
                .url(getAbsoluteApiUrl(partUrl))
                .content(json)
                .mediaType(MediaType.parse(MEDIA_TYPE_JSON))
                .headers(headers)
                .build()
                .execute(callback);
    }

    public static void postJsonAsync(String partUrl, String json, BitmapCallback callback) {
        PostStringBuilder builder = OkHttpUtils
                .postString()
                .url(partUrl)
                .mediaType(MediaType.parse(MEDIA_TYPE_JSON));
        if (json != null) {
            builder.content(json);
        }
        builder.build().execute(callback);
    }

    public static Response getFormSync(String partUrl) {
        try {
            Response response = OkHttpUtils
                    .get()
                    .url(partUrl)
                    .build()
                    .execute();
            return response;
        } catch (IOException e) {
            return null;
        }
    }

    public static void getAsync(String partUrl, StringCallback callback) {
        OkHttpUtils
                .get()
                .url(partUrl)
                .build()
                .execute(callback);
    }

    public static void addHeader(String key, String value) {
        if (headers.containsKey(key)) {
            headers.remove(key);
        }
        headers.put(key, value);
    }

    public static void addBodys(String key, String value) {
        if (bodys.containsKey(key)) {
            bodys.remove(key);
        }
        bodys.put(key, value);
    }

    private static String generateSignStr(Map<String, String> params) {
        //1、将请求数据按照key字典序排序后的数组
        Map<String, String> sortMap = new TreeMap((Comparator<String>) (s, t1) -> s.compareTo(t1));
        sortMap.putAll(params);
        //2、将所有的请求数据拼接为字符串
        StringBuilder sb = new StringBuilder();
        for (String value:sortMap.values()) {
            sb.append(value);
        }
        //3、将 $str urlencode 加密
        String encodeStr = URLEncoder.encode(sb.toString());
        //4、将上面加密的字符串转化为小写
        encodeStr = encodeStr.toLowerCase();
        //5、转化为小写之后再进行md5加密
        String md5Str = EncryptUtil.md5(encodeStr);
        //生成signStr之后的请求参数数组
        Map<String, Object> map = new HashMap();
        map.put("params", sortMap);
        map.put("signStr", md5Str);
        //6、将请求数组转化为json格式
        String json = new Gson().toJson(map);
        //将上一步生成的json数据转化为 base64 格式数据
        Log.d("json", json);
        Log.d("base64", Base64.encodeToString(json.getBytes(), Base64.NO_WRAP));
        return Base64.encodeToString(json.getBytes(), Base64.NO_WRAP);
    }
}

