
#import "JibeStreamOdpModule.h"

#import "EventEmitter.h"
#import <extend.h>


@interface JibeStreamOdpModule() <OnExtendDelegate>


// Arrow icon object
//@property (nonatomic, strong) JMapMovingObject * arrow;
//@property (nonatomic) JMapUI *mapUIKit;

@property (strong, nonatomic) Extend * extend;
@property (strong, nonatomic) CTPEventEmitter *eventEmitter;

@end

@implementation JibeStreamOdpModule

RCT_EXPORT_MODULE(JibeStreamOdp);


//CTPEventEmitter *odpEventEmitter;
long long lastNavUpdateTime = 0;

static id ObjectOrNull(id object){
    return object ?: [NSNull null];
}

RCT_EXPORT_METHOD(startOdp:(nonnull NSNumber *) reactTag
                  key:(NSString *) key
                  host:(NSString *) host)
{
    self.eventEmitter = [CTPEventEmitter allocWithZone: nil];
    self.extend = [Extend sharedExtendWithKey:key url:host delegate:self];
    [self.extend setVicinityEnabled:true];
};

RCT_EXPORT_METHOD(stopOdp:(nonnull NSNumber *) reactTag)
{
    [self.extend stop];
};

RCT_EXPORT_METHOD(uploadLogs:(nonnull NSNumber *) reactTag)
{
    [self.extend uploadLogs];
};

- (void) onReady:(bool)ready
{
    NSDictionary *eventData = @{
        @"ready": @(ready),
    };
    
    [self.eventEmitter sendEvent:@"ODP_READY" body:eventData];
}

- (void) onKeyValidation:(bool)validated
{
    
    if (![self.extend isServiceStarted] && validated)
    {
        [self.extend setVicinityEnabled:true];
        [self.extend start];
        
    }else{
        NSLog(@"Failed to Validate Key");
    }
    
    NSDictionary *eventData = @{
        @"validated": @(validated),
    };
    
//    [eventEmitter sendEvent:@"ODP_KEY_VALIDATION" body:eventData];
}

- (void) onNavigationUpdate:(TDNavOutput *)navOutput{
    long long currentTime = [self getSystemTimeMillis];
    if(currentTime - lastNavUpdateTime >200){
        NSDictionary *eventData = @{
            @"lat": ObjectOrNull(@(navOutput.latitude)),
            @"long": ObjectOrNull(@(navOutput.longitude)),
            @"bearing": ObjectOrNull(@(navOutput.bearing)),
            @"viewHeading": ObjectOrNull(@(navOutput.viewHeading)),
            @"floor": ObjectOrNull(@(navOutput.floor)),
            @"accuracyRadius": ObjectOrNull(@(navOutput.accuracyRadius)),
            @"utc": ObjectOrNull(@(navOutput.utc)),
            @"x": ObjectOrNull(@(navOutput.x)),
            @"y": ObjectOrNull(@(navOutput.y)),
            @"xFom": ObjectOrNull(@(navOutput.xFom)),
            @"yFom": ObjectOrNull(@(navOutput.yFom)),
            @"usedSystems": ObjectOrNull(@(navOutput.usedSystems)),
            @"dynamicState": ObjectOrNull(@(navOutput.dynamicState)),
            @"elevationState": ObjectOrNull(@(navOutput.elevationState)),
            @"pdrSpeedLimitExceeded": ObjectOrNull(@(navOutput.pdrSpeedLimitExceeded))
        };
        
//        CGPoint convertPoint = CGPointMake(navOutput.longitude, navOutput.latitude);
//        convertPoint = [JMapUtils convertPoint:convertPoint fromProjection:@"EPSG:4326" toProjection:@"jmap:local" inVenue:self.controller.activeVenue];

        [self.eventEmitter sendEvent:@"ODP_NAVIGATION_UPDATE" body:eventData];
        lastNavUpdateTime = currentTime;
    }
}

- (void) onFacilityUpdateName:(NSString *)name onFacilityUpdateLocation:(Location *)location onFacilityUpdateRegion:(Region *)region onFacilityUpdateFloorPlans:(NSArray *)plans onFacilityUpdateCategories:(NSArray *)categories {
    
    NSDictionary *locationDict = @{
        @"latitude": ObjectOrNull(@(location.latLong.latitude)),
        @"longitude": ObjectOrNull(@(location.latLong.longitude)),
        @"x": ObjectOrNull(@(location.x)),
        @"y": ObjectOrNull(@(location.y)),
        @"z": ObjectOrNull(@(location.z)),
        @"altitude": ObjectOrNull(@(location.altitude)),
        @"isGeo": ObjectOrNull(@(location.isGeo)),
        
    };
    
    
    NSDictionary *regionDict = @{
        @"floor": ObjectOrNull(@(region.floor)),
        @"id": ObjectOrNull(@(region.uid)),
        @"name": ObjectOrNull(region.name),
        @"icon": ObjectOrNull(region.icon),
        @"type": ObjectOrNull(region.type),
        @"points": ObjectOrNull(region.locations),
        @"distanceToUser": ObjectOrNull(@(region.distanceToUser)),
        @"userOnSameFloor": ObjectOrNull(@(region.userOnSameFloor)),
        @"className": ObjectOrNull(region.type),
    };
    
    NSDictionary *eventData = @{
        @"name": name,
        @"location": locationDict,
        @"region": regionDict,
        @"floorPlans": ObjectOrNull(plans),
    };
    
    [self.eventEmitter sendEvent:@"ODP_FACILITY_UPDATE" body:eventData];
    
}

- (void) dataLoadEvent: (NSString *)data
{
}

-(long long) getSystemTimeMillis {
    NSDate *now = [NSDate date];
    NSTimeInterval timeInterval = [now timeIntervalSinceReferenceDate];
    NSTimeInterval milliseconds = timeInterval * 1000.0;
    long long currentTimeMillis = (long long)milliseconds;
    return currentTimeMillis;
}

@end
