// WunderkindSdkModule.java

package co.wunderkind.sdk;

import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.Callback;

import androidx.annotation.NonNull;

import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;

import org.jetbrains.annotations.NotNull;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import co.wunderkind.sdk.Currency;
import co.wunderkind.sdk.Customer;
import co.wunderkind.sdk.Invoice;
import co.wunderkind.sdk.LoginMethod;
import co.wunderkind.sdk.Order;
import co.wunderkind.sdk.Product;
import co.wunderkind.sdk.ProductCategory;
import co.wunderkind.sdk.ScreenType;
import co.wunderkind.sdk.Wunderkind;
import co.wunderkind.sdk.other.log.LogLevel;

public class WunderkindSdkModule extends ReactContextBaseJavaModule {

    private final ReactApplicationContext reactContext;
    Wunderkind wunderkind = Wunderkind.getInstance();

    public WunderkindSdkModule(ReactApplicationContext reactContext) {
        this.reactContext = reactContext;
    }

    @NonNull
    @Override
    public String getName() {
        return "WunderkindProvider";
    }

    @ReactMethod
    public void initializeSdk(@NotNull Double websiteId, boolean isDebugMode) {
        wunderkind.initialize(reactContext, websiteId.longValue(), isDebugMode);
    }

    @ReactMethod
    public void trackScreenView(@NotNull String url, int screenType) {
        URL i = null;
        try {
            i = new URL(url);
        } catch (MalformedURLException e) {
            e.printStackTrace();
            return;
        }
        wunderkind.trackScreenView(i, ScreenType.values()[screenType]);
    }

    @ReactMethod
    public void trackViewItem(@NotNull String itemId, @NotNull String groupId) {
        wunderkind.trackViewItem(itemId, groupId);
    }

    @ReactMethod
    public void trackAddToCart(@NotNull String itemId) {
        wunderkind.trackAddToCart(itemId);
    }

    @ReactMethod
    public void trackEmptyCart() {
        wunderkind.trackEmptyCart();
    }

    @ReactMethod
    public void trackViewCategory(@NotNull ReadableMap map) {
        wunderkind.trackViewCategory(mapToCategory(map));
    }

    @ReactMethod
    public void trackLoggedIn(@NotNull String email, int loginMethod) {
        wunderkind.trackLoggedIn(email, LoginMethod.values()[loginMethod]);
    }

    @ReactMethod
    public void trackHashedLoggedIn(@NotNull String email, int loginMethod) {
        wunderkind.trackHashedLoggedIn(email, LoginMethod.values()[loginMethod]);
    }

    @ReactMethod
    public void trackSelectSku(@NotNull String groupId, @NotNull String feedId) {
        wunderkind.trackSelectSku(groupId, feedId);
    }

    @ReactMethod
    public void trackViewSearch(@NotNull ReadableMap map) {
        wunderkind.trackViewSearch(mapToCategory(map));
    }

    @ReactMethod
    public void trackPurchase(@NotNull ReadableMap map) {
        wunderkind.trackPurchase(mapToOrder(map));
    }

    @ReactMethod
    public Double getVisitDuration(){
        return Double.valueOf(wunderkind.getVisitDuration());
    }

    @ReactMethod
    public void setLogLevel(@NotNull Double pos){
        wunderkind.setLogLevel(LogLevel.values()[pos.intValue()]);
    }

    @ReactMethod
    public boolean getIsContextInfoTrackingEnabled(){
        return wunderkind.getIsContextInfoTrackingEnabled();
    }

    @ReactMethod
    public void setIsContextInfoTrackingEnabled(boolean isEnabled){
        wunderkind.setIsContextInfoTrackingEnabled(isEnabled);
    }

    @ReactMethod
    public boolean getIsAAIDTrackingEnabled(){
        return wunderkind.getIsAAIDTrackingEnabled();
    }

    @ReactMethod
    public void setIsAAIDTrackingEnabled(boolean isEnabled){
        wunderkind.setIsContextInfoTrackingEnabled(isEnabled);
    }

    @ReactMethod
    public boolean getIsLocationTrackingEnabled(){
        return wunderkind.getIsAAIDTrackingEnabled();
    }

    @ReactMethod
    public void setIsLocationTrackingEnabled(boolean isEnabled){
        wunderkind.setIsLocationTrackingEnabled(isEnabled);
    }


    String titleKey = "title";
    String urlKey = "url";
    String itemIdsKey = "itemIds";
    public ProductCategory mapToCategory(@NotNull ReadableMap map){
        URL url = null;
        try {
            url = new URL(map.getString(urlKey));
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
        ProductCategory category = new ProductCategory(
                map.getString(titleKey),
                url,
                map.getArray(itemIdsKey).toArrayList().stream().map(Object::toString).collect(Collectors.toList())
        );
        return category;
    }

    //Order keys
    String orderIdKey = "orderId";
    String invoiceKey = "invoice";
    String paymentMethodKey = "paymentMethod";
    String productsKey = "products";
    String customerKey = "customer";
    String couponsKey = "coupons";
    String goalKey = "goal";
    //Invoice keys
    String amountKey = "amount";
    String taxKey = "tax";
    String shippingKey = "shipping";
    String totalDiscountKey = "totalDiscount";
    String currencyKey = "currency";
    //Customer
    String emailKey = "email";
    String phoneKey = "phone";
    public Order mapToOrder(@NotNull ReadableMap map){
        String orderId = map.getString(orderIdKey);

        ReadableMap invoiceMap = map.getMap(invoiceKey);
        double amount = invoiceMap.getDouble(amountKey);
        double tax = invoiceMap.getDouble(taxKey);
        double shipping = invoiceMap.getDouble(shippingKey);
        Double totalDiscount = invoiceMap.getDouble(totalDiscountKey);
        Currency currency = Currency.values()[(int)invoiceMap.getDouble(currencyKey)];
        Invoice invoice = new Invoice(amount,tax,shipping,totalDiscount,currency);

        String paymentMethod = map.getString(paymentMethodKey);
        List<Product> products = new ArrayList<>();
        ReadableArray couponsArrayMap = map.getArray(productsKey);
        for (int i = 0; i < couponsArrayMap.size(); i++) {
            ReadableMap readableMap = couponsArrayMap.getMap(i);
            products.add(mapToProduct(readableMap));
        }
        ReadableMap customerMap = map.getMap(customerKey);
        String email = customerMap.getString(emailKey);
        String phone = customerMap.getString(phoneKey);
        Customer customer = new Customer(email, phone);
        List<String> coupons = map.getArray(couponsKey).toArrayList().stream().map(Object::toString).collect(Collectors.toList());

        String goal = map.getString(goalKey);
        return new Order(
                orderId,
                invoice,
                paymentMethod,
                products,
                customer,
                coupons,
                goal
        );
    }

    String productIdKey = "productId";
    String skuIdKey = "skuId";
    String priceKey = "price";
    String quantityKey = "quantity";
    public Product mapToProduct(@NotNull ReadableMap map){
        String productId = map.getString(productIdKey);
        String skuId = map.getString(skuIdKey);
        double price = map.getDouble(priceKey);
        long quantity = ((Double)map.getDouble(quantityKey)).longValue();
        return new Product(
                productId,
                skuId,
                price,
                quantity
        );
    }
}