//
//  CallLogs.m
//  rainbow
//
//  Created by Doha Tubaileh on 9/24/19.
//  Copyright © 2019 Facebook. All rights reserved.
//

#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import <React/RCTBridgeModule.h>
#import <React/RCTLog.h>
#import "Rainbow/Rainbow.h"
#import "IEventEmmiter.h"
#import "CallLogs.h"
#import "CallLogHelper.h"
#import "CallLogEventsNames.h"

@interface CallLogs ()
@property(nonatomic,strong) CallLogsService *callLogsService;
@property(nonatomic,strong) VoiceMessagesService *voiceMessagesService;
@property(nonatomic,strong) MyUser *myUser;
@property (strong, nonatomic) IEventEmmiter *eventEmitter;
@property (nonatomic, weak) RCTBridge *bridge;

@end

@implementation CallLogs

RCT_EXPORT_MODULE();

- (instancetype)init {
    self = [super init];
    if (self) {
        _callLogsService = [ServicesManager sharedInstance].callLogsService;
        _voiceMessagesService = [ServicesManager sharedInstance].voiceMessagesService;
        _myUser = [ServicesManager sharedInstance].myUser;
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didLogin:) name:kLoginManagerDidLoginSucceeded object:nil];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didLogout:) name:kLoginManagerDidLogoutSucceeded object:nil];
    }
    return self;
}



- (void)dealloc {
    _callLogsService = nil;
    [self unRegisterCallLogsEvents];
    [self unRegisterVoiceMailCountEvents];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:kLoginManagerDidLoginSucceeded object:nil];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:kLoginManagerDidLogoutSucceeded object:nil];
}

#pragma mark - Auth_Notifications

-(void) didLogin:(NSNotification *) notification {
    NSLog(@"[CallLogs] connection was Succeeded");
    _callLogsService = [ServicesManager sharedInstance].callLogsService;
    _voiceMessagesService = [ServicesManager sharedInstance].voiceMessagesService;
    _myUser = [ServicesManager sharedInstance].myUser;
}

-(void) didLogout:(NSNotification *) notification {
    NSLog(@"[CallLogs] ConnectedUser signOut");
    _callLogsService = nil;
    _voiceMessagesService = nil;
    _myUser = nil;
}

#pragma mark - ReactNative_functions

RCT_EXPORT_METHOD(getCallLogs) {
    NSLog(@"[CallLogs]getCallLogs");
    NSArray *callLogs = _callLogsService.getAllCallLogs;
    NSArray *callReact = [[CallLogHelper sharedManager] processCallLogs:callLogs];
    [self sendEventWithName:CallLogsUpdated eventBody:callReact];
}

RCT_EXPORT_METHOD(getMissedCalls) {
    NSLog(@"[CallLogs]getMissedCalls");
    
    NSArray *callLogs = _callLogsService.getAllCallLogs;
    NSArray *callReact = [[CallLogHelper sharedManager] processCallLogs:callLogs];
    NSMutableArray *missedCall = [[NSMutableArray alloc] init];
    for (NSDictionary *reactCall in callReact) {
        NSLog(@"reactCall object %@",reactCall);
        NSDictionary *lastCallReact = reactCall[@"lastCall"];
        if ([lastCallReact[@"state"]  isEqual: @"Missed Incoming"]) {
            //add reactCall to the missed list call
            [missedCall addObject:reactCall];
        }
    }
    
    if (missedCall.count > 0) {
        [self sendEventWithName:MissedCallLogsUpdated eventBody:missedCall];
        
    }
    
}

RCT_EXPORT_METHOD(markAllMissedCallsAsRead) {
    
    NSLog(@"[CallLogs]markAllMissedCallsAsRead");
    [_callLogsService markAllCallLogsAsRead];
    //This will trigger the didUpdateCallUnreadCount, so no need to send the new missed count to React twice
}

RCT_EXPORT_METHOD(getUnreadMissedCallsNotification) {
    NSLog(@"[CallLogs]getUnreadMissedCallsNotification");
    [self registerCallLogsEvents];
    [self onCallLogUnreadCounterChanged];
}

RCT_EXPORT_METHOD(getVoiceMailCounter) {
    NSLog(@"[CallLogs] getVoiceMailCounter");
    [self registerVoiceMailCountEvents];
}


RCT_EXPORT_METHOD(getVoiceMailCapabilities) {
    NSLog(@"[CallLogs] getVoiceMailCapabilities");
    
    _myUser = [[ServicesManager sharedInstance] myUser];
    BOOL isAllowedToUseVoiceMail = [[ServicesManager sharedInstance] myUser].isAllowedToUseTelephonyVoiceMail;
    NSLog(@"Allowed to use voice mail %@", isAllowedToUseVoiceMail ? @"YES" : @"NO");
    
    NSMutableDictionary *voiceMailInfoDic = [[NSMutableDictionary alloc] init];
    [voiceMailInfoDic setValue:[NSNumber numberWithBool:_myUser.isAllowedToUseTelephonyVoiceMail] forKey:@"isVoiceMailAllowed"];
    
    id voiceMailNumber;
    if (_myUser.voiceMailNumber != nil || _myUser.voiceMailNumber.length) {
        voiceMailNumber = _myUser.voiceMailNumber;
    }
    else {
        voiceMailNumber = NSNull.null;
    }
    
    [voiceMailInfoDic setValue:voiceMailNumber forKey:@"voiceMailNumber"];
    
    [self sendEventWithName:VoiceMailCapabilityUpdate eventBody:voiceMailInfoDic];
}

#pragma mark - Others

-(NSInteger) getVoiceMailUnreadCount {
    NSInteger voiceMailCount = _myUser.voiceMailCount;
    if (voiceMailCount > 0) {
        return voiceMailCount;
    }
    
    for (int i =0; i<_voiceMessagesService.voiceMessages.count; i++) {
        VoiceMessage *msg = _voiceMessagesService.voiceMessages[i];
        if (!msg.isRead) {
            voiceMailCount++;
        }
    }
    return voiceMailCount;
}


- (void) onCallLogUnreadCounterChanged {
    NSLog(@"[CallLogs] onCallLogUnreadCounterChanged");
    
    [self sendEventWithName:MissedCallsCounterUpdated eventBody:[NSNumber numberWithInteger:_callLogsService.numberOfUnreadCallLogs]];
    
    NSInteger voiceMailCount = [self getVoiceMailUnreadCount];
    [self sendEventWithName:VoiceMailUnreadCounterUpdated eventBody:[NSNumber numberWithInteger:voiceMailCount]];
    
}

#pragma mark - CallLogNotification

-(void) didUpdateCallUnreadCount:(NSNotification *) notification {
    NSLog(@"[CallLogs]didUpdateCallUnreadCount");
    
    [self getCallLogs];
    
    if (_callLogsService.numberOfUnreadCallLogs > 0) {
        [self getMissedCalls];
    }
    [self onCallLogUnreadCounterChanged];
}

#pragma mark - VoiceMailNotifications

-(void) myUserVoicemailCountDidUpdate:(NSNotification *)notification {
    NSLog(@"[CallLogs]myUserVoicemailCountDidUpdate");
    [self onCallLogUnreadCounterChanged];
}

#pragma mark - Register-UnRegister Notifications

-(void) registerCallLogsEvents {
    NSLog(@"[CallLogs]registerCallLogsEvents");
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didUpdateCallUnreadCount:) name:kCallLogsServiceDidUpdateCallLogsUnreadCount object:nil];
}

-(void) unRegisterCallLogsEvents {
    NSLog(@"[CallLogs]unRegisterCallLogsEvents");
    [[NSNotificationCenter defaultCenter] removeObserver:self name:kCallLogsServiceDidUpdateCallLogsUnreadCount object:nil];
}

-(void) registerVoiceMailCountEvents {
    NSLog(@"[CallLogs]registerVoiceMailCountEvents");
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(myUserVoicemailCountDidUpdate:) name:kMyUserVoicemailCountDidUpdate object:nil];
}

-(void) unRegisterVoiceMailCountEvents {
    NSLog(@"[CallLogs]unRegisterVoiceMailCountEvents");
    [[NSNotificationCenter defaultCenter] removeObserver:self name:kMyUserVoicemailCountDidUpdate object:nil];
}
- ( IEventEmmiter *)eventEmitter {
    if (!_eventEmitter) {
        _eventEmitter = [self.bridge moduleForClass:[IEventEmmiter class]];
    }
    return _eventEmitter;
}

- (void)sendEventWithName:(NSString *)eventName eventBody:(id)eventBody {
    IEventEmmiter *eventEmitter = [self eventEmitter];
    if (eventEmitter) {
        NSLog(@" [CallLogs] sendEventWithName: %@", eventName);
        [eventEmitter sendEvent:eventName eventBody:eventBody];
    } else {
        NSLog(@"[CallLogss] sendEventWithName:  Bridge is not ready. Cannot send event: %@", eventName);
    }
}
+ (BOOL)requiresMainQueueSetup
{
    return NO;
}

@end
