/*
 * Version for React Native
 * © 2020 YANDEX
 * You may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * https://yandex.com/legal/appmetrica_sdk_agreement/
 */

package com.yandex.metrica.plugin.reactnative;

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

import com.facebook.react.bridge.Callback;
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.ReadableMap;

import java.util.ArrayList;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;

import io.appmetrica.analytics.AppMetrica;
import io.appmetrica.analytics.ecommerce.ECommerceCartItem;
import io.appmetrica.analytics.ecommerce.ECommerceEvent;
import io.appmetrica.analytics.ecommerce.ECommerceProduct;
import io.appmetrica.analytics.ecommerce.ECommerceScreen;
import io.appmetrica.analytics.ecommerce.ECommerceReferrer;
import io.appmetrica.analytics.ecommerce.ECommerceOrder;

public class AppMetricaModule extends ReactContextBaseJavaModule {

    private static final String TAG = "AppMetricaModule";

    private final ReactApplicationContext reactContext;

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

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

    @ReactMethod
    public void activate(ReadableMap configMap) {
        AppMetrica.activate(reactContext, Utils.toYandexMetricaConfig(configMap));
        enableActivityAutoTracking();
    }

    private void enableActivityAutoTracking() {
        Activity activity = getCurrentActivity();
        if (activity != null) { // TODO: check
            AppMetrica.enableActivityAutoTracking(activity.getApplication());
        } else {
            Log.w(TAG, "Activity is not attached");
        }
    }

    @ReactMethod
    public void getLibraryApiLevel(Promise promise) {
        promise.resolve(AppMetrica.getLibraryApiLevel());
    }

    @ReactMethod
    public void getLibraryVersion(Promise promise) {
        promise.resolve(AppMetrica.getLibraryVersion());
    }

    @ReactMethod
    public void pauseSession() {
        AppMetrica.pauseSession(getCurrentActivity());
    }

    @ReactMethod
    public void reportAppOpen(String deeplink) {
        AppMetrica.reportAppOpen(deeplink);
    }

    @ReactMethod
    public void reportError(String message) {
        try {
            Integer.valueOf("00xffWr0ng");
        } catch (Throwable error) {
            AppMetrica.reportError(message, error);
        }
    }

    @ReactMethod
    public void reportEvent(String eventName, ReadableMap attributes) {
        if (attributes == null) {
            AppMetrica.reportEvent(eventName);
        } else {
            AppMetrica.reportEvent(eventName, attributes.toHashMap());
        }
    }

    @ReactMethod
    public void reportEcommerceProductCardShow(ReadableMap productInfo, ReadableMap screenInfo) {
        ECommerceProduct product = Utils.toEcommerceProduct(productInfo);
        ECommerceScreen screen = Utils.toEcommerceScreen(screenInfo);
        if (product == null || screen == null) {
            return;
        }

        AppMetrica.reportECommerce(ECommerceEvent.showProductCardEvent(product, screen));
    }

    @ReactMethod
    public void reportEcommerceProductDetailShow(ReadableMap productInfo, @Nullable ReadableMap refererInfo) {
        ECommerceProduct product = Utils.toEcommerceProduct(productInfo);
        if (product == null) {
            return;
        }

        ECommerceReferrer referrer = Utils.toEcommerceReferer(refererInfo);
        AppMetrica.reportECommerce(ECommerceEvent.showProductDetailsEvent(product, referrer));
    }

    @ReactMethod
    public void reportEcommerceAddCartItem(ReadableMap cartItemInfo, @Nullable ReadableMap refererInfo) {
        ECommerceCartItem cartItem = Utils.toEcommerceCartItem(cartItemInfo);
        if (cartItem == null) {
            return;
        }

        cartItem.setReferrer(Utils.toEcommerceReferer(refererInfo));
        AppMetrica.reportECommerce(ECommerceEvent.addCartItemEvent(cartItem));
    }

    @ReactMethod
    public void reportEcommerceRemoveCartItem(ReadableMap cartItemInfo, @Nullable ReadableMap refererInfo) {
        ECommerceCartItem cartItem = Utils.toEcommerceCartItem(cartItemInfo);
        if (cartItem == null) {
            return;
        }

        cartItem.setReferrer(Utils.toEcommerceReferer(refererInfo));
        AppMetrica.reportECommerce(ECommerceEvent.removeCartItemEvent(cartItem));
    }

    @ReactMethod
    public void reportEcommerceBeginCheckout(ReadableMap orderInfo) {
        ECommerceOrder order = Utils.toEcommerceOrder(orderInfo);
        if (order == null) {
            return;
        }

        AppMetrica.reportECommerce(ECommerceEvent.beginCheckoutEvent(order));
    }

    @ReactMethod
    public void reportEcommercePurchase(ReadableMap orderInfo) {
        ECommerceOrder order = Utils.toEcommerceOrder(orderInfo);
        if (order == null) {
            return;
        }

        AppMetrica.reportECommerce(ECommerceEvent.purchaseEvent(order));
    }

    @ReactMethod
    public void requestAppMetricaDeviceID(Callback listener) {
        ArrayList<String> list = new ArrayList<>();
        list.add(ReactNativeStartupParamsCallback.APPMETRICA_DEVICE_ID_HASH);
        list.add(ReactNativeStartupParamsCallback.APPMETRICA_DEVICE_ID);
        list.add(ReactNativeStartupParamsCallback.APPMETRICA_UUID);

        AppMetrica.requestStartupParams(reactContext, new ReactNativeStartupParamsCallback(listener), list);
    }

    @ReactMethod
    public void resumeSession() {
        AppMetrica.resumeSession(getCurrentActivity());
    }

    @ReactMethod
    public void sendEventsBuffer() {
        AppMetrica.sendEventsBuffer();
    }

    @ReactMethod
    public void setLocation(ReadableMap locationMap) {
        AppMetrica.setLocation(Utils.toLocation(locationMap));
    }

    @ReactMethod
    public void setLocationTracking(boolean enabled) {
        AppMetrica.setLocationTracking(enabled);
    }

    @ReactMethod
    public void setUserProfileID(String userProfileID) {
        AppMetrica.setUserProfileID(userProfileID);
    }
}
