
#import "RNNativeCarthageColocatorLibrary.h"

@implementation RNNativeCarthageColocatorLibrary

static CCLocation *ccLocation;
+ (CCLocation *) ccLocationInstance { return ccLocation; }

- (instancetype)init {
    self = [super init];
    
    if (ccLocation == NULL) {
        ccLocation = CCLocation.sharedInstance;
        ccLocation.delegate = self;
    }
    return self;
}

+ (BOOL)requiresMainQueueSetup
{
  return YES;
}

- (dispatch_queue_t)methodQueue
{
    return dispatch_get_main_queue();
}

RCT_EXPORT_MODULE()

RCT_EXPORT_METHOD(start:(NSString *)apiKey)
{
    [ccLocation startWithApiKey:apiKey urlString:NULL];
    NSLog(@"Start method called with key %@ and default url", apiKey);
}

RCT_EXPORT_METHOD(startWithKeyAndUrl:(NSString *)apiKey :(NSString *)urlString)
{
    [ccLocation startWithApiKey:apiKey urlString:urlString];
    NSLog(@"Start method called with key %@ and url %@", apiKey, urlString);
}

RCT_EXPORT_METHOD(stop)
{
    [ccLocation stop];
    NSLog(@"Stop method called");
}

RCT_EXPORT_METHOD(askForMotionPermission)
{
    // missing method
    NSLog(@"Missing method askForMotionPermission");
}

RCT_EXPORT_METHOD(triggerBluetoothPermissionPopUp)
{
    [ccLocation triggerBluetoothPermissionPopUp];
    NSLog(@"Trigger Bluetooth Popup method called");
}

RCT_EXPORT_METHOD(getDeviceID)
{
    NSString *ID = [ccLocation getDeviceId];
    NSLog(@"Received device ID %@", ID);
}

RCT_EXPORT_METHOD(addAlias:(NSString *)key :(NSString *)value)
{
    [ccLocation addAliasWithKey:key value:value];
    NSLog(@"Add alias method called");
}

RCT_EXPORT_METHOD(requestLocation)
{
    [ccLocation requestLocation];
    NSLog(@"RequestLocation method called");
}

RCT_EXPORT_METHOD(registerLocationListener)
{
    [ccLocation registerLocationListener];
    NSLog(@"RegisterLocationListener method called");
}

RCT_EXPORT_METHOD(unregisterLocationListener)
{
    [ccLocation unregisterLocationListener];
    NSLog(@"UnregisterLocationListener method called");
}

// Sending Events to JAvaScript through an Emitter
// https://facebook.github.io/react-native/docs/native-modules-ios#sending-events-to-javascript

- (void)ccLocationDidConnect {
    [self sendEventWithName:@"ConnectionSucceeded" body:@{@"status": @"connected"}];
    NSLog(@"CC Delegate: ccLocationDidConnect");
}

- (void)ccLocationDidFailWithErrorWithError:(NSError * _Nonnull)error {
    [self sendEventWithName:@"ConnectionFailed" body:@{@"status": @"disconnected"}];
    NSLog(@"CC Delegate: ccLocationDidFailWithErrorWithError %@", error);
}

- (void)didFailToUpdateCCLocation {
    [self sendEventWithName:@"UpdateLocationStatusFailed" body:@{@"status": @"fail"}];
    NSLog(@"CC Delegate: didFailToUpdateCCLocation");
}

- (void)didReceiveCCLocation:(LocationResponse * _Nonnull)location {
    //  Issues when trying to access LocationResponse object's fields
    //  Mark them as public and objc in the ios CCLocation module
    
        NSDictionary *locationResponseDicstionary = [NSDictionary dictionaryWithObjectsAndKeys:
                                                     @"description", location.description,
                                                     @"latitude", @"x",
                                                     @"longitude", @"y",
                                                     @"headingOffset", @"z",
                                                     @"error", @"t",
                                                     @"timestamp", @"w",
                                                     nil];
        [self sendEventWithName:@"LocationResponse" body:locationResponseDicstionary];
        NSLog(@"CC Delegate: didReceiveCCLocation %@", location);
    }

- (NSArray<NSString *> *)supportedEvents
{
    return @[@"ConnectionSucceeded", @"ConnectionFailed", @"UpdateLocationStatusFailed", @"LocationResponse"];
}

//// In JS the emitter should be use like follows
//const ccLocationEmitter = new NativeEventEmitter(RNNativeColocatorLibrary);
//
//const subscription = ccLocationEmitter.addListener(
//  'LocationResponse',
//  (reminder) => console.log(reminder.status)
//);
//
//// subscription for each supported event: [@"ConnectionSucceeded", @"ConnectionFailed", @"UpdateLocationStatusFailed", @"LocationResponse"]
//
//// Don't forget to unsubscribe, typically in componentWillUnmount
//subscription.remove();

@end
