package com.rn.na.qiniu;

import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;

import org.json.JSONObject;

import android.util.Log;

import androidx.annotation.Nullable;

import com.facebook.react.bridge.WritableMap;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.qiniu.android.storage.UpCancellationSignal;
import com.qiniu.android.storage.UpCompletionHandler;
import com.qiniu.android.storage.Configuration;
import com.qiniu.android.storage.UpProgressHandler;
import com.qiniu.android.storage.UploadManager;
import com.qiniu.android.http.ResponseInfo;
import com.qiniu.android.storage.UploadOptions;

public class RNNativeQiniuModule extends ReactContextBaseJavaModule {

  private final ReactApplicationContext reactContext;
  private UploadManager uploadManager;
  private volatile Boolean isCancelled;
  String UploadProgresseEventName = "uploadProgress";


  public RNNativeQiniuModule(ReactApplicationContext reactContext) {
    super(reactContext);
    this.reactContext = reactContext;
  }

  private void sendEvent(ReactContext reactContext,
                         String eventName,
                         @Nullable WritableMap params) {
    reactContext
      .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
      .emit(eventName, params);
  }

  @Override
  public String getName() {
    return "RNNativeQiniu";
  }


  @ReactMethod
  public void config(Boolean useHttps, Boolean useConcurrentResumeUpload, int concurrentTaskCount, int connectTimeout, int responseTimeout) {
    Configuration config = new Configuration.Builder()
      .useHttps(useHttps)               // 是否使用https上传域名
      .useConcurrentResumeUpload(useConcurrentResumeUpload) // 使用并发上传，使用并发上传时，除最后一块大小不定外，其余每个块大小固定为4M，
      .concurrentTaskCount(concurrentTaskCount)          // 并发上传线程数量为3
      .connectTimeout(connectTimeout)           // 链接超时。默认10秒
      .responseTimeout(responseTimeout)          // 服务器响应超时。默认60秒
      .build();
    uploadManager = new UploadManager(config);//配置3个线程数并发上传；不配置默认为3，只针对file.size>4M生效。线程数建议不超过5，上传速度主要取决于上行带宽，带宽很小的情况单线程和多线程没有区别
  }

  @ReactMethod
  public void upload(final String uri, String key, String token, final Promise promise) {
    isCancelled = false;
    uploadManager.put(uri.replace("file://", ""), key, token,
      new UpCompletionHandler() {
        @Override
        public void complete(String key, ResponseInfo info, JSONObject res) {
          //res包含hash、key等信息，具体字段取决于上传策略的设置
          WritableMap params = Arguments.createMap();
          params.putInt("status", info.statusCode);
          params.putString("error", info.error);
          promise.resolve(params);
          Log.i("qiniu", key + ",\r\n " + info + ",\r\n " + res + ",\r\n" + uri);
        }
      }, new UploadOptions(null, null, false,
        new UpProgressHandler() {
          public void progress(String key, double percent) {
            WritableMap params = Arguments.createMap();
            params.putString("key", key);
            params.putDouble("percent", percent);
            sendEvent(reactContext, UploadProgresseEventName, params);
            Log.i("qiniu", key + ": " + percent);
          }
        }, new UpCancellationSignal() {
        public boolean isCancelled() {
          return isCancelled;
        }
      }));
  }

  @ReactMethod
  public void cancel() {
    isCancelled = true;
  }
}
