package com.pixelpay.reactnativeplugin;

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.bridge.WritableMap;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.module.annotations.ReactModule;

import com.pixel.sdk.base.Helpers;
import com.pixel.sdk.base.Response;
import com.pixel.sdk.mobile.services.Tokenization;
import com.pixel.sdk.mobile.services.Transaction;
import com.pixel.sdk.models.Settings;
import com.pixel.sdk.requests.AuthTransaction;
import com.pixel.sdk.requests.CaptureTransaction;
import com.pixel.sdk.requests.CardTokenization;
import com.pixel.sdk.requests.SaleTransaction;
import com.pixel.sdk.requests.StatusTransaction;
import com.pixel.sdk.requests.VoidTransaction;

import java.util.HashMap;
import java.util.Map;

@ReactModule(name = ReactNativePluginModule.NAME)
public class ReactNativePluginModule extends ReactContextBaseJavaModule {
	public static final String NAME = "ReactNativePlugin";

	public ReactNativePluginModule(ReactApplicationContext reactContext) {
		super(reactContext);
	}

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

	private Transaction getTransactionService(String settings) {
		return (new Transaction(Helpers.jsonToObject(settings, Settings.class), getCurrentActivity()));
	}

	private Tokenization getTokenizationService(String settings) {
		return (new Tokenization(Helpers.jsonToObject(settings, Settings.class), getCurrentActivity()));
	}

	private void parseSuccess(Promise promise, Response response) {
		WritableMap map = Arguments.createMap();

		map.putString("status", String.valueOf(response.getStatus()));
		map.putString("response", response.toJson());

		promise.resolve(map);
	}

	private void parseError(Promise promise, Exception error, String code) {
		promise.reject(code, error.getLocalizedMessage(), error);
	}

	@ReactMethod
	public void transactionDoSale(String settings, String request, Promise promise) {
		this.getTransactionService(settings)
				.doSale(Helpers.jsonToObject(request, SaleTransaction.class))
				.then(response -> this.parseSuccess(promise, response))
				.thenCatch(err -> this.parseError(promise, err, "transaction-error"))
				.start();
	}

	@ReactMethod
	public void transactionDoAuth(String settings, String request, Promise promise) {
		this.getTransactionService(settings)
				.doAuth(Helpers.jsonToObject(request, AuthTransaction.class))
				.then(response -> this.parseSuccess(promise, response))
				.thenCatch(err -> this.parseError(promise, err, "transaction-error"))
				.start();
	}

	@ReactMethod
	public void transactionDoCapture(String settings, String request, Promise promise) {
		this.getTransactionService(settings)
				.doCapture(Helpers.jsonToObject(request, CaptureTransaction.class))
				.then(response -> this.parseSuccess(promise, response))
				.thenCatch(err -> this.parseError(promise, err, "transaction-error"))
				.start();
	}

	@ReactMethod
	public void transactionDoVoid(String settings, String request, Promise promise) {
		this.getTransactionService(settings)
				.doVoid(Helpers.jsonToObject(request, VoidTransaction.class))
				.then(response -> this.parseSuccess(promise, response))
				.thenCatch(err -> this.parseError(promise, err, "transaction-error"))
				.start();
	}

	@ReactMethod
	public void transactionGetStatus(String settings, String request, Promise promise) {
		this.getTransactionService(settings)
				.getStatus(Helpers.jsonToObject(request, StatusTransaction.class))
				.then(response -> this.parseSuccess(promise, response))
				.thenCatch(err -> this.parseError(promise, err, "transaction-error"))
				.start();
	}

	@ReactMethod
	public void tokenizationVaultCard(String settings, String request, Promise promise) {
		this.getTokenizationService(settings)
				.vaultCard(Helpers.jsonToObject(request, CardTokenization.class))
				.then(response -> this.parseSuccess(promise, response))
				.thenCatch(err -> this.parseError(promise, err, "tokenization-error"))
				.start();
	}

	@ReactMethod
	public void tokenizationUpdateCard(String settings, String token, String request, Promise promise) {
		this.getTokenizationService(settings)
				.updateCard(token, Helpers.jsonToObject(request, CardTokenization.class))
				.then(response -> this.parseSuccess(promise, response))
				.thenCatch(err -> this.parseError(promise, err, "tokenization-error"))
				.start();
	}

	@ReactMethod
	public void tokenizationShowCard(String settings, String token, Promise promise) {
		this.getTokenizationService(settings)
				.showCard(token)
				.then(response -> this.parseSuccess(promise, response))
				.thenCatch(err -> this.parseError(promise, err, "tokenization-error"))
				.start();
	}

	@ReactMethod
	public void tokenizationShowCards(String settings, String tokens, Promise promise) {
		this.getTokenizationService(settings)
				.showCards(tokens.split("|"))
				.then(response -> this.parseSuccess(promise, response))
				.thenCatch(err -> this.parseError(promise, err, "tokenization-error"))
				.start();
	}

	@ReactMethod
	public void tokenizationDeleteCard(String settings, String token, Promise promise) {
		this.getTokenizationService(settings)
				.deleteCard(token)
				.then(response -> this.parseSuccess(promise, response))
				.thenCatch(err -> this.parseError(promise, err, "tokenization-error"))
				.start();
	}
}
