@import UIKit;
#import "RNRegulaDocumentReader.h"

@implementation RNRegulaDocumentReader

@synthesize bridge = _bridge;

RCT_EXPORT_MODULE();

- (NSArray<NSString *> *)supportedEvents
{
    return @[@"prepareDatabaseProgressChangeEvent"];
}

static NSNumber * _databasePercentageDownloaded;

+ (NSNumber*)databasePercentageDownloaded{ return _databasePercentageDownloaded; }
+ (void)setDatabasePercentageDownloaded:(NSNumber *)number { _databasePercentageDownloaded = number; }


RCT_EXPORT_METHOD(exec:(NSString*)moduleName:(NSString*)action:(NSArray*)args:(RCTResponseSenderBlock)successCallback:(RCTResponseSenderBlock)errorCallback){
    if([action isEqualToString:@"startRFIDReader"])
        [self startRFIDReader :successCallback :errorCallback];
    else if ([action isEqualToString:@"removeDatabase"])
        [self removeDatabase :successCallback :errorCallback];
    else if ([action isEqualToString:@"cancelDBUpdate"])
        [self cancelDBUpdate :successCallback :errorCallback];
    else if ([action isEqualToString:@"showScanner"])
        [self showScanner :successCallback :errorCallback];
    else if ([action isEqualToString:@"getConfig"])
        [self getConfig :successCallback :errorCallback];
    else if ([action isEqualToString:@"getRfidScenario"])
        [self getRfidScenario :successCallback :errorCallback];
    else if ([action isEqualToString:@"readRFID"])
        [self readRFID :successCallback :errorCallback];
    else if ([action isEqualToString:@"stopRFIDReader"])
        [self stopRFIDReader :successCallback :errorCallback];
    else if ([action isEqualToString:@"clearPKDCertificates"])
        [self clearPKDCertificates :successCallback :errorCallback];
    else if ([action isEqualToString:@"deinitializeReader"])
        [self deinitializeReader :successCallback :errorCallback];
    else if ([action isEqualToString:@"selectedScenario"])
        [self selectedScenario :successCallback :errorCallback];
    else if ([action isEqualToString:@"stopScanner"])
        [self stopScanner :successCallback :errorCallback];
    else if ([action isEqualToString:@"startNewSession"])
        [self startNewSession :successCallback :errorCallback];
    else if ([action isEqualToString:@"startNewPage"])
        [self startNewPage :successCallback :errorCallback];
    else if ([action isEqualToString:@"getDocumentReaderIsReady"])
        [self getDocumentReaderIsReady :successCallback :errorCallback];
    else if ([action isEqualToString:@"getAPIVersion"])
        [self getAPIVersion :successCallback :errorCallback];
    else if ([action isEqualToString:@"getCoreVersion"])
        [self getCoreVersion :successCallback :errorCallback];
    else if ([action isEqualToString:@"getCoreMode"])
        [self getCoreMode :successCallback :errorCallback];
    else if ([action isEqualToString:@"getDatabaseID"])
        [self getDatabaseID :successCallback :errorCallback];
    else if ([action isEqualToString:@"getDatabaseVersion"])
        [self getDatabaseVersion :successCallback :errorCallback];
    else if ([action isEqualToString:@"getDatabaseDate"])
        [self getDatabaseDate :successCallback :errorCallback];
    else if ([action isEqualToString:@"getDatabaseDescription"])
        [self getDatabaseDescription :successCallback :errorCallback];
    else if ([action isEqualToString:@"getDatabaseCountriesNumber"])
        [self getDatabaseCountriesNumber :successCallback :errorCallback];
    else if ([action isEqualToString:@"getDatabaseDocumentsNumber"])
        [self getDatabaseDocumentsNumber :successCallback :errorCallback];
    else if ([action isEqualToString:@"getLicenseExpiryDate"])
        [self getLicenseExpiryDate :successCallback :errorCallback];
    else if ([action isEqualToString:@"getLicenseCountryFilter"])
        [self getLicenseCountryFilter :successCallback :errorCallback];
    else if ([action isEqualToString:@"licenseIsRfidAvailable"])
        [self licenseIsRfidAvailable :successCallback :errorCallback];
    else if ([action isEqualToString:@"getLicenseMessage"])
        [self getLicenseMessage :successCallback :errorCallback];
    else if ([action isEqualToString:@"getDocumentReaderStatus"])
        [self getDocumentReaderStatus :successCallback :errorCallback];
    else if ([action isEqualToString:@"getRfidSessionStatus"])
        [self getRfidSessionStatus :successCallback :errorCallback];
    else if ([action isEqualToString:@"getCurrentScenario"])
        [self getCurrentScenario :successCallback :errorCallback];
    else if ([action isEqualToString:@"getCameraSessionIsPaused"])
        [self getCameraSessionIsPaused :successCallback :errorCallback];
    else if ([action isEqualToString:@"isRFIDAvailableForUse"])
        [self isRFIDAvailableForUse :successCallback :errorCallback];
    else if ([action isEqualToString:@"getSessionLogFolder"])
        [self getSessionLogFolder :successCallback :errorCallback];
    else if ([action isEqualToString:@"getAvailableScenarios"])
        [self getAvailableScenarios :successCallback :errorCallback];
    else if ([action isEqualToString:@"initializeReader"])
        [self initializeReader:[args objectAtIndex:0] :successCallback :errorCallback];
    else if ([action isEqualToString:@"setRfidScenario"])
        [self setRfidScenario:[args objectAtIndex:0] :successCallback :errorCallback];
    else if ([action isEqualToString:@"prepareDatabase"])
        [self prepareDatabase:[args objectAtIndex:0] :successCallback :errorCallback];
    else if ([action isEqualToString:@"runAutoUpdate"])
        [self runAutoUpdate:[args objectAtIndex:0] :successCallback :errorCallback];
    else if ([action isEqualToString:@"recognizeImage"])
        [self recognizeImage:[args objectAtIndex:0] :successCallback :errorCallback];
    else if ([action isEqualToString:@"recognizeImages"])
        [self recognizeImages:[args objectAtIndex:0] :successCallback :errorCallback];
    else if ([action isEqualToString:@"setConfig"])
        [self setConfig:[args objectAtIndex:0] :successCallback :errorCallback];
    else if ([action isEqualToString:@"addPKDCertificates"])
        [self addPKDCertificates:[args objectAtIndex:0] :successCallback :errorCallback];
    else if ([action isEqualToString:@"setCameraSessionIsPaused"])
        [self setCameraSessionIsPaused:[args objectAtIndex:0] :successCallback :errorCallback];
    else if ([action isEqualToString:@"initializeReaderWithDatabasePath"])
        [self initializeReaderWithDatabasePath:[args objectAtIndex:0] :[args objectAtIndex:1] :successCallback :errorCallback];
    else if ([action isEqualToString:@"recognizeImageWithCameraMode"])
        [self recognizeImageWithCameraMode:[args objectAtIndex:0] :[args objectAtIndex:1] :successCallback :errorCallback];
    else
        [self result:[NSString stringWithFormat:@"%@/%@", @"method not implemented: ", action] :errorCallback];
}

- (void) startRFIDReader:(RCTResponseSenderBlock)successCallback :(RCTResponseSenderBlock)errorCallback{
    if([RGLDocReader.shared isDocumentReaderIsReady])
        dispatch_async(dispatch_get_main_queue(), ^{
            [RGLDocReader.shared startRFIDReaderFromPresenter:[[[UIApplication sharedApplication] keyWindow] rootViewController] completion:[self getCompletion :successCallback :errorCallback]];
        });
    else
        [self result:@"document reader not ready" :successCallback];
}

- (void) initializeReader:(NSString*)licenseString :(RCTResponseSenderBlock)successCallback :(RCTResponseSenderBlock)errorCallback{
    [RGLDocReader.shared initializeReader:[[NSData alloc] initWithBase64EncodedString:licenseString options:0] completion:[self getInitCompletion :successCallback :errorCallback]];
}

- (void) initializeReaderWithDatabasePath:(NSString*)licenseString :(NSString*)databasePath :(RCTResponseSenderBlock)successCallback :(RCTResponseSenderBlock)errorCallback{
    [RGLDocReader.shared initializeReader:[[NSData alloc] initWithBase64EncodedString:licenseString options:0] databasePath:databasePath completion:[self getInitCompletion :successCallback :errorCallback]];
}

- (void) prepareDatabase:(NSString*)dbID :(RCTResponseSenderBlock)successCallback :(RCTResponseSenderBlock)errorCallback{
    [RGLDocReader.shared prepareDatabase:dbID progressHandler:[self getProgressHandler :successCallback :errorCallback] completion:[self getPrepareCompletion :successCallback :errorCallback]];
}

- (void) removeDatabase:(RCTResponseSenderBlock)successCallback :(RCTResponseSenderBlock)errorCallback{
    [RGLDocReader.shared removeDatabase:^(BOOL successful, NSString * _Nullable error) {
        if (successful)
            [self result:@"database removed" :successCallback];
        else
            [self result:[NSString stringWithFormat:@"%@/%@", @"database removal failed: ", error] :errorCallback];
    }];
}

- (void) cancelDBUpdate:(RCTResponseSenderBlock)successCallback :(RCTResponseSenderBlock)errorCallback{
    [RGLDocReader.shared cancelDBUpdate];
    [self result:@"" :successCallback];
}

-(void) runAutoUpdate:(NSString*)dbID :(RCTResponseSenderBlock)successCallback :(RCTResponseSenderBlock)errorCallback{
    [RGLDocReader.shared runAutoUpdate:dbID progressHandler:[self getProgressHandler :successCallback :errorCallback] completion:[self getPrepareCompletion :successCallback :errorCallback]];
}

- (void) showScanner:(RCTResponseSenderBlock)successCallback :(RCTResponseSenderBlock)errorCallback{
    if([RGLDocReader.shared isDocumentReaderIsReady]){
        dispatch_async(dispatch_get_main_queue(), ^{
            [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent animated:YES];
            UIViewController *currentViewController = [[[UIApplication sharedApplication] keyWindow] rootViewController];
            [RGLDocReader.shared showScanner:currentViewController completion:[self getCompletion :successCallback :errorCallback]];
        });
    }else
        [self result:@"document reader not ready" :successCallback];
}

- (void) recognizeImage:(NSMutableString*)base64 :(RCTResponseSenderBlock)successCallback :(RCTResponseSenderBlock)errorCallback{
    [self recognizeImageWith :base64 :false :successCallback :errorCallback];
}

- (void) recognizeImages:(NSArray*)input :(RCTResponseSenderBlock)successCallback :(RCTResponseSenderBlock)errorCallback{
    if([RGLDocReader.shared isDocumentReaderIsReady]){
        NSMutableArray<UIImage*>* images = [[NSMutableArray alloc] init];
        for(__strong NSMutableString* base64 in input){
            if(![[base64 substringToIndex:10] isEqualToString:@"data:image"])
                base64 = [NSMutableString stringWithFormat: @"%@%@", @"data:image/jpeg;base64,", base64];
            [images addObject:[UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:base64]]]];
        }
        dispatch_async(dispatch_get_main_queue(), ^{
            [RGLDocReader.shared recognizeImages:images completion:[self getCompletion :successCallback :errorCallback]];
        });
    }else
        [self result:@"document reader not ready" :successCallback];
}

- (void) recognizeImageWithCameraMode:(NSMutableString*)base64 :(BOOL)cameraMode :(RCTResponseSenderBlock)successCallback :(RCTResponseSenderBlock)errorCallback{
    [self recognizeImageWith :base64 :cameraMode :successCallback :errorCallback];
}

- (void) recognizeImageWith:(NSMutableString*)base64 :(BOOL)cameraMode :(RCTResponseSenderBlock)successCallback :(RCTResponseSenderBlock)errorCallback{
    if([RGLDocReader.shared isDocumentReaderIsReady]){
        if(![[base64 substringToIndex:10] isEqualToString:@"data:image"])
            base64 = [NSMutableString stringWithFormat: @"%@%@", @"data:image/jpeg;base64,", base64];
        dispatch_async(dispatch_get_main_queue(), ^{
            [RGLDocReader.shared recognizeImage:[UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:base64]]] cameraMode:cameraMode completion:[self getCompletion :successCallback :errorCallback]];
        });
    }else
        [self result:@"document reader not ready" :successCallback];
}

- (void) setConfig:(NSDictionary*)config :(RCTResponseSenderBlock)successCallback :(RCTResponseSenderBlock)errorCallback{
        [RegulaConfig setConfig:config :RGLDocReader.shared];
        [self result:@"" :successCallback];
}

- (void) getConfig:(RCTResponseSenderBlock)successCallback :(RCTResponseSenderBlock)errorCallback{
    [self result:[[NSString alloc] initWithData:[NSJSONSerialization dataWithJSONObject:[RegulaConfig getConfig:RGLDocReader.shared] options:NSJSONWritingPrettyPrinted error:nil] encoding:NSUTF8StringEncoding] :successCallback];
}

- (void) setRfidScenario:(NSDictionary*)rfidScenario :(RCTResponseSenderBlock)successCallback :(RCTResponseSenderBlock)errorCallback{
        [RegulaConfig setRfidScenario:rfidScenario  :RGLDocReader.shared.rfidScenario];
        [self result:@"" :successCallback];
}

- (void) getRfidScenario:(RCTResponseSenderBlock)successCallback :(RCTResponseSenderBlock)errorCallback{
        [self result:[[NSString alloc] initWithData:[NSJSONSerialization dataWithJSONObject:RGLDocReader.shared.rfidScenario.rfidScenarioDictionary options:NSJSONWritingPrettyPrinted error:nil] encoding:NSUTF8StringEncoding] :successCallback];
}

- (void) readRFID:(RCTResponseSenderBlock)successCallback :(RCTResponseSenderBlock)errorCallback{
    if([RGLDocReader.shared isDocumentReaderIsReady])
        [RGLDocReader.shared readRFID:nil completion:[self getRFIDCompletion :successCallback :errorCallback]];
    else
        [self result:@"document reader not ready" :successCallback];
}

- (void) stopRFIDReader:(RCTResponseSenderBlock)successCallback :(RCTResponseSenderBlock)errorCallback{
    [RGLDocReader.shared stopRFIDReader:^(){[self result:@"" :successCallback];}];
}

- (void) clearPKDCertificates:(RCTResponseSenderBlock)successCallback :(RCTResponseSenderBlock)errorCallback{
    [RGLDocReader.shared clearPKDCertificates];
    [self result:@"" :successCallback];
}

- (void) addPKDCertificates:(NSArray*)input :(RCTResponseSenderBlock)successCallback :(RCTResponseSenderBlock)errorCallback{
    NSMutableArray<RGLPKDCertificate*>* certificates = [[RGLPKDCertificate init] alloc];
    for(NSDictionary* certificateJSON in input)
        [certificates addObject:[JsonConstructor RGLPKDCertificateFromJson:certificateJSON]];
    [RGLDocReader.shared addPKDCertificates:certificates];
    [self result:@"" :successCallback];
}

- (void) deinitializeReader:(RCTResponseSenderBlock)successCallback :(RCTResponseSenderBlock)errorCallback{
    [RGLDocReader.shared deinitializeReader];
    [self result:@"" :successCallback];
}

- (void) selectedScenario:(RCTResponseSenderBlock)successCallback :(RCTResponseSenderBlock)errorCallback{
    [self result:[JsonConstructor generateScenario:RGLDocReader.shared.selectedScenario] :successCallback];
}

- (void) stopScanner:(RCTResponseSenderBlock)successCallback :(RCTResponseSenderBlock)errorCallback{
    [RGLDocReader.shared stopScanner:^(){[self result:@"" :successCallback];}];
}

- (void) startNewSession:(RCTResponseSenderBlock)successCallback :(RCTResponseSenderBlock)errorCallback{
    [RGLDocReader.shared startNewSession];
    [self result:@"" :successCallback];
}

- (void) startNewPage:(RCTResponseSenderBlock)successCallback :(RCTResponseSenderBlock)errorCallback{
    [RGLDocReader.shared startNewPage];
    [self result:@"" :successCallback];
}

- (void) getDocumentReaderIsReady:(RCTResponseSenderBlock)successCallback :(RCTResponseSenderBlock)errorCallback{
    [self result:[RGLDocReader.shared isDocumentReaderIsReady] ? @YES : @NO :successCallback];
}

- (void) getAPIVersion:(RCTResponseSenderBlock)successCallback :(RCTResponseSenderBlock)errorCallback{
    [self result:[[RGLDocReader.shared version] api] :successCallback];
}

- (void) getCoreVersion:(RCTResponseSenderBlock)successCallback :(RCTResponseSenderBlock)errorCallback{
    [self result:[[RGLDocReader.shared version] core] :successCallback];
}

- (void) getCoreMode:(RCTResponseSenderBlock)successCallback :(RCTResponseSenderBlock)errorCallback{
    [self result:[[RGLDocReader.shared version] coreMode] :successCallback];
}

- (void) getDatabaseID:(RCTResponseSenderBlock)successCallback :(RCTResponseSenderBlock)errorCallback{
    [self result:[[[RGLDocReader.shared version] database] databaseID] :successCallback];
}

- (void) getDatabaseVersion:(RCTResponseSenderBlock)successCallback :(RCTResponseSenderBlock)errorCallback{
    [self result:[[[RGLDocReader.shared version] database] version] :successCallback];
}

- (void) getDatabaseDate:(RCTResponseSenderBlock)successCallback :(RCTResponseSenderBlock)errorCallback{
    [self result:[[[RGLDocReader.shared version] database] date] :successCallback];
}

- (void) getDatabaseDescription:(RCTResponseSenderBlock)successCallback :(RCTResponseSenderBlock)errorCallback{
    [self result:[[[RGLDocReader.shared version] database] databaseDescription] :successCallback];
}

- (void) getDatabaseCountriesNumber:(RCTResponseSenderBlock)successCallback :(RCTResponseSenderBlock)errorCallback{
    [self result:[NSString stringWithFormat: @"%ld", (long)RGLDocReader.shared.version.database.countriesNumber] :successCallback];
}

- (void) getDatabaseDocumentsNumber:(RCTResponseSenderBlock)successCallback :(RCTResponseSenderBlock)errorCallback{
    [self result:[NSString stringWithFormat: @"%ld", (long)RGLDocReader.shared.version.database.documentsNumber] :successCallback];
}

- (void) getLicenseExpiryDate:(RCTResponseSenderBlock)successCallback :(RCTResponseSenderBlock)errorCallback{
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setFormatterBehavior:NSDateFormatterBehaviorDefault];
    [formatter setDateStyle:NSDateFormatterShortStyle];
    [formatter setTimeStyle:NSDateFormatterNoStyle];
    [self result:[formatter stringFromDate:RGLDocReader.shared.license.expiryDate] :successCallback];
}

- (void) getLicenseCountryFilter:(RCTResponseSenderBlock)successCallback :(RCTResponseSenderBlock)errorCallback{
    if(RGLDocReader.shared.license.countryFilter == nil)
        [self result:@"nil" :successCallback];
    else
        [self result:[[NSString alloc] initWithData:[NSJSONSerialization dataWithJSONObject:RGLDocReader.shared.license.countryFilter options:NSJSONWritingPrettyPrinted error:nil] encoding:NSUTF8StringEncoding] :successCallback];
}

- (void) licenseIsRfidAvailable:(RCTResponseSenderBlock)successCallback :(RCTResponseSenderBlock)errorCallback{
    [self result:RGLDocReader.shared.license.isRfidAvailable ? @YES : @NO :successCallback];
}

- (void) getLicenseMessage:(RCTResponseSenderBlock)successCallback :(RCTResponseSenderBlock)errorCallback{
    [self result:@"nil" :successCallback];
}

- (void) getDocumentReaderStatus:(RCTResponseSenderBlock)successCallback :(RCTResponseSenderBlock)errorCallback{
    [self result:RGLDocReader.shared.documentReaderStatus :successCallback];
}

- (void) getRfidSessionStatus:(RCTResponseSenderBlock)successCallback :(RCTResponseSenderBlock)errorCallback{
    [self result:RGLDocReader.shared.rfidSessionStatus :successCallback];
}

- (void) getCurrentScenario:(RCTResponseSenderBlock)successCallback :(RCTResponseSenderBlock)errorCallback{
    [self result:RGLDocReader.shared.processParams.scenario :successCallback];
}

- (void) getCameraSessionIsPaused:(RCTResponseSenderBlock)successCallback :(RCTResponseSenderBlock)errorCallback{
    [self result:RGLDocReader.shared.isCameraSessionIsPaused ? @YES : @NO :successCallback];
}

- (void) setCameraSessionIsPaused:(BOOL)paused :(RCTResponseSenderBlock)successCallback :(RCTResponseSenderBlock)errorCallback{
    RGLDocReader.shared.cameraSessionIsPaused = paused;
    [self result:@"" :successCallback];
}

- (void) isRFIDAvailableForUse:(RCTResponseSenderBlock)successCallback :(RCTResponseSenderBlock)errorCallback{
    [self result:RGLDocReader.shared.isRFIDAvailableForUse ? @YES : @NO :successCallback];
}

- (void) getSessionLogFolder:(RCTResponseSenderBlock)successCallback :(RCTResponseSenderBlock)errorCallback{
    [self result:RGLDocReader.shared.processParams.sessionLogFolder :successCallback];
}

- (void) getAvailableScenarios:(RCTResponseSenderBlock)successCallback :(RCTResponseSenderBlock)errorCallback{
    NSMutableArray *availableScenarios = [[NSMutableArray alloc] init];
    for(RGLScenario *scenario in [RGLDocReader.shared availableScenarios])
        [availableScenarios addObject:[JsonConstructor generateScenario:scenario]];
    [self result:[[NSString alloc] initWithData:[NSJSONSerialization dataWithJSONObject:availableScenarios options:NSJSONWritingPrettyPrinted error:nil] encoding:NSUTF8StringEncoding] :successCallback];
}

-(RGLDocumentReaderInitializationCompletion)getInitCompletion:(RCTResponseSenderBlock)successCallback :(RCTResponseSenderBlock)errorCallback{
    return ^(BOOL successful, NSString * _Nullable error ) {
        if (successful)
            [self result:@"init complete" :successCallback];
        else
            [self result:[NSString stringWithFormat:@"%@/%@", @"init failed: ", error] :errorCallback];
    };
}

-(void (^_Nullable)(NSProgress * _Nonnull progress))getProgressHandler:(RCTResponseSenderBlock)successCallback :(RCTResponseSenderBlock)errorCallback{
    return ^(NSProgress * _Nonnull progress) {
        if(RNRegulaDocumentReader.databasePercentageDownloaded != [NSNumber numberWithDouble:progress.fractionCompleted * 100]){
            [self sendEventWithName:@"prepareDatabaseProgressChangeEvent" body:@{@"msg": [NSString stringWithFormat:@"%@%.1f%@", @"Downloading database: ", progress.fractionCompleted * 100, @"%"]}];
            [RNRegulaDocumentReader setDatabasePercentageDownloaded:[NSNumber numberWithDouble:progress.fractionCompleted * 100]];
        }
    };
}

-(RGLDocumentReaderPrepareCompletion _Nonnull)getPrepareCompletion:(RCTResponseSenderBlock)successCallback :(RCTResponseSenderBlock)errorCallback{
    return ^(BOOL successful, NSString * _Nullable error) {
        if (successful)
            [self result:@"database prepared" :successCallback];
        else
            [self result:[NSString stringWithFormat:@"%@/%@", @"database preparation failed: ", error] :errorCallback];
    };
}

-(RGLDocumentReaderCompletion _Nonnull)getCompletion:(RCTResponseSenderBlock)successCallback :(RCTResponseSenderBlock)errorCallback{
    return ^(RGLDocReaderAction action, RGLDocumentReaderResults * _Nullable results, NSString * _Nullable error) {
        switch (action) {
            case RGLDocReaderActionCancel: {
                [self result:@"Cancelled by user" :errorCallback];
                break;
            }
                
            case RGLDocReaderActionComplete: {
                [self result:[JsonConstructor resultsToJsonString:results] :successCallback];
                break;
            }
                
            case RGLDocReaderActionError: {
                [self result:[NSString stringWithFormat:@"%@/%@", @"error: ", error] :errorCallback];
                break;
            }
                
            case RGLDocReaderActionProcess:
            case RGLDocReaderActionMorePagesAvailable: {
                break;
            }
        }
    };
}

-(RGLRFIDProcessCompletion _Nonnull)getRFIDCompletion:(RCTResponseSenderBlock)successCallback :(RCTResponseSenderBlock)errorCallback{
    return ^(RGLRFIDCompleteAction action, RGLDocumentReaderResults * _Nullable results, NSString * _Nullable error, RGLRFIDErrorCodes errorCode) {
        switch (action) {
            case RGLRFIDCompleteActionCancel: {
                [self result:@"Cancelled by user" :errorCallback];
                break;
            }
                
            case RGLRFIDCompleteActionComplete: {
                [self result:[JsonConstructor resultsToJsonString:results] :successCallback];
                break;
            }
                
            case RGLRFIDCompleteActionError: {
                [self result:[NSString stringWithFormat:@"%@/%@", @"error: ", error] :errorCallback];
                break;
            }
            case RGLRFIDCompleteActionSessionRestarted: {
                break;
            }
        }
    };
}

- (void) result:(NSString*)message :(RCTResponseSenderBlock)callback{
    callback(@[message]);
}

@end
