package com.gingersoft.gsa.cloud.base.utils.okhttpUtils;

import android.util.Log;

import com.gingersoft.gsa.cloud.base.application.GsaCloudApplication;
import com.gingersoft.gsa.cloud.constans.AppConstans;
import com.gingersoft.gsa.cloud.base.utils.encryption.Aes;
import com.jess.arms.utils.DeviceUtils;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.TimeUnit;

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Headers;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

/**
 * 作者：ELEGANT_BIN
 * 版本：1.6.0
 * 创建日期：2019/1/10
 * 修订历史：2019/1/10
 * 描述：
 */
public class OkHttp3Utils {

    private static volatile OkHttpClient mOkHttpClient;
    private static final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/png");

    public static void getOkHttpClient() {
        if (mOkHttpClient == null) {
            synchronized (OkHttp3Utils.class) {
                if (mOkHttpClient == null) {
                    mOkHttpClient = new OkHttpClient.Builder()
                            .connectTimeout(GsaCloudApplication.REQUEST_TIMEOUT, TimeUnit.SECONDS)
                            .readTimeout(GsaCloudApplication.REQUEST_TIMEOUT, TimeUnit.SECONDS)
                            .addInterceptor(new UserAgentIntercepter())
                            .build();

                }
            }
        }
    }

    public static Observable<String> get(String reqUrl) {
        getOkHttpClient();
        return Observable.create(new ObservableOnSubscribe<String>() {

            @Override
            public void subscribe(ObservableEmitter<String> emitter) throws Exception {
                //构建请求体
                Request.Builder RequestBuilder = new Request.Builder();
                RequestBuilder.url(reqUrl);// 添加URL地址
                Request request = RequestBuilder.build();
                mOkHttpClient.newCall(request).enqueue(new Callback() {

                    @Override
                    public void onFailure(Call call, IOException e) {
                        emitter.onError(e);
                        emitter.onComplete();
                        call.cancel();
                    }

                    @Override
                    public void onResponse(Call call, Response response) throws IOException {
                        String str = response.body().string();
                        emitter.onNext(str);
                        emitter.onComplete();
                        call.cancel();
                    }
                });
            }
        });
    }

    public static Observable<String> post(String reqUrl, RequestBody requestBody) {
        getOkHttpClient();
        return Observable.create(new ObservableOnSubscribe<String>() {

            @Override
            public void subscribe(ObservableEmitter<String> emitter) throws Exception {
                //构建请求体
                Request.Builder RequestBuilder = new Request.Builder();
                RequestBuilder.url(reqUrl);// 添加URL地址
                RequestBuilder.post(requestBody);
                Request request = RequestBuilder.build();
                mOkHttpClient.newCall(request).enqueue(new Callback() {

                    @Override
                    public void onFailure(Call call, IOException e) {
                        emitter.onError(e);
                        emitter.onComplete();
                        call.cancel();
                    }

                    @Override
                    public void onResponse(Call call, Response response) throws IOException {
                        String str = response.body().string();
                        emitter.onNext(str);
                        emitter.onComplete();
                        call.cancel();
                    }
                });
            }
        });
    }

    /**
     * 上传文件
     *
     * @param reqUrl   URL地址
     * @param file_key 上传文件的关键字
     * @param files    文件
     * @param params   用戶ID,日誌類型
     */
    public static Observable<String> sendFileMultipart(String reqUrl, String file_key, List<File> files, HashMap<String, String> params) {
        getOkHttpClient();
        return Observable.create(new ObservableOnSubscribe<String>() {

            @Override
            public void subscribe(ObservableEmitter<String> emitter) throws Exception {
                MultipartBody.Builder multipartBodyBuilder = new MultipartBody.Builder();
                multipartBodyBuilder.setType(MultipartBody.FORM);
                //遍历map中所有参数到builder
                if (params != null) {
                    for (String key : params.keySet()) {
                        multipartBodyBuilder.addFormDataPart(key, params.get(key));
                    }
                }
                //遍历paths中所有图片绝对路径到builder，并约定key如“upload”作为后台接受多张图片的key
                if (files != null) {
                    for (int i = 0; i < files.size(); i++) {
                        multipartBodyBuilder.addFormDataPart(file_key, files.get(i).getName(), RequestBody.create(MEDIA_TYPE_PNG, files.get(i)));
                    }
                }
                //构建请求体
                RequestBody requestBody = multipartBodyBuilder.build();

                Request.Builder RequestBuilder = new Request.Builder();
                RequestBuilder.url(reqUrl);// 添加URL地址
                RequestBuilder.post(requestBody);
                Request request = RequestBuilder.build();
                mOkHttpClient.newCall(request).enqueue(new Callback() {

                    @Override
                    public void onFailure(Call call, IOException e) {
                        emitter.onError(e);
                        emitter.onComplete();
                        call.cancel();
                    }

                    @Override
                    public void onResponse(Call call, Response response) throws IOException {
                        String str = response.body().string();
                        emitter.onNext(str);
                        emitter.onComplete();
                        call.cancel();
                    }
                });
            }
        });
    }

    /**
     * 上传多张图片及参数
     *
     * @param reqUrl  URL地址
     * @param params  参数
     * @param pic_key 上传图片的关键字
     * @param files   图片文件
     */
    public static Observable<String> sendImageMultipart(String reqUrl, HashMap<String, String> params, String pic_key, List<File> files) {
        getOkHttpClient();
        return Observable.create(new ObservableOnSubscribe<String>() {

            @Override
            public void subscribe(ObservableEmitter<String> emitter) throws Exception {
                MultipartBody.Builder multipartBodyBuilder = new MultipartBody.Builder();
                multipartBodyBuilder.setType(MultipartBody.FORM);
                //遍历map中所有参数到builder
                if (params != null) {
                    for (String key : params.keySet()) {
                        multipartBodyBuilder.addFormDataPart(key, params.get(key));
                    }
                }
                //遍历paths中所有图片绝对路径到builder，并约定key如“upload”作为后台接受多张图片的key
                if (files != null) {
                    for (int i = 0; i < files.size(); i++) {
                        multipartBodyBuilder.addFormDataPart(pic_key + i, files.get(i).getName(), RequestBody.create(MEDIA_TYPE_PNG, files.get(i)));
                    }
                }
                //构建请求体
                RequestBody requestBody = multipartBodyBuilder.build();

                Request.Builder RequestBuilder = new Request.Builder();
                RequestBuilder.url(reqUrl);// 添加URL地址
                RequestBuilder.post(requestBody);
                Request request = RequestBuilder.build();
                mOkHttpClient.newCall(request).enqueue(new Callback() {

                    @Override
                    public void onFailure(Call call, IOException e) {
                        emitter.onError(e);
                        emitter.onComplete();
                        call.cancel();
                    }

                    @Override
                    public void onResponse(Call call, Response response) throws IOException {
                        String str = response.body().string();
                        emitter.onNext(str);
                        emitter.onComplete();
                        call.cancel();
                    }
                });
            }
        });
    }

    /**
     * 添加请求头
     */
    public static class UserAgentIntercepter implements Interceptor {

        @Override
        public Response intercept(Chain chain) throws IOException {
            Request request = chain.request();
            Headers headers = request.headers();

            Headers.Builder builder = new Headers.Builder();
            for (int i = 0; i < headers.size(); i++) {
                builder.set(headers.name(i), headers.value(i));
            }

            builder.set("mobileVersion", android.os.Build.VERSION.RELEASE);//set表示name1是唯一的，会覆盖掉已经存在的，add不会覆盖已经存在的头，可以存在多个
            builder.set("mobielModel", android.os.Build.MODEL);
            builder.set("apptype", AppConstans.APP_TYPE);
            builder.set("appinfo", DeviceUtils.getVersionName(GsaCloudApplication.getAppContext()));
            builder.set("mobileId", "1");

            if (GsaCloudApplication.isLogin) {
                String token;
                int memberId = GsaCloudApplication.getMemberId(GsaCloudApplication.getAppContext());
                String loginToken = GsaCloudApplication.getLoginToken(GsaCloudApplication.getAppContext());
                token = Aes.aesEncrypt("9_" + memberId + "_" + System.currentTimeMillis() + "_" + loginToken);
                token = token.replaceAll("\r|\n", "");
                builder.set("token", token);
            }
            Request request1 = chain.request().newBuilder().headers(builder.build()).build();
            return chain.proceed(request1);
        }
    }


}
