//
//  Datastreams.m
//  Datastreams
//
//  Created by Nicky Romeijn on 16-06-16.
//  Copyright © 2016 Adversitement. All rights reserved.
//

#import "Tagger.h"
#import "Dispatcher.h"

@implementation Tagger

static objectCount = 0;

-(Tagger *) init :(NSString *)appId :(NSString *)endpoint :(NSNumber *)dispatchInterval :(Boolean) forceStartTimer; {
    self = [super init];
    
    self.funnel = [[NSMutableArray alloc] init];
    self.funnel_lock = [[NSLock alloc] init];
    _dispatcher = [[Dispatcher alloc] init :appId];
    _alias = [[NSUUID UUID] UUIDString];
    _identity = @"";
    _location = @"";
    
    [self setAppId:appId];
    [self setEndpoint:endpoint];
    [self setDispatchInterval:dispatchInterval];
    NSDictionary *buildInitFunnel = @{
                                      @"alias" : _alias,
                                      @"identity": _identity
                                      };
    [self addToFunnel:@"alias" : buildInitFunnel];
    //    if(objectCount == 1 || forceStartTimer == true){
    NSTimer *timer = [NSTimer timerWithTimeInterval:[dispatchInterval floatValue]
                                             target:self
                                           selector:@selector(dispatch:)
                                           userInfo:nil
                                            repeats:YES];
    [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
    NSLog(@"Init tagger with timer");
    //    } else {
    //        NSLog(@"Init tagger");
    //    }
    objectCount++;
    return self;
}

-(void) dispatch:(NSTimer *)timer;{
    NSLog(@"Dispatcher has been called");
    //[self.funnel_lock lock];
    if([[self funnel] count] > 0){
        NSLog(@"Dispatcher has dispatched");
        [_dispatcher setAliasAndIdentity :_alias :_identity];
        [_dispatcher dispatch :_endpoint :[self funnel]];
    }
    //    [self.funnel_lock unlock];
}

-(void) clearFunnel; {
    [self.funnel_lock lock];
    [[self funnel] removeAllObjects];
    [self.funnel_lock unlock];
}

-(void) addToFunnel :(NSString*)funnelKey :(NSDictionary*)funnelData; {
    [self.funnel_lock lock];
    
    //if([[self funnel] objectForKey:funnelKey] == nil){
    // [[self funnel] setObject :[[NSMutableArray alloc] init] forKey :funnelKey];
    //}
    
    //[[[self funnel] objectForKey:funnelKey] addObject:funnelData];
    NSMutableDictionary *formattedDict = [[NSMutableDictionary alloc] init];
    [formattedDict  setObject:funnelKey forKey :@"eventType"];
    [formattedDict  setObject:funnelData forKey :@"eventValue"];
    [formattedDict setObject:[self getTimestamp] forKey:@"trackingDateTime"];
    [[self funnel] addObject:formattedDict];
    
    
    int numberOfItems = 0;
    /*for(id key in [self funnel]){
     numberOfItems += [[[self funnel] objectForKey:key] count];
     }
     if(numberOfItems > 1){
     NSLog(@"I am bigger than 1 and am starting to dispatch");
     [_dispatcher dispatch :_endpoint :_funnel];
     }
     */
    NSLog(@"Array Count = %u && number of items %u", [[self funnel] count], numberOfItems);
    [self.funnel_lock unlock];
    
}

-(void)track :(NSString*)eventName; {
    NSLog(@"Track %@", eventName);
    NSDictionary *funnel = @{
                             @"event" : eventName,
                             @"alias":_alias,
                             @"identitiy":_identity,
                             @"location":_location,
                             @"time":[self getTimestamp]
                             };
    
    [self addToFunnel:eventName :funnel];
}


-(void)trackWithProperties:(NSString*)eventName:(NSString*)propertiesAsJson;
{
    NSLog(@"Track %@:%@", eventName, propertiesAsJson);
    NSData *data = [propertiesAsJson dataUsingEncoding:NSUTF8StringEncoding];
    id json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
    NSDictionary *funnel = @{
                             @"event" : eventName,
                             @"alias":_alias,
                             @"identitiy":_identity,
                             @"location":_location,
                             @"time":[self getTimestamp],
                             @"properties":json
                             };
    [self addToFunnel:eventName :funnel];
}


-(void)createAlias:(NSString*)alias; {
    NSLog(@"Alias %@", alias);
    _alias = alias;
    NSDictionary *funnel = @{
                             @"event" : @"alias",
                             @"alias":_alias,
                             @"identitiy":_identity,
                             @"location":_location,
                             @"time":[self getTimestamp]
                             };
    [self addToFunnel:@"alias" :funnel];
}

-(void)identify:(NSString *)identity; {
    NSLog(@"Identity %@", identity);
    _identity = identity;
    NSDictionary *funnel = @{
                             @"event" : @"identity",
                             @"alias":_alias,
                             @"identitiy":_identity,
                             @"location":_location,
                             @"time":[self getTimestamp]
                             };
    [self addToFunnel:@"identity" :funnel];
}

-(void)trackLocation :(NSString*)location;{
    NSLog(@"location %@", location);
    NSData *loc = [location dataUsingEncoding:NSUTF8StringEncoding];
    NSError *error;
    if ([NSJSONSerialization JSONObjectWithData:loc  options:kNilOptions  error:&error] == nil)   {
        //not valid json
        _location = location;
    } else {
        _location = [NSJSONSerialization JSONObjectWithData:loc options:0 error:nil];
    }
    
    NSDictionary *funnel = @{
                             @"event" : @"location",
                             @"alias":_alias,
                             @"identitiy":_identity,
                             @"location":_location,
                             @"time":[self getTimestamp]
                             };
    [self addToFunnel:@"identity" :funnel];
}



-(NSString*) getTimestamp; {
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    NSLocale *enUSPOSIXLocale = [NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"];
    [dateFormatter setLocale:enUSPOSIXLocale];
    [dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssZ"];
    
    NSDate *now = [NSDate date];
    NSString *iso8601String = [dateFormatter stringFromDate:now];
    return [iso8601String stringByReplacingOccurrencesOfString:@"+" withString:@"%2B"];
    //NSTimeInterval timeStamp = [[NSDate date] timeIntervalSince1970];
    // NSTimeInterval is defined as double
    //NSNumber *timeStampObj = [NSNumber numberWithDouble: timeStamp];
    //long milliseconds = (long)(NSTimeInterval)([[NSDate date] timeIntervalSince1970]);
    //NSNumber *dateTime = [NSNumber numberWithLong:milliseconds];
    //return  dateTime;
}

-(void)timeEventStartWithProperties:(NSString*)eventName:(NSString*)propertiesAsJson;{
    NSLog(@"timeEventStartWithProperties %@:%@", eventName, propertiesAsJson);
    
    NSData *data = [propertiesAsJson dataUsingEncoding:NSUTF8StringEncoding];
    id json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
    
    _startTime = [self getTimestamp];
    _timedEvent = eventName;
    _timedEventProperties = json;
}

-(void)timeEventStart:(NSString*)eventName;{
    NSLog(@"timeEventStart %@", eventName);
    _startTime = [self getTimestamp];
    _timedEvent = eventName;
}


-(void)timeEventStop:(NSString*)eventName;{
    NSLog(@"timeEventStop %@", eventName);
    if([_timedEvent isEqualToString:eventName]){
        if(_timedEventProperties){
            NSDictionary *funnel = @{
                                     @"event" : eventName,
                                     @"alias":_alias,
                                     @"identitiy":_identity,
                                     @"timeStart":_startTime,
                                     @"location":_location,
                                     @"timeStop":[self getTimestamp],
                                     @"properties":_timedEventProperties
                                     };
            [self addToFunnel:eventName :funnel];
        } else {
            NSDictionary *funnel = @{
                                     @"event" : eventName,
                                     @"alias":_alias,
                                     @"identitiy":_identity,
                                     @"location":_location,
                                     @"timeStart":_startTime,
                                     @"timeStop":[self getTimestamp]
                                     };
            [self addToFunnel:eventName :funnel];
        }
    }
}

@end



