package com.reactnativepayengine.collect;

import android.app.Activity;
import android.content.Intent;
import android.util.Log;

import androidx.annotation.NonNull;

import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.reactnativepayengine.util.JSONObjectUtil;
import com.verygoodsecurity.vgscollect.VGSCollectLogger;
import com.verygoodsecurity.vgscollect.core.Environment;
import com.verygoodsecurity.vgscollect.core.HTTPMethod;
import com.verygoodsecurity.vgscollect.core.VGSCollect;
import com.verygoodsecurity.vgscollect.core.model.network.VGSRequest;
import com.verygoodsecurity.vgscollect.core.model.network.VGSResponse;
import com.verygoodsecurity.vgscollect.core.model.state.FieldState;
import com.verygoodsecurity.vgscollect.view.InputFieldView;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.HashMap;
import java.util.List;
import java.util.Optional;

public class VGSCollectModule extends ReactContextBaseJavaModule {

  private static ReactApplicationContext reactContext;

  private VGSCollect collect;

  public VGSCollectModule(ReactApplicationContext c) {
    super(c);
    reactContext = c;
  }

  @Override
  public void initialize() {
    super.initialize();
//    Activity activity = reactContext.getCurrentActivity();
//    collect = new VGSCollect.Builder(activity, "")
//      .create();
  }

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

  @ReactMethod
  public void setConfiguration(String vaultId, String environment, String cname, double vgsSatellitePort) {
    Log.e("test", "Create event called with name: " + vaultId + " and location: " + environment + " cname: " + cname);

    VGSCollectLogger.INSTANCE.setLogLevel(VGSCollectLogger.Level.DEBUG);

    Activity activity = reactContext.getCurrentActivity();
    collect = new VGSCollect.Builder(activity, vaultId)
      .setEnvironment(environment)
//      .setHostname(cname)
//      .setPort((int) Math.round(vgsSatellitePort))
      .create();

  }

  @ReactMethod
  public void createCard(String merchantId, Promise promise) {
    this.submit("/api/cards", merchantId, promise);
  }

  @ReactMethod
  public void createBankAccount(String merchantId, Promise promise) {
    this.submit("/api/bank-accounts", merchantId, promise);
  }

  private void submit(String path, String merchantId, Promise promise) {
    HashMap<String, Object> customData = new HashMap<>();
    customData.put("pci_vault_provider", "vgs");
    if (merchantId != null && !merchantId.isEmpty()) {
      customData.put("merchant_id", merchantId);
    }

    HashMap<String, String> headers = new HashMap<>();
    headers.put("CUSTOM-HEADER", "custom-header");

    List<FieldState> states = collect.getAllStates();

    for (int i = 0; i < states.size(); i++) {
      FieldState state = states.get(i);

      if (!state.isValid()) {
        String message = new StringBuilder("Field ")
          .append(state.getFieldName())
          .append(" is not valid.")
          .toString();
        promise.reject("validation_error", message);
        return;
      }
      if (state instanceof FieldState.CardNumberState) {
        FieldState.CardNumberState cardState = (FieldState.CardNumberState) state;
        customData.put("last_4", cardState.getNumber());
        customData.put("bin", cardState.getBin());
        customData.put("brand", cardState.getCardBrand());
      }
    }

    VGSRequest request = new VGSRequest.VGSRequestBuilder()
      .setMethod(HTTPMethod.POST)
      .setPath(path)
      .setCustomHeader(headers)
      .setCustomData(customData)
      .build();

    VGSResponse response = collect.submit(request);
    Log.e("test", "response " + response.getBody());
    if (response instanceof VGSResponse.SuccessResponse) {
      VGSResponse.SuccessResponse result = (VGSResponse.SuccessResponse) response;
      try {
        JSONObject jsonObj = new JSONObject(result.getBody());
        promise.resolve(JSONObjectUtil.convertJsonToMap(jsonObj.getJSONObject("data")));
        return;
      } catch (JSONException e) {
        e.printStackTrace();
        promise.reject("invalid_response", "We got success response but unable to parse it");
      }
    } else if (response instanceof VGSResponse.ErrorResponse) {
      VGSResponse.ErrorResponse error = (VGSResponse.ErrorResponse) response;
      promise.reject(String.valueOf(error.getErrorCode()), error.getLocalizeMessage());
    }

  }

  public void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
    if (collect != null) {
      collect.onActivityResult(requestCode, resultCode, data);
    }
  }

  public void bindView(InputFieldView inputFieldView) {
    Log.e("test", "collect bindView " + inputFieldView.getFieldName() + " - Collect " + collect.getAllStates());
    collect.bindView(inputFieldView);
  }
}
