package com.dahe.pass.oss;

import android.app.Activity;
import android.app.ProgressDialog;
import android.graphics.Bitmap;
import android.util.Log;
import android.view.Window;
import android.widget.ImageView;
import android.widget.ProgressBar;

import androidx.core.widget.ContentLoadingProgressBar;

import com.alibaba.sdk.android.oss.ClientConfiguration;
import com.alibaba.sdk.android.oss.ClientException;
import com.alibaba.sdk.android.oss.OSS;
import com.alibaba.sdk.android.oss.OSSClient;
import com.alibaba.sdk.android.oss.ServiceException;
import com.alibaba.sdk.android.oss.callback.OSSCompletedCallback;
import com.alibaba.sdk.android.oss.callback.OSSProgressCallback;
import com.alibaba.sdk.android.oss.common.auth.OSSAuthCredentialsProvider;
import com.alibaba.sdk.android.oss.common.auth.OSSCredentialProvider;
import com.alibaba.sdk.android.oss.internal.OSSAsyncTask;
import com.alibaba.sdk.android.oss.model.OSSRequest;
import com.alibaba.sdk.android.oss.model.PutObjectRequest;
import com.alibaba.sdk.android.oss.model.PutObjectResult;
import com.dahe.pass.base.App;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.core.Observable;
import io.reactivex.rxjava3.functions.Consumer;

/**
 * @ClassName OssServiceUtil
 * @Author 用户
 * @Date 2021/9/29 17:53
 * @Description TODO
 */
public class OssServiceUtil {

    private static OSS oss;
    private static OSSCredentialProvider credentialProvider;
    private static ClientConfiguration conf;
    private String bucket;
    private picResultCallback callback;//回调接口
    private String path = "tms/user-cert/";
    private ProgressDialog dialog;

    private OssServiceUtil() {
    }

    private static volatile OssServiceUtil ossUtils;

    public static OssServiceUtil getInstance() {
        if (ossUtils == null) {
            synchronized (OssServiceUtil.class) {
                if (ossUtils == null) {
                    ossUtils = new OssServiceUtil();
                }
            }
        }
        return ossUtils;
    }



    private void initDialog(Activity activity) {
        dialog = new ProgressDialog(activity);
        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setCanceledOnTouchOutside(false);
        dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        dialog.setMessage("网络请求中......");
    }

    //初始化使用参数
    public void init(){
        bucket = "dh-tms";

        String stsServer = "http://tms.api.test.dahehuodongbao.com:8081/oss/getToken";


        credentialProvider = new OSSAuthCredentialsProvider(stsServer);

//        credentialProvider = new OSSPlainTextAKSKCredentialProvider(OssConfigBean.accessKeyId,OssConfigBean.accessKeySecret);
//        credentialProvider = new OSSCustomSignerCredentialProvider() {
//            @Override
//            public String signContent(String content) {
//                System.out.println(content);
//                return content;
//            }
//        };
        conf = new ClientConfiguration();
        conf.setConnectionTimeout(15 * 1000); // 连接超时，默认15秒
        conf.setSocketTimeout(15 * 1000); // socket超时，默认15秒
        conf.setMaxConcurrentRequest(5); // 最大并发请求书，默认5个
        conf.setMaxErrorRetry(2); // 失败后最大重试次数，默认2次

        oss = new OSSClient(App.mApplication, "oss-cn-beijing.aliyuncs.com", credentialProvider, conf);
//        initDialog(activity);
    }

    public void setResultCallBack(picResultCallback callback) {
        this.callback = callback;
    }

    /**
     * 图片以路径的方式上传
     * <p>
     * //     * @param 图片的上传地址（更后台要）
     * //     * @param 图片本地地址
     * //     * @param 进度条
     */
    public void asyncPutImage(final String localFile, final ContentLoadingProgressBar mProgress) {
//        if (object.equals("")) {
//            return;
//        }

        File file = new File(localFile);
        if (!file.exists()) {
            return;
        }
        String name = file.getName();
        // 构造上传请求
        PutObjectRequest put = new PutObjectRequest(OssConfigBean.bucket, OssConfigBean.BUCKET_OBJECT+name, localFile);

        put.setCRC64(OSSRequest.CRC64Config.YES);
        String mCallbackAddress = OssConfigBean.OSS_CALLBACK_URL;
//        if (mCallbackAddress != null) {
//            // 传入对应的上传回调参数，这里默认使用OSS提供的公共测试回调服务器地址
//            put.setCallbackParam(new HashMap<String, String>() {
//                {
//                    put("callbackUrl", mCallbackAddress);
//                    //callbackBody可以自定义传入的信息
//                    put("callbackBody", "filename=${object}");
//                }
//            });
//        }

        //上传后回调通知
        // 异步上传时可以设置进度回调
        put.setProgressCallback(new OSSProgressCallback<PutObjectRequest>() {
            @Override
            public void onProgress(PutObjectRequest request, long currentSize, long totalSize) {
                int progress = (int) (100 * currentSize / totalSize);
                if (mProgress != null) {
                    mProgress.setProgress(progress);
                }
                if (dialog!=null){
                    dialog.show();
                }
            }
        });

        OSSAsyncTask task = oss.asyncPutObject(put, new OSSCompletedCallback<PutObjectRequest, PutObjectResult>() {
            @Override
            public void onSuccess(PutObjectRequest request, final PutObjectResult result) {
                if (dialog!=null){
                    dialog.dismiss();
                }
                String serverCallbackReturnBody = result.getServerCallbackReturnBody();
                callback.getPicData(result, OssConfigBean.BUCKET_BASE_URL+ OssConfigBean.BUCKET_OBJECT+name);
            }

            @Override
            public void onFailure(PutObjectRequest request, ClientException clientExcepion, ServiceException serviceException) {
                if (dialog!=null){
                    dialog.dismiss();
                }
                String info = "";
                // 请求异常
                if (clientExcepion != null) {
                    // 本地异常如网络异常等
                    clientExcepion.printStackTrace();
                    info = clientExcepion.toString();
                }
                if (serviceException != null) {
                    // 服务异常
                    Log.e("ErrorCode", serviceException.getErrorCode());
                    Log.e("RequestId", serviceException.getRequestId());
                    Log.e("HostId", serviceException.getHostId());
                    Log.e("RawMessage", serviceException.getRawMessage());
                    info = serviceException.toString();
                }
//                task.cancel();
            }
        });
    }


    /**
     * 上传次数
     */
    int number;
    /**
     * 成功上传(本地文件名作为key,阿里云地址为value)
     */
    List<String> success = new ArrayList<>();
    /**
     * 失败上传(返回失败文件的本地地址)
     */
    List<String> failure = new ArrayList<>();

    /**
     * 批量上传图片
     * @param localFiles
     */
    public void asyncPutImages(final List<String> localFiles,PicsResultCallback callback){
        //初始化
        number = 1;
        success.clear();
        for (int i = 0; i < localFiles.size(); i++) {
            File file = new File(localFiles.get(i));
            if (!file.exists()) {
                return;
            }
            String name = file.getName();
            // 构造上传请求
            PutObjectRequest put = new PutObjectRequest(OssConfigBean.bucket, OssConfigBean.BUCKET_OBJECT+name, localFiles.get(i));

            put.setCRC64(OSSRequest.CRC64Config.YES);

            oss.asyncPutObject(put, new OSSCompletedCallback<PutObjectRequest, PutObjectResult>() {
                @Override
                public void onSuccess(PutObjectRequest request, final PutObjectResult result) {

                    String aliPath = OssConfigBean.BUCKET_BASE_URL+ OssConfigBean.BUCKET_OBJECT+name;
                    success.add(aliPath);
                    if (number == localFiles.size()) {
                        //返回 上传路径,以及失败的路径
                        callback.onOssSuccess(success, failure);
                    }
                    number++;
                }

                @Override
                public void onFailure(PutObjectRequest request, ClientException clientExcepion, ServiceException serviceException) {
                    number++;
                    String aliPath = OssConfigBean.BUCKET_BASE_URL+ OssConfigBean.BUCKET_OBJECT+name;
                    failure.add(aliPath);
                    if (number == localFiles.size()) {
                        callback.onOssSuccess(success, failure);
                    }
                }
            });
        }

    }

    /**
     * 图片以bitmap的形式上传
     *
     * @param object
     * @param localFile
     * @param mProgress
     * @param img
     * @param type
     */
    public void asyncPutImage(String object, final Bitmap localFile, final ProgressBar mProgress, final ImageView img, String type) {
        if (object.equals("")) {
            Log.w("AsyncPutImage", "ObjectNull");
            return;
        }
        if (localFile == null) {
            Log.w("AsyncPutImage", "bitmapNull");
            return;
        }

        // 构造上传请求
        PutObjectRequest put = new PutObjectRequest(bucket, object, getBitmapByte(localFile));
        //上传后回调通知
        // 客户端在上传Object时可以指定OSS服务端在处理完上传请求后，通知您的业务服务器，在该服务器确认接收了该回调后将回调的结果返回给客户端。
        put.setCallbackParam(new HashMap<String, String>() {
            {
                put("callbackUrl", path);
                put("callbackBody",
//参数跟后台商议
                        "filename=${object}&size=${size}&action=${x:action}}");
            }
        });
        HashMap<String, String> hashMap = new HashMap<>();
        hashMap.put("x:action", type);
        put.setCallbackVars(hashMap);
        OSSAsyncTask task = oss.asyncPutObject(put, new OSSCompletedCallback<PutObjectRequest, PutObjectResult>() {
            @Override
            public void onSuccess(PutObjectRequest request, final PutObjectResult result) {

                Observable.just(result).observeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer<PutObjectResult>() {
                    @Override
                    public void accept(PutObjectResult putObjectResult) throws Throwable {
                        callback.getPicData(result, "");
                    }
                });
//                Observable.just(result).observeOn(AndroidSchedulers.mainThread()).subscribe(putObjectResult -> callback.getPicData(result, ""));
            }

            @Override
            public void onFailure(PutObjectRequest request, ClientException clientExcepion, ServiceException serviceException) {
                String info = "";
                // 请求异常
                if (clientExcepion != null) {
                    // 本地异常如网络异常等
                    clientExcepion.printStackTrace();
                    info = clientExcepion.toString();
                }
                if (serviceException != null) {
                    // 服务异常
                    Log.e("ErrorCode", serviceException.getErrorCode());
                    Log.e("RequestId", serviceException.getRequestId());
                    Log.e("HostId", serviceException.getHostId());
                    Log.e("RawMessage", serviceException.getRawMessage());
                    info = serviceException.toString();
                }
            }
        });
    }

    public byte[] getBitmapByte(Bitmap bitmap) {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
        try {
            out.flush();
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return out.toByteArray();
    }

    public interface picResultCallback {
        void getPicData(PutObjectResult data, String oldPath);
    }

    public interface PicsResultCallback {
        void onOssSuccess(List<String> success, List<String> failure);
    }
}
