package com.sobot.network.http;

import android.os.Build;
import android.text.TextUtils;

import com.sobot.network.customhttp.SobotCustomHttpUtils;
import com.sobot.network.customhttp.bean.CommCallback;
import com.sobot.network.http.builder.PostFormBuilder;
import com.sobot.network.http.callback.StringCallback;
import com.sobot.network.http.download.SobotDownload;
import com.sobot.network.http.download.SobotDownloadTask;
import com.sobot.network.http.log.SobotNetLogUtils;
import com.sobot.network.http.request.RequestCall;
import com.sobot.network.http.upload.SobotUpload;
import com.sobot.network.http.upload.SobotUploadTask;

import org.json.JSONObject;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

import okhttp3.Call;
import okhttp3.FormBody;
import okhttp3.MediaType;
import okhttp3.Response;

public class HttpBaseUtils {
    private static HttpBaseUtils client = null;

    private HttpBaseUtils() {
    }

    public static HttpBaseUtils getInstance() {
        if (client == null) {
            client = new HttpBaseUtils();
        }
        return client;
    }

    public void doPost(Object cancelTag, final String url_str, Map<String, Object> paramMap,
                       Map<String, String> headerMap,
                       final StringCallBack callback) {
        doPost(cancelTag, url_str, 8 * 1000, paramMap, headerMap, callback);
    }

    public void doPost(Object cancelTag, final String url_str, long timeOut, Map<String, Object> paramMap,
                       Map<String, String> headerMap,
                       final StringCallBack callback) {
        SobotNetLogUtils.i("请求URL: --> " + url_str);
        SobotNetLogUtils.i("请求参数: --> " + paramMap);
        SobotNetLogUtils.i("请求头参数: --> " + headerMap);
        if (headerMap == null) {
            headerMap = new HashMap<>();
        }
        if (Build.VERSION.SDK_INT >= 21) {
            SobotOkHttpUtils
                    .post()
                    .tag(cancelTag)
                    .url(url_str)
                    .headers(headerMap)
                    .params(paramMap)
                    .build()
                    .readTimeOut(timeOut)
                    .writeTimeOut(timeOut)
                    .connTimeOut(timeOut).execute(new StringCallback() {

                        @Override
                        public void onResponse(String response) {
                            SobotNetLogUtils.i(url_str + "----请求返回结果: --> " + response);
                            callback.onResponse(response);

                        }

                        @Override
                        public void onError(Call call, Exception e) {
                            SobotNetLogUtils.i(call.toString());
                            e.printStackTrace();
                            callback.onError(e, call.toString(), -1);
                        }
                    });
        } else {
            SobotCustomHttpUtils.build()
                    .url(url_str)
                    .addParams(paramMap)
                    .addHeaders(headerMap)
                    .onExecuteByPost(new com.sobot.network.customhttp.bean.StringCallBack() {
                        @Override
                        public void onSucceed(String response) {
                            SobotNetLogUtils.i(url_str + "----请求返回结果: --> " + response);
                            callback.onResponse(response);
                        }

                        @Override
                        public void onFailed(Exception e) {
                            SobotNetLogUtils.i(e.toString());
                            callback.onError(e, e.getMessage(), -1);
                        }
                    });
        }
    }


    //请求参数为json
    public void doPostByJsonString(Object cancelTag, final String
            url_str, Map<String, Object> paramMap,
                                   Map<String, String> headerMap,
                                   final StringCallBack callback) {

        SobotNetLogUtils.i("请求URL: --> " + url_str);
        SobotNetLogUtils.i("请求参数: --> " + paramMap);
        SobotNetLogUtils.i("请求头参数: --> " + headerMap);
        if (headerMap == null) {
            headerMap = new HashMap<>();
        }
        if (Build.VERSION.SDK_INT >= 21) {
            SobotOkHttpUtils
                    .postString()
                    .tag(cancelTag)
                    .url(url_str)
                    .headers(headerMap)
                    .mediaType(MediaType.get("application/json"))
                    .content(map2Json(paramMap))
                    .build()
                    .readTimeOut(8 * 1000)
                    .writeTimeOut(8 * 1000)
                    .connTimeOut(8 * 1000).execute(new StringCallback() {

                        @Override
                        public void onResponse(String response) {
                            SobotNetLogUtils.i(url_str + "----请求返回结果: --> " + response);
                            callback.onResponse(response);

                        }

                        @Override
                        public void onError(Call call, Exception e) {
                            SobotNetLogUtils.i(call.toString());
                            e.printStackTrace();
                            callback.onError(e, call.toString(), -1);
                        }
                    });
        } else {
            SobotCustomHttpUtils.build()
                    .url(url_str)
                    .setContentType("application/json")
                    .addParams(paramMap)
                    .addHeaders(headerMap)
                    .onExecuteByPost(new com.sobot.network.customhttp.bean.StringCallBack() {
                        @Override
                        public void onSucceed(String response) {
                            SobotNetLogUtils.i(url_str + "----请求返回结果: --> " + response);
                            callback.onResponse(response);
                        }

                        @Override
                        public void onFailed(Exception e) {
                            SobotNetLogUtils.i(e.toString());
                            callback.onError(e, e.getMessage(), -1);
                        }
                    });
        }
    }

    public void doGet(Object cancelTag, final String url_str,
                      final Map<String, Object> paramMap, Map<String, String> headerMap,
                      final StringCallBack callback) {
        doGet(cancelTag, url_str, 8 * 1000, paramMap, headerMap, callback);
    }

    public void doGet(Object cancelTag, final String url_str, long timeOut,
                      final Map<String, Object> paramMap, Map<String, String> headerMap,
                      final StringCallBack callback) {
        SobotNetLogUtils.i("请求URL: --> " + url_str);
        SobotNetLogUtils.i("请求参数: --> " + paramMap);
        SobotNetLogUtils.i("请求头参数: --> " + headerMap);
        if (headerMap == null) {
            headerMap = new HashMap<>();
        }
        if (Build.VERSION.SDK_INT >= 21) {
            SobotOkHttpUtils
                    .get()
                    .tag(cancelTag)
                    .url(url_str)
                    .params(paramMap)
                    .headers(headerMap)
                    .build()
                    .readTimeOut(timeOut)
                    .writeTimeOut(timeOut)
                    .connTimeOut(timeOut).execute(new StringCallback() {

                        @Override
                        public void onResponse(String response) {
                            SobotNetLogUtils.i(url_str + "----请求返回结果: --> " + response);
                            callback.onResponse(response);

                        }

                        @Override
                        public void onError(Call call, Exception e) {
                            SobotNetLogUtils.i(call.toString());
                            e.printStackTrace();
                            callback.onError(e, call.toString(), -1);
                        }
                    });
        } else {
            SobotCustomHttpUtils.build()
                    .url(url_str)
                    .addParams(paramMap)
                    .addHeaders(headerMap)
                    .onExecute(new com.sobot.network.customhttp.bean.StringCallBack() {
                        @Override
                        public void onSucceed(String response) {
                            SobotNetLogUtils.i(url_str + "----请求返回结果: --> " + response);
                            callback.onResponse(response);
                        }

                        @Override
                        public void onFailed(Exception e) {
                            SobotNetLogUtils.i(e.toString());
                            callback.onError(e, e.getMessage(), -1);
                        }
                    });
        }
    }

    private static FormBody addParamToBuilder(Map<String, String> params) {
        FormBody.Builder builder = new FormBody.Builder();
        if (params != null && params.keySet().size() > 0) {
            try {
                for (String key : params.keySet()) {
                    builder.add(key, params.get(key));
                }
            } catch (Exception e) {
            }
        }
        return builder.build();
    }

    public void doPut(Object cancelTag, final String url_str, Map<String, String> paramMap,
                      Map<String, String> headerMap,
                      final StringCallBack callback) {
        SobotNetLogUtils.i("请求URL: --> " + url_str);
        SobotNetLogUtils.i("请求参数: --> " + paramMap);
        SobotNetLogUtils.i("请求头参数: --> " + headerMap);
        if (headerMap == null) {
            headerMap = new HashMap<>();
        }
        FormBody formBody = addParamToBuilder(paramMap);
        SobotOkHttpUtils
                .put()
                .requestBody(formBody)
                .tag(cancelTag)
                .url(url_str)
                .headers(headerMap)
                .build()
                .readTimeOut(8 * 1000)
                .writeTimeOut(8 * 1000)
                .connTimeOut(8 * 1000).execute(new StringCallback() {

                    @Override
                    public void onResponse(String response) {
                        SobotNetLogUtils.i(url_str + "----请求返回结果: --> " + response);
                        callback.onResponse(response);

                    }

                    @Override
                    public void onError(Call call, Exception e) {
                        SobotNetLogUtils.i(call.toString());
                        e.printStackTrace();
                        callback.onError(e, call.toString(), -1);
                    }
                });
    }

    public void download(String url_str, final File file,
                         final FileCallBack callback) {
        SobotNetLogUtils.i("下载地址：" + url_str);
        if (Build.VERSION.SDK_INT >= 21) {
            SobotOkHttpUtils
                    .get()
                    .url(url_str)
                    .build()
                    .connTimeOut(1000 * 30)
                    .readTimeOut(1000 * 30)
                    .writeTimeOut(1000 * 30)
                    .execute(new com.sobot.network.http.callback.FileCallBack(file.getAbsolutePath()) {

                        @Override
                        public void onError(Call call, Exception e) {
                            callback.onError(e, call.toString(), -1);
                        }

                        @Override
                        public void onResponse(File file) {
                            callback.onResponse(file);
                        }

                        @Override
                        public void inProgress(float progress, long total) {
                            callback.inProgress((int) (progress * 100));
                        }
                    });
        } else {
            SobotCustomHttpUtils.build()
                    .url(url_str)
                    .setFileSaveDir(file.getAbsolutePath())
                    .setConnTimeOut(6000)//设置连接超时时间[可选，默认5s]
                    .setReadTimeOut(5 * 60 * 1000)//设置读取超时时间[可选，默认30s]
                    .onExecuteDwonload(new CommCallback() {
                        @Override
                        public void onSucceed(Object o) {
                        }

                        @Override
                        public void onFailed(Exception e) {
                            callback.onError(e, e.getMessage(), -1);
                        }

                        @Override
                        public void onDownLoadFinished() {
                            callback.onResponse(file);
                        }

                        @Override
                        public void onDownloading(long total, long current) {
                            callback.inProgress((int) (((double) current / total) * 100));
                        }
                    });
        }
    }

    public void uploadFile(Object cancelTag, String
            url_str, Map<String, Object> paramMap, Map<String, String> headerMap,
                           String path, final StringCallBack callback) {
        SobotNetLogUtils.i("请求URL: --> " + url_str);
        SobotNetLogUtils.i("请求参数: --> " + paramMap);
        SobotNetLogUtils.i("请求头参数: --> " + headerMap);
        SobotNetLogUtils.i("上传文件地址: --> " + path);
        if (headerMap == null) {
            headerMap = new HashMap<>();
        }
        if (Build.VERSION.SDK_INT >= 21) {
            PostFormBuilder post = SobotOkHttpUtils.post();
            if (!TextUtils.isEmpty(path)) {
                File file = new File(path);
                if (file.exists() && file.isFile()) {
                    post.addFile("file", file.getName(), file);
                }
            }
            post.url(url_str)//
                    .params(paramMap)
                    .headers(headerMap)
                    .tag(cancelTag)
                    .build()
                    .connTimeOut(1000 * 30)
                    .readTimeOut(1000 * 30)
                    .writeTimeOut(1000 * 30)
                    .execute(new StringCallback() {

                        @Override
                        public void onResponse(String response) {
                            SobotNetLogUtils.i("上传返回结果:" + response);
                            callback.onResponse(response);
                        }

                        @Override
                        public void onError(Call call, Exception e) {
                            callback.onError(e, call.toString(), -1);
                        }

                        @Override
                        public void inProgress(float progress) {
                            super.inProgress(progress);
                            callback.inProgress((int) (progress * 100));
                        }
                    });
        } else {
            File file = null;
            if (!TextUtils.isEmpty(path)) {
                file = new File(path);
            }
            if (file == null) {
                SobotNetLogUtils.e("上传文件 " + path + " 不存在，不执行上传请求");
            }
            SobotCustomHttpUtils.build()
                    .uploadUrl(url_str)
                    .addFile(file)
                    .addParams(paramMap)
                    .addHeaders(headerMap)
                    .setConnTimeOut(6000)//设置连接超时时间[可选，默认5s]
                    .setReadTimeOut(5 * 60 * 1000)//设置读取超时时间[可选，默认30s]
                    .onExecuteUpLoad(new CommCallback() {
                        @Override
                        public void onSucceed(Object o) {
                        }

                        @Override
                        public void onFailed(Exception e) {
                            callback.onError(e, e.getMessage(), -1);
                        }

                        @Override
                        public void onUploadFinished(String result) {
                            callback.onResponse(result);
                            SobotNetLogUtils.i("上传返回结果:" + result);
                        }

                        @Override
                        public void onDownloading(long total, long current) {
                        }
                    });
        }
    }

    /**
     * 添加上传文件任务
     *
     * @param msgTag    上传文件的识别码 这里相当于msgId
     * @param url_str   上传文件的地址
     * @param paramMap  参数
     * @param path      文件本地地址
     * @param imageFile 视频文件的快照本地地址
     * @return
     */
    public SobotUploadTask addUploadFileTask(String msgTag, String
            url_str, Map<String, Object> paramMap, Map<String, String> headerMap,
                                             String path, String imageFile) {
        SobotNetLogUtils.i("上传文件 请求URL: --> " + url_str);
        SobotNetLogUtils.i("上传文件 请求参数: --> " + paramMap);
        SobotNetLogUtils.i("请求头参数: --> " + headerMap);
        if (headerMap == null) {
            headerMap = new HashMap<>();
        }
        PostFormBuilder post = SobotOkHttpUtils.post();
        if (!TextUtils.isEmpty(path)) {
            File file = new File(path);
            post.addFile("file", file.getName(), file);
        }

        if (!TextUtils.isEmpty(imageFile)) {
            File file2 = new File(imageFile);
            post.addFile("imageFile", file2.getName(), file2);
        }

        if (headerMap == null) {
            headerMap = new HashMap<>();
        }
        RequestCall requestCall = post.url(url_str)//
                .params(paramMap)
                .headers(headerMap)
                .build()
                .connTimeOut(1000 * 30)
                .readTimeOut(1000 * 30)
                .writeTimeOut(1000 * 30);
        Random random = new Random();
        // msgid
        return SobotUpload.request(msgTag, requestCall)
                .priority(random.nextInt(100))
                .tmpTag(msgTag)
                .filePath(path).start();
    }

    /**
     * 添加下载文件任务
     *
     * @param msgTag   上传文件的识别码 这里相当于msgId
     * @param url_str  文件的下载地址
     * @param paramMap 参数
     * @return
     */
    public SobotDownloadTask addDownloadFileTask(String msgTag, String url_str, String
            fileName, Map<String, Object> paramMap, Map<String, String> headerMap) {

        if (TextUtils.isEmpty(msgTag) || TextUtils.isEmpty(url_str)) {
            return null;
        }
        Random random = new Random();
        // msgid
        return SobotDownload.request(msgTag, obtainGetRequest(url_str, paramMap, headerMap))
                .priority(random.nextInt(100))
                .fileName(fileName)
                .save();
    }

    public RequestCall obtainGetRequest(String
                                                url_str, Map<String, Object> paramMap, Map<String, String> headerMap) {
        SobotNetLogUtils.i("请求URL: --> " + url_str);
        SobotNetLogUtils.i("请求参数: --> " + paramMap);
        SobotNetLogUtils.i("请求头参数: --> " + headerMap);
        if (headerMap == null) {
            headerMap = new HashMap<>();
        }
        return SobotOkHttpUtils.get().url(url_str)
                .headers(headerMap)
                .params(paramMap)
                .build()
                .connTimeOut(1000 * 30)
                .readTimeOut(1000 * 30)
                .writeTimeOut(1000 * 30);
    }

    //同步
    public Response doPostSync(Object cancelTag, String
            url_str, Map<String, Object> paramMap, Map<String, String> headerMap) throws
            IOException {
        SobotNetLogUtils.i("请求URL: --> " + url_str);
        SobotNetLogUtils.i("请求参数: --> " + paramMap);
        SobotNetLogUtils.i("请求头参数: --> " + headerMap);
        if (headerMap == null) {
            headerMap = new HashMap<>();
        }
        return SobotOkHttpUtils
                .post()
                .tag(cancelTag)
                .url(url_str)
                .headers(headerMap)
                .params(paramMap)
                .build()
                .readTimeOut(8 * 1000)
                .writeTimeOut(8 * 1000)
                .connTimeOut(8 * 1000).execute();
    }

    public interface StringCallBack {
        void onResponse(String result);

        void onError(Exception e, String msg, int responseCode);

        void inProgress(int progress);
    }

    public interface FileCallBack {
        void onResponse(File result);

        void onError(Exception e, String msg, int responseCode);

        void inProgress(int progress);
    }


    public static String map2Json(Map<String, Object> map) {
        if (map != null && map.size() > 0) {
            JSONObject a = new JSONObject(map);
            return a.toString();
        }
        return "";
    }
}
