package com.mayi.fastdevelop.okhttp;

import android.os.Handler;
import android.os.Looper;
import android.text.TextUtils;

import com.alibaba.fastjson.JSON;
import com.mayi.fastdevelop.util.LogUtils;
import com.tencent.bugly.crashreport.CrashReport;

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

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.util.concurrent.TimeUnit;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okio.Buffer;


public class NetWorkUtil {

    private static NetWorkUtil instance;
    private OkHttpClient client;
    private final MediaType FORM_CONTENT_TYPE
            = MediaType.parse("application/json;charset=utf-8");
    private Handler handler;

    private NetWorkUtil() {
        client = new OkHttpClient.Builder()
                .connectTimeout(60, TimeUnit.SECONDS)
                .readTimeout(60, TimeUnit.SECONDS).build();
        handler = new Handler(Looper.getMainLooper());
    }

    public static NetWorkUtil getInstance() {
        if (instance == null) {
            instance = new NetWorkUtil();
        }
        return instance;
    }

    /**
     * 将InputStream转换为String
     *
     * @param is
     * @return
     */
    public String convertStreamToString(InputStream is) {
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        StringBuilder sb = new StringBuilder();
        String line = null;
        try {
            while ((line = reader.readLine()) != null) {
                sb.append(line + "/n");
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        String str = sb.toString();
        str = str.substring(0, str.length() - 2);
        return str;
    }
//      上传文件
//    public String uploadFile(String url, File file) {
//        try {
//            String result = "";
//            MediaType FROM_DATA = MediaType.parse("multipart/form-data");
//            RequestBody fileBody = RequestBody.create(MediaType.parse("application/octet-stream"), file);
//            MultipartBody body = new MultipartBody.Builder().setType(FROM_DATA).addFormDataPart("file", "SoundRecording.wav", fileBody).build();
//
//            //构建请求
//            Request request = new Request.Builder()
//                    .post(body)//添加请求体
//                    .url(url)
//                    .build();
//            Response response = client.newCall(request).execute();
//            if (response.isSuccessful()) {
//                result = convertStreamToString(response.body().byteStream());
//            }
//            Logger.i("url=" + url);
//            Logger.i("result=" + result);
//            return result;
//        } catch (IOException e) {
//            e.printStackTrace();
//            Logger.i("url=" + url);
//            if (TextUtils.isEmpty(e.getMessage())) {
//                Logger.i("Exception Message is null");
//            } else {
//                Logger.i("Exception=" + e.getMessage());
//            }
//            return "";
//        }
//    }

    //发起get请求
    public void performSynGetHttpRequest(String url, ResultCallback callback) {
        Request request = new Request.Builder().get()
                .url(url)
                .addHeader("content-type", "application/json")
                .addHeader("__REQUEST_TYPE", "HTTP_CLIENT")
                .addHeader("AUTH_TYPE", "1")
                .addHeader("AUTH_TOKEN", "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ7XCJ1c2VyQ29kZVwiOlwiOTA0NjM5NlwifSIsImlhdCI6MTU2MTQ1MTQwOX0.xizAX3iHVFMXNElpdMILZIYD7K7x8gaF2dG9J1hHPhE94e5a8fbea974e10aeebbe55eee21845")
                .addHeader("x-auth-token","5fea181d-ec7f-4083-8647-3afa22268627")
                .addHeader("USER_CODE",  "9046396")
                .build();
        initiateRequest(callback, request);
    }

    private void initiateRequest(final ResultCallback callback, final Request request) {
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, final IOException e) {
                if (callback != null) {
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            if (e instanceof UnknownHostException) {
                                callback.onFail("连接网络异常");
                            } else if (e instanceof SocketTimeoutException) {
                                callback.onFail("服务器连接超时，请稍后再试！");
                            } else {
                                callback.onFail("服务器繁忙，请稍后再试！");
                            }
                        }
                    });
                }
                Throwable throwable=new Throwable("网络异常",e);
                CrashReport.postCatchedException(throwable);
                LogUtils.netWorkFail("NetWorkUtil", call.request().url().toString(), bodyToString(call.request()), e);
            }

            @Override
            public void onResponse(Call call, final Response response) throws IOException {
                //{"code":401,"msg":"UNAUTHORIZED","ok":false,"timestamp":1551166509635,"obj":"网络成功返回数据"}
                final String json = convertStreamToString(response.body().byteStream());
                if (response.networkResponse().code() == 200) {
                    response.networkResponse().code();
                    if (callback != null) {
                        try {
                            final JSONObject jsonObject = new JSONObject(json);
                            boolean ok = jsonObject.optBoolean("ok");
                            if (ok) {
                                handler.post(new Runnable() {
                                    @Override
                                    public void run() {
                                        callback.onSuccess(JSON.parseObject(jsonObject.optString("data")
                                                , callback.getGenericType(0)));
                                    }
                                });
                            } else {
                                handler.post(new Runnable() {
                                    @Override
                                    public void run() {
                                        callback.onFail(jsonObject.optString("msg", "服务器繁忙，请稍后再试！"));
                                    }
                                });
                            }
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    }
                } else {
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            callback.onFail("服务器繁忙，请稍后再试！");
                        }
                    });
                }
                LogUtils.netWorkSuccess("NetWorkUtil", call.request().url().toString(), bodyToString(call.request()), json);
            }
        });
    }

    //发起post请求
    public void performSynPostHttpRequest(String url, String json, ResultCallback callback) {
        if (TextUtils.isEmpty(json)) {
            json = "";
        }
        RequestBody body = RequestBody.create(FORM_CONTENT_TYPE, json);
        Request request = new Request.Builder()
                .url(url)
                .post(body)
                .build();
        initiateRequest(callback, request);
    }

    private boolean isText(MediaType mediaType) {
        if (mediaType.type() != null && mediaType.type().equals("text")) {
            return true;
        }
        if (mediaType.subtype() != null) {
            if (mediaType.subtype().equals("json") ||
                    mediaType.subtype().equals("xml") ||
                    mediaType.subtype().equals("html") ||
                    mediaType.subtype().equals("webviewhtml")
                    )
                return true;
        }
        return false;
    }

    private String bodyToString(Request request) {
        RequestBody requestBody = request.body();
        if (requestBody != null) {
            MediaType mediaType = requestBody.contentType();
            if (mediaType != null) {
                if (isText(mediaType)) {
                    try {
                        Request copy = request.newBuilder().build();
                        Buffer buffer = new Buffer();
                        copy.body().writeTo(buffer);
                        return buffer.readUtf8();
                    } catch (final IOException e) {
                        return "something error when show requestBody.";
                    }
                } else {
                    return "requestBody's content :  maybe [file part] , too large too print , ignored!";
                }
            }
        }
        return "";
    }

}
