//
//  ExtSdkContactManagerWrapper.m
//
//
//  Created by 杜洁鹏 on 2019/10/8.
//

#import "ExtSdkContactManagerWrapper.h"
#import "ExtSdkMethodTypeObjc.h"
#import "ExtSdkToJson.h"

@interface ExtSdkContactManagerWrapper () <AgoraChatContactManagerDelegate>

@end

@implementation ExtSdkContactManagerWrapper

+ (nonnull instancetype)getInstance {
    static ExtSdkContactManagerWrapper *instance = nil;
    static dispatch_once_t predicate;
    dispatch_once(&predicate, ^{
      instance = [[ExtSdkContactManagerWrapper alloc] init];
    });
    return instance;
}

- (void)initSdk {
    [AgoraChatClient.sharedClient.contactManager removeDelegate:self];
    [AgoraChatClient.sharedClient.contactManager addDelegate:self delegateQueue:nil];
}

#pragma mark - Actions
- (void)addContact:(NSDictionary *)param
    withMethodType:(NSString *)aChannelName
            result:(nonnull id<ExtSdkCallbackObjc>)result {
    __weak typeof(self) weakSelf = self;
    NSString *username = param[@"username"];
    NSString *reason = param[@"reason"];
    [AgoraChatClient.sharedClient.contactManager
        addContact:username
           message:reason
        completion:^(NSString *aUsername, AgoraChatError *aError) {
          [weakSelf onResult:result
              withMethodType:ExtSdkMethodKeyAddContact
                   withError:aError
                  withParams:aUsername];
        }];
}

- (void)deleteContact:(NSDictionary *)param
       withMethodType:(NSString *)aChannelName
               result:(nonnull id<ExtSdkCallbackObjc>)result {
    __weak typeof(self) weakSelf = self;
    NSString *username = param[@"username"];
    BOOL keepConversation = [param[@"keepConversation"] boolValue];
    [AgoraChatClient.sharedClient.contactManager
               deleteContact:username
        isDeleteConversation:keepConversation
                  completion:^(NSString *aUsername, AgoraChatError *aError) {
                    [weakSelf onResult:result
                        withMethodType:ExtSdkMethodKeyDeleteContact
                             withError:aError
                            withParams:aUsername];
                  }];
}

- (void)getAllContactsFromServer:(NSDictionary *)param
                  withMethodType:(NSString *)aChannelName
                          result:(nonnull id<ExtSdkCallbackObjc>)result {
    __weak typeof(self) weakSelf = self;
    [AgoraChatClient.sharedClient.contactManager
        getContactsFromServerWithCompletion:^(NSArray *aList, AgoraChatError *aError) {
          [weakSelf onResult:result
              withMethodType:ExtSdkMethodKeyGetAllContactsFromServer
                   withError:aError
                  withParams:aList];
        }];
}

- (void)getAllContactsFromDB:(NSDictionary *)param
              withMethodType:(NSString *)aChannelName
                      result:(nonnull id<ExtSdkCallbackObjc>)result {
    __weak typeof(self) weakSelf = self;
    NSArray *aList = AgoraChatClient.sharedClient.contactManager.getContacts;
    [weakSelf onResult:result
        withMethodType:ExtSdkMethodKeyGetAllContactsFromDB
             withError:nil
            withParams:aList];
}

- (void)addUserToBlockList:(NSDictionary *)param
            withMethodType:(NSString *)aChannelName
                    result:(nonnull id<ExtSdkCallbackObjc>)result {
    __weak typeof(self) weakSelf = self;
    NSString *username = param[@"username"];
    [AgoraChatClient.sharedClient.contactManager
        addUserToBlackList:username
                completion:^(NSString *aUsername, AgoraChatError *aError) {
                  [weakSelf onResult:result
                      withMethodType:ExtSdkMethodKeyAddUserToBlockList
                           withError:aError
                          withParams:aUsername];
                }];
}

- (void)removeUserFromBlockList:(NSDictionary *)param
                 withMethodType:(NSString *)aChannelName
                         result:(nonnull id<ExtSdkCallbackObjc>)result {
    __weak typeof(self) weakSelf = self;
    NSString *username = param[@"username"];
    [AgoraChatClient.sharedClient.contactManager
        removeUserFromBlackList:username
                     completion:^(NSString *aUsername, AgoraChatError *aError) {
                       [weakSelf onResult:result
                           withMethodType:ExtSdkMethodKeyRemoveUserFromBlockList
                                withError:aError
                               withParams:aUsername];
                     }];
}

- (void)getBlockListFromServer:(NSDictionary *)param
                withMethodType:(NSString *)aChannelName
                        result:(nonnull id<ExtSdkCallbackObjc>)result {
    __weak typeof(self) weakSelf = self;
    [AgoraChatClient.sharedClient.contactManager
        getBlackListFromServerWithCompletion:^(NSArray *aList,
                                               AgoraChatError *aError) {
          [weakSelf onResult:result
              withMethodType:ExtSdkMethodKeyGetBlockListFromServer
                   withError:aError
                  withParams:aList];
        }];
}

- (void)getBlockListFromDB:(NSDictionary *)param
            withMethodType:(NSString *)aChannelName
                    result:(nonnull id<ExtSdkCallbackObjc>)result {

    NSArray *list = [AgoraChatClient.sharedClient.contactManager getBlackList];
    [self onResult:result
        withMethodType:ExtSdkMethodKeyGetBlockListFromDB
             withError:nil
            withParams:list];
}

- (void)acceptInvitation:(NSDictionary *)param
          withMethodType:(NSString *)aChannelName
                  result:(nonnull id<ExtSdkCallbackObjc>)result {
    __weak typeof(self) weakSelf = self;
    NSString *username = param[@"username"];
    [AgoraChatClient.sharedClient.contactManager
        approveFriendRequestFromUser:username
                          completion:^(NSString *aUsername, AgoraChatError *aError) {
                            [weakSelf onResult:result
                                withMethodType:ExtSdkMethodKeyAcceptInvitation
                                     withError:aError
                                    withParams:aUsername];
                          }];
}

- (void)declineInvitation:(NSDictionary *)param
           withMethodType:(NSString *)aChannelName
                   result:(nonnull id<ExtSdkCallbackObjc>)result {
    __weak typeof(self) weakSelf = self;
    NSString *username = param[@"username"];
    [AgoraChatClient.sharedClient.contactManager
        declineFriendRequestFromUser:username
                          completion:^(NSString *aUsername, AgoraChatError *aError) {
                            [weakSelf onResult:result
                                withMethodType:ExtSdkMethodKeyDeclineInvitation
                                     withError:aError
                                    withParams:aUsername];
                          }];
}

- (void)getSelfIdsOnOtherPlatform:(NSDictionary *)param
                   withMethodType:(NSString *)aChannelName
                           result:(nonnull id<ExtSdkCallbackObjc>)result {
    __weak typeof(self) weakSelf = self;
    [AgoraChatClient.sharedClient.contactManager
        getSelfIdsOnOtherPlatformWithCompletion:^(NSArray *aList,
                                                  AgoraChatError *aError) {
          [weakSelf onResult:result
              withMethodType:ExtSdkMethodKeyGetSelfIdsOnOtherPlatform
                   withError:aError
                  withParams:aList];
        }];
}

- (void)getAllContacts:(NSDictionary *)param
        withMethodType:(NSString *)aChannelName
                result:(nonnull id<ExtSdkCallbackObjc>)result {
    NSArray<AgoraChatContact *> *contacts =
        [AgoraChatClient.sharedClient.contactManager getAllContacts];
    NSMutableArray *contactList = [NSMutableArray array];
    for (AgoraChatContact *contact in contacts) {
        [contactList addObject:[contact toJsonObject]];
    }
    [self onResult:result
        withMethodType:aChannelName
             withError:nil
            withParams:contactList];
}

- (void)setContactRemark:(NSDictionary *)param
          withMethodType:(NSString *)aChannelName
                  result:(nonnull id<ExtSdkCallbackObjc>)result {
    NSString *userId = param[@"userId"];
    NSString *remark = param[@"remark"];
    __weak typeof(self) weakSelf = self;
    [AgoraChatClient.sharedClient.contactManager
        setContactRemark:userId
                  remark:remark
              completion:^(AgoraChatContact *_Nullable contact,
                           AgoraChatError *_Nullable aError) {
                [weakSelf onResult:result
                    withMethodType:aChannelName
                         withError:aError
                        withParams:nil];
              }];
}

- (void)getContact:(NSDictionary *)param
    withMethodType:(NSString *)aChannelName
            result:(nonnull id<ExtSdkCallbackObjc>)result {
    NSString *userId = param[@"userId"];
    AgoraChatContact *contact =
        [AgoraChatClient.sharedClient.contactManager getContact:userId];
    [self onResult:result
        withMethodType:aChannelName
             withError:nil
            withParams:[contact toJsonObject]];
}

- (void)fetchAllContacts:(NSDictionary *)param
          withMethodType:(NSString *)aChannelName
                  result:(nonnull id<ExtSdkCallbackObjc>)result {
    __weak typeof(self) weakSelf = self;
    [AgoraChatClient.sharedClient.contactManager
        getAllContactsFromServerWithCompletion:^(
            NSArray<AgoraChatContact *> *_Nullable aList, AgoraChatError *_Nullable aError) {
          NSMutableArray *contactList = [NSMutableArray array];
          for (AgoraChatContact *contact in aList) {
              [contactList addObject:[contact toJsonObject]];
          }
          [weakSelf onResult:result
              withMethodType:aChannelName
                   withError:aError
                  withParams:contactList];
        }];
}

- (void)fetchContacts:(NSDictionary *)param
       withMethodType:(NSString *)aChannelName
               result:(nonnull id<ExtSdkCallbackObjc>)result {
    __weak typeof(self) weakSelf = self;
    NSString *cursor = param[@"cursor"];
    int pageSize = [param[@"pageSize"] intValue];
    [AgoraChatClient.sharedClient.contactManager
        getContactsFromServerWithCursor:cursor
                               pageSize:pageSize
                             completion:^(
                                 AgoraChatCursorResult<AgoraChatContact *> *_Nullable aResult,
                                 AgoraChatError *_Nullable aError) {
                               [weakSelf onResult:result
                                   withMethodType:aChannelName
                                        withError:aError
                                       withParams:[aResult toJsonObject]];
                             }];
}

#pragma mark - ExtSdkContactManagerDelegate

- (void)friendshipDidAddByUser:(NSString *)aUsername {
    NSDictionary *map = @{@"type" : @"onContactAdded", @"username" : aUsername};
    [self onReceive:ExtSdkMethodKeyOnContactChanged withParams:map];
}

- (void)friendshipDidRemoveByUser:(NSString *)aUsername {
    NSDictionary *map =
        @{@"type" : @"onContactDeleted", @"username" : aUsername};
    [self onReceive:ExtSdkMethodKeyOnContactChanged withParams:map];
}

- (void)friendRequestDidReceiveFromUser:(NSString *)aUsername
                                message:(NSString *)aMessage {
    NSDictionary *map = @{
        @"type" : @"onContactInvited",
        @"username" : aUsername,
        @"reason" : aMessage
    };
    [self onReceive:ExtSdkMethodKeyOnContactChanged withParams:map];
}

- (void)friendRequestDidApproveByUser:(NSString *)aUsername {
    NSDictionary *map =
        @{@"type" : @"onFriendRequestAccepted", @"username" : aUsername};
    [self onReceive:ExtSdkMethodKeyOnContactChanged withParams:map];
}

- (void)friendRequestDidDeclineByUser:(NSString *)aUsername {
    NSDictionary *map =
        @{@"type" : @"onFriendRequestDeclined", @"username" : aUsername};
    [self onReceive:ExtSdkMethodKeyOnContactChanged withParams:map];
}

@end
