package com.sobot.common.login;

import android.content.Context;
import android.text.TextUtils;

import com.sobot.network.http.SobotOkHttpUtils;
import com.sobot.network.http.builder.PostFormBuilder;
import com.sobot.network.http.builder.PostMultipartFormBuilder;
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 com.sobot.utils.SobotStringUtils;

import org.json.JSONObject;

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

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

public class SobotCommonHttpUtils {
    private static SobotCommonHttpUtils client = null;

    private String sobot_from = "2";//android

    private SobotCommonHttpUtils() {
    }

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

    private static String getTokenId(Context context) {
        String token = SobotLoginTools.getInstance().getToken();
        return token;
    }

    private static String getLanguage(Context context) {
        String languageStr = "";
        if (SobotLoginTools.getInstance().getServiceInfo() != null) {
            languageStr = SobotStringUtils.checkStringIsNull(SobotLoginTools.getInstance().getServiceInfo().getServiceWorkbenchLang());
        }
        return languageStr;
    }

    public void doPost(Object cancelTag, Context context, final String url_str, final Map<String, Object> map, String version,
                       final StringCallBack callback) {
        SobotNetLogUtils.i("请求URL: --> " + url_str);
        SobotNetLogUtils.i("请求参数: --> " + map);
        SobotNetLogUtils.i("请求token: --> " + getTokenId(context));
        SobotNetLogUtils.i("请求language: --> " + getLanguage(context));
        SobotOkHttpUtils
                .post()
                .tag(cancelTag)
                .url(url_str)
                .params(map)
                .addHeader(SobotCommonConstant.SOBOT_TOKEN, getTokenId(context))
                .addHeader(SobotCommonConstant.KEY_TEMP_ID, getTokenId(context))
                .addHeader("language", getLanguage(context))
                .addHeader("from", sobot_from)
                .addHeader("version", version)
                .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 doPostByJson(Object cancelTag, Context context, final String url_str, final Map<String, Object> map, String version,
                             final StringCallBack callback) {
        SobotNetLogUtils.i("请求URL: --> " + url_str);
        SobotNetLogUtils.i("请求参数: --> " + map);
        SobotNetLogUtils.i("请求token: --> " + getTokenId(context));
        SobotNetLogUtils.i("请求language: --> " + getLanguage(context));
        SobotOkHttpUtils
                .postString()
                .tag(cancelTag)
                .url(url_str)
                .addHeader(SobotCommonConstant.SOBOT_TOKEN, getTokenId(context))
                .addHeader(SobotCommonConstant.KEY_TEMP_ID, getTokenId(context))
                .mediaType(MediaType.get("application/json"))
                .content(map2Json(map))
                .addHeader("language", getLanguage(context))
                .addHeader("from", sobot_from)
                .addHeader("version", version)
                .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 doPostWithFile(Object cancelTag, Context context, final String url_str, final Map<String, Object> map, String path, String version,
                               final StringCallBack callback) {
        SobotNetLogUtils.i("请求URL: --> " + url_str);
        SobotNetLogUtils.i("请求参数: --> " + map);
        SobotNetLogUtils.i("请求token: --> " + getTokenId(context));
        SobotNetLogUtils.i("请求language: --> " + getLanguage(context));

        PostMultipartFormBuilder post = SobotOkHttpUtils.postMultipart();
        if (!TextUtils.isEmpty(path)) {
            File file = new File(path);
            if (file.exists() && file.isFile()) {
                post.addFile("file", file.getName(), file);
            }
        }

        post.tag(cancelTag)
                .url(url_str)
                .params(map)
                .addHeader(SobotCommonConstant.SOBOT_TOKEN, getTokenId(context))
                .addHeader("language", getLanguage(context))
                .addHeader("from", sobot_from)
                .addHeader("version", version)
                .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);
                    }

                    @Override
                    public void inProgress(float progress) {
                        super.inProgress(progress);
                        callback.inProgress((int) (progress * 100));
                    }
                });
    }

    public void doGet(Object cancelTag, Context context, final String url_str, final Map<String, Object> map, String version,
                      final StringCallBack callback) {
        SobotNetLogUtils.i("请求URL: --> " + url_str);
        SobotNetLogUtils.i("请求参数: --> " + map);
        SobotNetLogUtils.i("请求token: --> " + getTokenId(context));
        SobotNetLogUtils.i("请求language: --> " + getLanguage(context));

        SobotOkHttpUtils
                .get()
                .tag(cancelTag)
                .url(url_str)
                .params(map)
                .addHeader(SobotCommonConstant.SOBOT_TOKEN, getTokenId(context))
                .addHeader(SobotCommonConstant.KEY_TEMP_ID, getTokenId(context))
                .addHeader("language", getLanguage(context))
                .addHeader("from", sobot_from)
                .addHeader("version", version)
                .build()
                .readTimeOut(20 * 1000)
                .writeTimeOut(20 * 1000)
                .connTimeOut(20 * 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 doGetWithNoHeader(Object cancelTag, final String url_str, final Map<String, Object> map, String version,
                                  final StringCallBack callback) {
        SobotNetLogUtils.i("请求URL: --> " + url_str);
        SobotNetLogUtils.i("请求参数: --> " + map);
        SobotOkHttpUtils
                .get()
                .tag(cancelTag)
                .url(url_str)
                .params(map)
                .addHeader("from", sobot_from)
                .addHeader("version", version)
                .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);
                    }
                });
    }

    private void printLog(String url_str, Map<String, String> map) {
        try {
            StringBuilder sb = new StringBuilder();
            sb.append("sobot---请求参数： url = " + url_str + "  ");
            for (String key : map.keySet()) {
                sb.append(key + "=" + map.get(key) + ", ");
            }
            SobotNetLogUtils.i(sb.toString().substring(0, sb.toString().length() - 2));
        } catch (Exception e) {
            //ignor
        }
    }

    public void download(String url_str, File file, Map<String, String> map, String version,
                         final FileCallBack callback) {
        SobotNetLogUtils.i("下载地址：" + url_str);
        SobotOkHttpUtils
                .get()
                .url(url_str)
                .addHeader("from", sobot_from)
                .addHeader("version", version)
                .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));
                    }
                });

    }

    public void uploadFile(Object cancelTag, Context context, String url_str, Map<String, Object> map, String version,
                           String path, final StringCallBack callback) {
        SobotNetLogUtils.i("请求URL: --> " + url_str);
        SobotNetLogUtils.i("请求参数: --> " + map);
        PostFormBuilder post = SobotOkHttpUtils.post();
        if (!TextUtils.isEmpty(path)) {
            File file = new File(path);
            if (file.exists() && file.isFile()) {
                post.addFile("file", file.getName(), file);
            }
            file = null;
        }
        post.url(url_str)//
                .params(map)
                .tag(cancelTag)
                .addHeader(SobotCommonConstant.SOBOT_TOKEN, getTokenId(context))
                .addHeader(SobotCommonConstant.KEY_TEMP_ID, getTokenId(context))
                .addHeader("language", getLanguage(context))
                .addHeader("from", sobot_from)
                .addHeader("version", version)
                .build()
                .connTimeOut(1000 * 30)
                .readTimeOut(1000 * 30)
                .writeTimeOut(1000 * 30)
                .execute(new StringCallback() {

                    @Override
                    public void onResponse(String 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));
                    }
                });
    }

    /**
     * 添加上传文件任务
     *
     * @param msgTag    上传文件的识别码 这里相当于msgId
     * @param url_str   上传文件的地址
     * @param map       参数
     * @param path      文件本地地址
     * @param imageFile 视频文件的快照本地地址
     * @return
     */
    public SobotUploadTask addUploadFileTask(String msgTag, String url_str, Map<String, Object> map, String version,
                                             String path, String imageFile) {
        SobotNetLogUtils.i("上传文件 请求URL: --> " + url_str);
        SobotNetLogUtils.i("上传文件 请求参数: --> " + map);
        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);
        }

        RequestCall requestCall = post.url(url_str)//
                .params(map)
                .addHeader("from", sobot_from)
                .addHeader("version", version)
                .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 map     参数
     * @return
     */
    public SobotDownloadTask addDownloadFileTask(String msgTag, String url_str, String fileName, Map<String, Object> map, String version) {

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

    public RequestCall obtainGetRequest(String url_str, Map<String, Object> map, String version) {
        return SobotOkHttpUtils.get().url(url_str)
                .params(map)
                .addHeader("from", sobot_from)
                .addHeader("version", version)
                .build()
                .connTimeOut(1000 * 30)
                .readTimeOut(1000 * 30)
                .writeTimeOut(1000 * 30);
    }

    //同步
    public Response doPostSync(Object cancelTag, String url_str, Map<String, Object> map, String version) throws IOException {
        return SobotOkHttpUtils
                .post()
                .tag(cancelTag)
                .url(url_str)
                .params(map)
                .addHeader("from", sobot_from)
                .addHeader("version", version)
                .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 "";
    }
}
