/*
 * 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/
 */

#import "AppMetrica.h"
#import "AppMetricaUtils.h"

static NSString *const kYMMReactNativeExceptionName = @"ReactNativeException";

@implementation AppMetrica

@synthesize methodQueue = _methodQueue;

RCT_EXPORT_MODULE()

RCT_EXPORT_METHOD(activate:(NSDictionary *)configDict)
{
    [AMAAppMetrica activateWithConfiguration:[AppMetricaUtils configurationForDictionary:configDict]];
    [[AMAAppMetricaCrashes crashes] setConfiguration:[AppMetricaUtils crashesConfigurationForDictionary:configDict]];
    if (configDict[@"errorEnvironment"] != nil) {
        for (NSString* key in configDict[@"errorEnvironment"]) {
            [[AMAAppMetricaCrashes crashes] setErrorEnvironmentValue:configDict[@"errorEnvironment"][key] forKey:key];
        }
    }
}

RCT_EXPORT_METHOD(getLibraryApiLevel)
{
    // It does nothing for iOS
}

RCT_EXPORT_METHOD(getLibraryVersion:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
{
    resolve([AMAAppMetrica libraryVersion]);
}

RCT_EXPORT_METHOD(pauseSession)
{
    [AMAAppMetrica pauseSession];
}

RCT_EXPORT_METHOD(reportAppOpen:(NSString *)deeplink)
{
    [AMAAppMetrica trackOpeningURL:[NSURL URLWithString:deeplink]];
}

RCT_EXPORT_METHOD(reportError:(NSString *)message) {
    AMAError *error = [AMAError errorWithIdentifier:@"" message:message parameters:nil];
    [[AMAAppMetricaCrashes crashes] reportError:error onFailure:NULL];
}

RCT_EXPORT_METHOD(reportEvent:(NSString *)eventName:(NSDictionary *)attributes)
{
    if (attributes == nil) {
        [AMAAppMetrica reportEvent:eventName onFailure:^(NSError *error) {
            NSLog(@"error: %@", [error localizedDescription]);
        }];
    } else {
        [AMAAppMetrica reportEvent:eventName parameters:attributes onFailure:^(NSError *error) {
            NSLog(@"error: %@", [error localizedDescription]);
        }];
    }
}

RCT_EXPORT_METHOD(reportEcommerceProductCardShow:(NSDictionary *)productInfo:(NSDictionary *)screenInfo)
{
    AMAECommerceProduct *product = [AppMetricaUtils toEcommerceProduct:productInfo];
    AMAECommerceScreen *screen = [AppMetricaUtils toEcommerceScreen:screenInfo];
    if (product == nil || screen == nil) {
        return;
    }
    [AMAAppMetrica reportECommerce:[AMAECommerce showProductCardEventWithProduct:product screen:screen] onFailure:nil];
}

RCT_EXPORT_METHOD(reportEcommerceProductDetailShow:(NSDictionary *)productInfo :(NSDictionary *)refererInfo)
{
    AMAECommerceProduct *product = [AppMetricaUtils toEcommerceProduct:productInfo];
    if (product == nil) {
        return;
    }
    
    AMAECommerceReferrer *referer = [AppMetricaUtils toEcommerceReferer:refererInfo];
    [AMAAppMetrica reportECommerce:[AMAECommerce showProductDetailsEventWithProduct:product referrer:referer] onFailure:nil];
}

RCT_EXPORT_METHOD(reportEcommerceAddCartItem:(NSDictionary *)cartItemInfo :(NSDictionary *)refererInfo)
{
    AMAECommerceCartItem *cartItem = [AppMetricaUtils toEcommerceCartItem:cartItemInfo :refererInfo];
    if (cartItem == nil) {
        return;
    }

    [AMAAppMetrica reportECommerce:[AMAECommerce addCartItemEventWithItem:cartItem] onFailure:nil];
}

RCT_EXPORT_METHOD(reportEcommerceRemoveCartItem:(NSDictionary *)cartItemInfo :(NSDictionary *)refererInfo)
{
    AMAECommerceCartItem *cartItem = [AppMetricaUtils toEcommerceCartItem:cartItemInfo :refererInfo];
    if (cartItem == nil) {
        return;
    }

    [AMAAppMetrica reportECommerce:[AMAECommerce removeCartItemEventWithItem:cartItem] onFailure:nil];
}

RCT_EXPORT_METHOD(reportEcommerceBeginCheckout:(NSDictionary *)orderInfo)
{
    AMAECommerceOrder *order = [AppMetricaUtils toEcommerceOrder:orderInfo];
    if (order == nil) {
        return;
    }

    [AMAAppMetrica reportECommerce:[AMAECommerce beginCheckoutEventWithOrder:order] onFailure:nil];
}

RCT_EXPORT_METHOD(reportEcommercePurchase:(NSDictionary *)orderInfo)
{
    AMAECommerceOrder *order = [AppMetricaUtils toEcommerceOrder:orderInfo];
    if (order == nil) {
        return;
    }

    [AMAAppMetrica reportECommerce:[AMAECommerce purchaseEventWithOrder:order] onFailure:nil];
}

RCT_EXPORT_METHOD(requestAppMetricaDeviceID:(RCTResponseSenderBlock)listener)
{
    AMAIdentifiersCompletionBlock completionBlock = ^(NSDictionary<AMAStartupKey, id> * _Nullable identifiers, NSError * _Nullable error) {
        if (identifiers.count) {
            listener(@[
                [self wrap:identifiers[kAMADeviceIDKey]],
                [self wrap:identifiers[kAMADeviceIDHashKey]],
                [self wrap:identifiers[kAMAUUIDKey]],
                [self wrap:[AppMetricaUtils stringFromRequestDeviceIDError:error]]
            ]);
        }
    };

    [AMAAppMetrica requestStartupIdentifiersWithCompletionQueue:nil completionBlock:completionBlock];
}

RCT_EXPORT_METHOD(resumeSession)
{
    [AMAAppMetrica resumeSession];
}

RCT_EXPORT_METHOD(sendEventsBuffer)
{
    [AMAAppMetrica sendEventsBuffer];
}

RCT_EXPORT_METHOD(setLocation:(NSDictionary *)locationDict)
{
    [AMAAppMetrica setCustomLocation:[AppMetricaUtils locationForDictionary:locationDict]];
}

RCT_EXPORT_METHOD(setLocationTracking:(BOOL)enabled)
{
    [AMAAppMetrica setLocationTrackingEnabled:enabled];
}

RCT_EXPORT_METHOD(setUserProfileID:(NSString *)userProfileID)
{
    [AMAAppMetrica setUserProfileID:userProfileID];
}

- (NSObject *)wrap:(NSObject *)value
{
    if (value == nil) {
        return [NSNull null];
    }
    return value;
}

@end
