//
//  ExtSdkChatroomManagerWrapper.m
//  im_flutter_sdk
//
//  Created by asteriskzuo on 2019/10/18.
//

#import "ExtSdkChatroomManagerWrapper.h"
#import "ExtSdkMethodTypeObjc.h"

#import "ExtSdkToJson.h"

@interface ExtSdkChatroomManagerWrapper () <AgoraChatroomManagerDelegate>

@end

@implementation ExtSdkChatroomManagerWrapper

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

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

#pragma mark - Actions

- (void)getChatroomsFromServer:(NSDictionary *)param
                withMethodType:(NSString *)aChannelName
                        result:(nonnull id<ExtSdkCallbackObjc>)result {
    NSInteger page = [param[@"pageNum"] integerValue];
    NSInteger pageSize = [param[@"pageSize"] integerValue];

    __weak typeof(self) weakSelf = self;

    [AgoraChatClient.sharedClient.roomManager
        getChatroomsFromServerWithPage:page
                              pageSize:pageSize
                            completion:^(AgoraChatPageResult *aResult,
                                         AgoraChatError *aError) {
                              [weakSelf onResult:result
                                  withMethodType:aChannelName
                                       withError:aError
                                      withParams:[aResult toJsonObject]];
                            }];
}

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

    __weak typeof(self) weakSelf = self;

    NSString *subject = param[@"subject"];
    NSString *description = param[@"desc"];
    NSArray *invitees = param[@"members"];
    NSString *message = param[@"welcomeMsg"];
    NSInteger maxMembersCount = [param[@"maxUserCount"] integerValue];
    [AgoraChatClient.sharedClient.roomManager
        createChatroomWithSubject:subject
                      description:description
                         invitees:invitees
                          message:message
                  maxMembersCount:maxMembersCount
                       completion:^(AgoraChatroom *aChatroom, AgoraChatError *aError) {
                         [weakSelf onResult:result
                             withMethodType:aChannelName
                                  withError:aError
                                 withParams:[aChatroom toJsonObject]];
                       }];
}

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

    __weak typeof(self) weakSelf = self;
    NSString *chatroomId = param[@"roomId"];
    BOOL exitOtherRoom =
        param[@"exitOtherRoom"] ? [param[@"exitOtherRoom"] boolValue] : NO;
    NSString *ext = param[@"ext"];
    [AgoraChatClient.sharedClient.roomManager
           joinChatroom:chatroomId
                    ext:ext
        leaveOtherRooms:exitOtherRoom
             completion:^(AgoraChatroom *_Nullable aChatroom,
                          AgoraChatError *_Nullable aError) {
               [weakSelf onResult:result
                   withMethodType:aChannelName
                        withError:aError
                       withParams:aChatroom ? [aChatroom toJsonObject] : nil];
             }];
}

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

    __weak typeof(self) weakSelf = self;

    NSString *chatroomId = param[@"roomId"];
    [AgoraChatClient.sharedClient.roomManager leaveChatroom:chatroomId
                                          completion:^(AgoraChatError *aError) {
                                            [weakSelf onResult:result
                                                withMethodType:aChannelName
                                                     withError:aError
                                                    withParams:nil];
                                          }];
}

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

    __weak typeof(self) weakSelf = self;

    NSString *chatroomId = param[@"roomId"];
    [AgoraChatClient.sharedClient.roomManager destroyChatroom:chatroomId
                                            completion:^(AgoraChatError *aError) {
                                              [weakSelf onResult:result
                                                  withMethodType:aChannelName
                                                       withError:aError
                                                      withParams:nil];
                                            }];
}

- (void)fetchChatroomFromServer:(NSDictionary *)param
                 withMethodType:(NSString *)aChannelName
                         result:(nonnull id<ExtSdkCallbackObjc>)result {
    __weak typeof(self) weakSelf = self;
    NSString *chatroomId = param[@"roomId"];
    BOOL hasFetchMembers = NO;
    BOOL fetchMembers = NO;
    if (param[@"fetchMembers"]) {
        fetchMembers = [param[@"fetchMembers"] boolValue];
        hasFetchMembers = YES;
    }
    if (hasFetchMembers) {
        [AgoraChatClient.sharedClient.roomManager
            getChatroomSpecificationFromServerWithId:chatroomId
                                        fetchMembers:fetchMembers
                                          completion:^(AgoraChatroom *aChatroom,
                                                       AgoraChatError *aError) {
                                            [weakSelf onResult:result
                                                withMethodType:aChannelName
                                                     withError:aError
                                                    withParams:
                                                        [aChatroom
                                                            toJsonObject]];
                                          }];
    } else {
        [AgoraChatClient.sharedClient.roomManager
            getChatroomSpecificationFromServerWithId:chatroomId
                                          completion:^(AgoraChatroom *aChatroom,
                                                       AgoraChatError *aError) {
                                            [weakSelf onResult:result
                                                withMethodType:aChannelName
                                                     withError:aError
                                                    withParams:
                                                        [aChatroom
                                                            toJsonObject]];
                                          }];
    }
}

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

    __weak typeof(self) weakSelf = self;
    AgoraChatroom *chatroom = [AgoraChatroom chatroomWithId:param[@"roomId"]];
    [weakSelf onResult:result
        withMethodType:aChannelName
             withError:nil
            withParams:[chatroom toJsonObject]];
}

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

    __weak typeof(self) weakSelf = self;
    [AgoraChatClient.sharedClient.roomManager
        getChatroomsFromServerWithPage:0
                              pageSize:-1
                            completion:^(AgoraChatPageResult *aResult,
                                         AgoraChatError *aError) {
                              NSMutableArray *list = [NSMutableArray array];
                              for (AgoraChatroom *room in aResult.list) {
                                  [list addObject:[room toJsonObject]];
                              }

                              [weakSelf onResult:result
                                  withMethodType:aChannelName
                                       withError:aError
                                      withParams:list];
                            }];
}

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

    __weak typeof(self) weakSelf = self;

    NSString *chatroomId = param[@"roomId"];
    NSString *cursor = param[@"cursor"];
    NSInteger pageSize = [param[@"pageSize"] integerValue];
    [AgoraChatClient.sharedClient.roomManager
        getChatroomMemberListFromServerWithId:chatroomId
                                       cursor:cursor
                                     pageSize:pageSize
                                   completion:^(AgoraChatCursorResult *aResult,
                                                AgoraChatError *aError) {
                                     [weakSelf onResult:result
                                         withMethodType:aChannelName
                                              withError:aError
                                             withParams:[aResult toJsonObject]];
                                   }];
}

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

    __weak typeof(self) weakSelf = self;

    NSString *chatroomId = param[@"roomId"];
    NSInteger pageNumber = [param[@"pageNum"] integerValue];
    ;
    NSInteger pageSize = [param[@"pageSize"] integerValue];
    [AgoraChatClient.sharedClient.roomManager
        getChatroomBlacklistFromServerWithId:chatroomId
                                  pageNumber:pageNumber
                                    pageSize:pageSize
                                  completion:^(NSArray *aList,
                                               AgoraChatError *aError) {
                                    [weakSelf onResult:result
                                        withMethodType:aChannelName
                                             withError:aError
                                            withParams:aList];
                                  }];
}

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

    __weak typeof(self) weakSelf = self;

    NSString *chatroomId = param[@"roomId"];
    NSInteger pageNumber = [param[@"pageNum"] integerValue];
    NSInteger pageSize = [param[@"pageSize"] integerValue];
    [AgoraChatClient.sharedClient.roomManager
        getChatroomMuteListFromServerWithId:chatroomId
                                 pageNumber:pageNumber
                                   pageSize:pageSize
                                 completion:^(NSArray *aList, AgoraChatError *aError) {
                                   [weakSelf onResult:result
                                       withMethodType:aChannelName
                                            withError:aError
                                           withParams:aList];
                                 }];
}

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

    __weak typeof(self) weakSelf = self;

    NSString *chatroomId = param[@"roomId"];
    [AgoraChatClient.sharedClient.roomManager
        getChatroomAnnouncementWithId:chatroomId
                           completion:^(NSString *aAnnouncement,
                                        AgoraChatError *aError) {
                             [weakSelf onResult:result
                                 withMethodType:aChannelName
                                      withError:aError
                                     withParams:aAnnouncement];
                           }];
}

- (void)chatRoomUpdateSubject:(NSDictionary *)param
               withMethodType:(NSString *)aChannelName
                       result:(nonnull id<ExtSdkCallbackObjc>)result {
    __weak typeof(self) weakSelf = self;
    NSString *subject = param[@"subject"];
    NSString *chatroomId = param[@"roomId"];
    [AgoraChatClient.sharedClient.roomManager
        updateSubject:subject
          forChatroom:chatroomId
           completion:^(AgoraChatroom *aChatroom, AgoraChatError *aError) {
             [weakSelf onResult:result
                 withMethodType:aChannelName
                      withError:aError
                     withParams:nil];
           }];
}

- (void)chatRoomUpdateDescription:(NSDictionary *)param
                   withMethodType:(NSString *)aChannelName
                           result:(nonnull id<ExtSdkCallbackObjc>)result {
    __weak typeof(self) weakSelf = self;
    NSString *description = param[@"description"];
    NSString *chatroomId = param[@"roomId"];
    [AgoraChatClient.sharedClient.roomManager
        updateDescription:description
              forChatroom:chatroomId
               completion:^(AgoraChatroom *aChatroom, AgoraChatError *aError) {
                 [weakSelf onResult:result
                     withMethodType:aChannelName
                          withError:aError
                         withParams:nil];
               }];
}

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

    __weak typeof(self) weakSelf = self;

    NSArray *members = param[@"members"];
    NSString *chatroomId = param[@"roomId"];
    [AgoraChatClient.sharedClient.roomManager
        removeMembers:members
         fromChatroom:chatroomId
           completion:^(AgoraChatroom *aChatroom, AgoraChatError *aError) {
             [weakSelf onResult:result
                 withMethodType:aChannelName
                      withError:aError
                     withParams:nil];
           }];
}

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

    __weak typeof(self) weakSelf = self;

    NSArray *members = param[@"members"];
    NSString *chatroomId = param[@"roomId"];
    [AgoraChatClient.sharedClient.roomManager
        blockMembers:members
        fromChatroom:chatroomId
          completion:^(AgoraChatroom *aChatroom, AgoraChatError *aError) {
            [weakSelf onResult:result
                withMethodType:aChannelName
                     withError:aError
                    withParams:nil];
          }];
}

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

    __weak typeof(self) weakSelf = self;

    NSArray *members = param[@"members"];
    NSString *chatroomId = param[@"roomId"];
    [AgoraChatClient.sharedClient.roomManager
        unblockMembers:members
          fromChatroom:chatroomId
            completion:^(AgoraChatroom *aChatroom, AgoraChatError *aError) {
              [weakSelf onResult:result
                  withMethodType:aChannelName
                       withError:aError
                      withParams:nil];
            }];
}

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

    __weak typeof(self) weakSelf = self;

    NSString *chatroomId = param[@"roomId"];
    NSString *newOwner = param[@"newOwner"];
    [AgoraChatClient.sharedClient.roomManager
        updateChatroomOwner:chatroomId
                   newOwner:newOwner
                 completion:^(AgoraChatroom *aChatroom, AgoraChatError *aError) {
                   [weakSelf onResult:result
                       withMethodType:aChannelName
                            withError:aError
                           withParams:nil];
                 }];
}

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

    __weak typeof(self) weakSelf = self;

    NSString *admin = param[@"admin"];
    NSString *chatroomId = param[@"roomId"];
    [AgoraChatClient.sharedClient.roomManager
          addAdmin:admin
        toChatroom:chatroomId
        completion:^(AgoraChatroom *aChatroomp, AgoraChatError *aError) {
          [weakSelf onResult:result
              withMethodType:aChannelName
                   withError:aError
                  withParams:nil];
        }];
}

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

    __weak typeof(self) weakSelf = self;

    NSString *admin = param[@"admin"];
    NSString *chatroomId = param[@"roomId"];
    [AgoraChatClient.sharedClient.roomManager
         removeAdmin:admin
        fromChatroom:chatroomId
          completion:^(AgoraChatroom *aChatroom, AgoraChatError *aError) {
            [weakSelf onResult:result
                withMethodType:aChannelName
                     withError:aError
                    withParams:nil];
          }];
}

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

    __weak typeof(self) weakSelf = self;

    NSArray *muteMembers = param[@"muteMembers"];
    NSInteger muteMilliseconds = [param[@"duration"] integerValue];
    NSString *chatroomId = param[@"roomId"];
    [AgoraChatClient.sharedClient.roomManager
             muteMembers:muteMembers
        muteMilliseconds:muteMilliseconds
            fromChatroom:chatroomId
              completion:^(AgoraChatroom *aChatroom, AgoraChatError *aError) {
                [weakSelf onResult:result
                    withMethodType:aChannelName
                         withError:aError
                        withParams:nil];
              }];
}

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

    __weak typeof(self) weakSelf = self;

    NSArray *unMuteMembers = param[@"unMuteMembers"];
    NSString *chatroomId = param[@"roomId"];
    [AgoraChatClient.sharedClient.roomManager
        unmuteMembers:unMuteMembers
         fromChatroom:chatroomId
           completion:^(AgoraChatroom *aChatroom, AgoraChatError *aError) {
             [weakSelf onResult:result
                 withMethodType:aChannelName
                      withError:aError
                     withParams:nil];
           }];
}

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

    __weak typeof(self) weakSelf = self;

    NSString *chatroomId = param[@"roomId"];
    NSString *announcement = param[@"announcement"];
    [AgoraChatClient.sharedClient.roomManager
        updateChatroomAnnouncementWithId:chatroomId
                            announcement:announcement
                              completion:^(AgoraChatroom *aChatroom,
                                           AgoraChatError *aError) {
                                [weakSelf onResult:result
                                    withMethodType:aChannelName
                                         withError:aError
                                        withParams:@(!aError)];
                              }];
}

- (void)addMembersToChatRoomWhiteList:(NSDictionary *)param
                       withMethodType:(NSString *)aChannelName
                               result:(nonnull id<ExtSdkCallbackObjc>)result {
    NSString *roomId = param[@"roomId"];
    NSArray *ary = param[@"members"];
    __weak typeof(self) weakSelf = self;
    [AgoraChatClient.sharedClient.roomManager
        addWhiteListMembers:ary
               fromChatroom:roomId
                 completion:^(AgoraChatroom *aChatroom, AgoraChatError *aError) {
                   [weakSelf onResult:result
                       withMethodType:aChannelName
                            withError:aError
                           withParams:nil];
                 }];
}

- (void)removeMembersFromChatRoomWhiteList:(NSDictionary *)param
                            withMethodType:(NSString *)aChannelName
                                    result:
                                        (nonnull id<ExtSdkCallbackObjc>)result {
    NSString *roomId = param[@"roomId"];
    NSArray *ary = param[@"members"];
    __weak typeof(self) weakSelf = self;
    [AgoraChatClient.sharedClient.roomManager
        removeWhiteListMembers:ary
                  fromChatroom:roomId
                    completion:^(AgoraChatroom *aChatroom, AgoraChatError *aError) {
                      [weakSelf onResult:result
                          withMethodType:aChannelName
                               withError:aError
                              withParams:nil];
                    }];
}

- (void)isMemberInChatRoomWhiteListFromServer:(NSDictionary *)param
                               withMethodType:(NSString *)aChannelName
                                       result:(nonnull id<ExtSdkCallbackObjc>)
                                                  result {
    NSString *roomId = param[@"roomId"];
    __weak typeof(self) weakSelf = self;
    [AgoraChatClient.sharedClient.roomManager
        isMemberInWhiteListFromServerWithChatroomId:roomId
                                         completion:^(BOOL inWhiteList,
                                                      AgoraChatError *aError) {
                                           [weakSelf onResult:result
                                               withMethodType:aChannelName
                                                    withError:aError
                                                   withParams:@(inWhiteList)];
                                         }];
}

- (void)fetchChatRoomWhiteListFromServer:(NSDictionary *)param
                          withMethodType:(NSString *)aChannelName
                                  result:
                                      (nonnull id<ExtSdkCallbackObjc>)result {
    NSString *roomId = param[@"roomId"];
    __weak typeof(self) weakSelf = self;
    [AgoraChatClient.sharedClient.roomManager
        getChatroomWhiteListFromServerWithId:roomId
                                  completion:^(NSArray *aList,
                                               AgoraChatError *aError) {
                                    [weakSelf onResult:result
                                        withMethodType:aChannelName
                                             withError:aError
                                            withParams:aList];
                                  }];
}

- (void)muteAllChatRoomMembers:(NSDictionary *)param
                withMethodType:(NSString *)aChannelName
                        result:(nonnull id<ExtSdkCallbackObjc>)result {
    NSString *roomId = param[@"roomId"];
    __weak typeof(self) weakSelf = self;
    [AgoraChatClient.sharedClient.roomManager
        muteAllMembersFromChatroom:roomId
                        completion:^(AgoraChatroom *aChatroom, AgoraChatError *aError) {
                          [weakSelf onResult:result
                              withMethodType:aChannelName
                                   withError:aError
                                  withParams:@(!aError)];
                        }];
}

- (void)unMuteAllChatRoomMembers:(NSDictionary *)param
                  withMethodType:(NSString *)aChannelName
                          result:(nonnull id<ExtSdkCallbackObjc>)result {
    NSString *roomId = param[@"roomId"];
    __weak typeof(self) weakSelf = self;
    [AgoraChatClient.sharedClient.roomManager
        unmuteAllMembersFromChatroom:roomId
                          completion:^(AgoraChatroom *aChatroom, AgoraChatError *aError) {
                            [weakSelf onResult:result
                                withMethodType:aChannelName
                                     withError:aError
                                    withParams:@(!aError)];
                          }];
}

- (void)fetchChatRoomAttributes:(NSDictionary *)param
                 withMethodType:(NSString *)aChannelName
                         result:(nonnull id<ExtSdkCallbackObjc>)result {
    NSString *roomId = param[@"roomId"];
    NSArray *keys = param[@"keys"];
    __weak typeof(self) weakSelf = self;
    [AgoraChatClient.sharedClient.roomManager
        fetchChatroomAttributes:roomId
                           keys:keys
                     completion:^(AgoraChatError *_Nullable aError,
                                  NSDictionary<NSString *, NSString *>
                                      *_Nullable properties) {
                       [weakSelf onResult:result
                           withMethodType:aChannelName
                                withError:aError
                               withParams:properties];
                     }];
}

- (void)fetchChatRoomAllAttributes:(NSDictionary *)param
                    withMethodType:(NSString *)aChannelName
                            result:(nonnull id<ExtSdkCallbackObjc>)result {
    NSString *roomId = param[@"roomId"];
    __weak typeof(self) weakSelf = self;
    [AgoraChatClient.sharedClient.roomManager
        fetchChatroomAllAttributes:roomId
                        completion:^(AgoraChatError *_Nullable error,
                                     NSDictionary<NSString *, NSString *>
                                         *_Nullable properties) {
                          [weakSelf onResult:result
                              withMethodType:aChannelName
                                   withError:error
                                  withParams:properties];
                        }];
}

- (void)setChatRoomAttributes:(NSDictionary *)param
               withMethodType:(NSString *)aChannelName
                       result:(nonnull id<ExtSdkCallbackObjc>)result {
    NSString *roomId = param[@"roomId"];
    NSArray *attributesArray = param[@"attributes"];
    NSNumber *autoDelete = param[@"autoDelete"];
    BOOL forced = [param[@"forced"] boolValue];
    __weak typeof(self) weakSelf = self;

    NSMutableDictionary *attributes = [NSMutableDictionary dictionary];
    for (int i = 0; i < attributesArray.count; ++i) {
        NSDictionary *kv = attributesArray[i];
        [attributes addEntriesFromDictionary:kv];
    }

    void (^block)(AgoraChatError *, NSDictionary<NSString *, AgoraChatError *> *) =
        ^(AgoraChatError *error, NSDictionary<NSString *, AgoraChatError *> *failureKeys) {
          NSMutableDictionary *tmp = [NSMutableDictionary dictionary];
          for (NSString *key in failureKeys) {
              tmp[key] = @(failureKeys[key].code);
          }
          [weakSelf onResult:result
              withMethodType:aChannelName
                   withError:failureKeys.count == 0 ? error : nil
                  withParams:tmp];
        };

    if (forced) {
        [AgoraChatClient.sharedClient.roomManager
            setChatroomAttributesForced:roomId
                             attributes:attributes
                             autoDelete:[autoDelete boolValue]
                        completionBlock:^(AgoraChatError *_Nullable aError,
                                          NSDictionary<NSString *, AgoraChatError *>
                                              *_Nullable failureKeys) {
                          block(aError, failureKeys);
                        }];
    } else {
        [AgoraChatClient.sharedClient.roomManager
            setChatroomAttributes:roomId
                       attributes:attributes
                       autoDelete:[autoDelete boolValue]
                  completionBlock:^(AgoraChatError *_Nullable aError,
                                    NSDictionary<NSString *, AgoraChatError *>
                                        *_Nullable failureKeys) {
                    block(aError, failureKeys);
                  }];
    }
}

- (void)removeChatRoomAttributes:(NSDictionary *)param
                  withMethodType:(NSString *)aChannelName
                          result:(nonnull id<ExtSdkCallbackObjc>)result {
    NSString *roomId = param[@"roomId"];
    NSArray *keys = param[@"keys"];
    BOOL forced = [param[@"forced"] boolValue];
    __weak typeof(self) weakSelf = self;

    void (^block)(AgoraChatError *, NSDictionary<NSString *, AgoraChatError *> *) =
        ^(AgoraChatError *error, NSDictionary<NSString *, AgoraChatError *> *failureKeys) {
          NSMutableDictionary *tmp = [NSMutableDictionary dictionary];
          for (NSString *key in failureKeys.allKeys) {
              tmp[key] = @(failureKeys[key].code);
          }
          [weakSelf onResult:result
              withMethodType:aChannelName
                   withError:failureKeys.count == 0 ? error : nil
                  withParams:tmp];
        };

    if (forced) {
        [AgoraChatClient.sharedClient.roomManager
            removeChatroomAttributesForced:roomId
                                attributes:keys
                           completionBlock:^(AgoraChatError *_Nullable aError,
                                             NSDictionary<NSString *, AgoraChatError *>
                                                 *_Nullable failureKeys) {
                             block(aError, failureKeys);
                           }];
    } else {
        [AgoraChatClient.sharedClient.roomManager
            removeChatroomAttributes:roomId
                          attributes:keys
                     completionBlock:^(AgoraChatError *_Nullable aError,
                                       NSDictionary<NSString *, AgoraChatError *>
                                           *_Nullable failureKeys) {
                       block(aError, failureKeys);
                     }];
    }
}

#pragma mark - AgoraChatroomManagerDelegate

- (void)userDidJoinChatroom:(AgoraChatroom *)aChatroom
                       user:(NSString *)aUsername
                        ext:(NSString *_Nullable)ext {
    NSDictionary *map = @{
        @"type" : @"onMemberJoined",
        @"roomId" : aChatroom.chatroomId,
        @"participant" : aUsername,
        @"ext" : ext,
    };
    [self onReceive:ExtSdkMethodKeyChatroomChanged withParams:map];
}

- (void)userDidLeaveChatroom:(AgoraChatroom *)aChatroom
                        user:(NSString *)aUsername {
    NSDictionary *map = @{
        @"type" : @"onMemberExited",
        @"roomId" : aChatroom.chatroomId,
        @"roomName" : aChatroom.subject,
        @"participant" : aUsername
    };
    [self onReceive:ExtSdkMethodKeyChatroomChanged withParams:map];
}

- (void)didDismissFromChatroom:(AgoraChatroom *)aChatroom
                        reason:(AgoraChatroomBeKickedReason)aReason {
    NSDictionary *map;
    if (aReason == AgoraChatroomBeKickedReasonDestroyed) {
        map = @{
            @"type" : @"onChatRoomDestroyed",
            @"roomId" : aChatroom.chatroomId,
            @"roomName" : aChatroom.subject
        };
    } else if (aReason == AgoraChatroomBeKickedReasonBeRemoved) {
        map = @{
            @"type" : @"onRemovedFromChatRoom",
            @"roomId" : aChatroom.chatroomId,
            @"roomName" : aChatroom.subject,
            @"participant" : [[AgoraChatClient sharedClient] currentUsername],
            @"reason" : @(aReason)
        };
    }

    [self onReceive:ExtSdkMethodKeyChatroomChanged withParams:map];
}

- (void)chatroomMuteListDidUpdate:(AgoraChatroom *)aChatroom
                addedMutedMembers:(NSArray *)aMutes
                       muteExpire:(NSInteger)aMuteExpire {
    NSDictionary *map = @{
        @"type" : @"onMuteListAdded",
        @"roomId" : aChatroom.chatroomId,
        @"mutes" : aMutes,
        @"expireTime" : [NSString stringWithFormat:@"%ld", aMuteExpire]
    };
    [self onReceive:ExtSdkMethodKeyChatroomChanged withParams:map];
}

- (void)chatroomMuteListDidUpdate:(AgoraChatroom *)aChatroom
                addedMutedMembers:
                    (NSDictionary<NSString *, NSNumber *> *)aMutes {
    NSMutableArray *array = [NSMutableArray array];
    for (NSString *key in aMutes) {
        [array addObject:key];
    }
    NSDictionary *map = @{
        @"type" : @"onMuteListAdded",
        @"roomId" : aChatroom.chatroomId,
        @"muteKVs" : aMutes,
    };
    [self onReceive:ExtSdkMethodKeyChatroomChanged withParams:map];
}

- (void)chatroomMuteListDidUpdate:(AgoraChatroom *)aChatroom
              removedMutedMembers:(NSArray *)aMutes {
    NSDictionary *map = @{
        @"type" : @"onMuteListRemoved",
        @"roomId" : aChatroom.chatroomId,
        @"mutes" : aMutes
    };
    [self onReceive:ExtSdkMethodKeyChatroomChanged withParams:map];
}

- (void)chatroomAdminListDidUpdate:(AgoraChatroom *)aChatroom
                        addedAdmin:(NSString *)aAdmin {
    NSDictionary *map = @{
        @"type" : @"onAdminAdded",
        @"roomId" : aChatroom.chatroomId,
        @"admin" : aAdmin
    };
    [self onReceive:ExtSdkMethodKeyChatroomChanged withParams:map];
}

- (void)chatroomAdminListDidUpdate:(AgoraChatroom *)aChatroom
                      removedAdmin:(NSString *)aAdmin {
    NSDictionary *map = @{
        @"type" : @"onAdminRemoved",
        @"roomId" : aChatroom.chatroomId,
        @"admin" : aAdmin
    };
    [self onReceive:ExtSdkMethodKeyChatroomChanged withParams:map];
}

- (void)chatroomOwnerDidUpdate:(AgoraChatroom *)aChatroom
                      newOwner:(NSString *)aNewOwner
                      oldOwner:(NSString *)aOldOwner {
    NSDictionary *map = @{
        @"type" : @"onOwnerChanged",
        @"roomId" : aChatroom.chatroomId,
        @"newOwner" : aNewOwner,
        @"oldOwner" : aOldOwner
    };
    [self onReceive:ExtSdkMethodKeyChatroomChanged withParams:map];
}

- (void)chatroomAnnouncementDidUpdate:(AgoraChatroom *)aChatroom
                         announcement:(NSString *)aAnnouncement {
    NSDictionary *map = @{
        @"type" : @"onAnnouncementChanged",
        @"roomId" : aChatroom.chatroomId,
        @"announcement" : aAnnouncement
    };
    [self onReceive:ExtSdkMethodKeyChatroomChanged withParams:map];
}

- (void)chatroomWhiteListDidUpdate:(AgoraChatroom *)aChatroom
             addedWhiteListMembers:(NSArray *)aMembers {
    NSDictionary *map = @{
        @"type" : @"onAllowListAdded",
        @"roomId" : aChatroom.chatroomId,
        @"members" : aMembers
    };
    [self onReceive:ExtSdkMethodKeyChatroomChanged withParams:map];
}

- (void)chatroomWhiteListDidUpdate:(AgoraChatroom *)aChatroom
           removedWhiteListMembers:(NSArray *)aMembers {
    NSDictionary *map = @{
        @"type" : @"onAllowListRemoved",
        @"roomId" : aChatroom.chatroomId,
        @"members" : aMembers
    };
    [self onReceive:ExtSdkMethodKeyChatroomChanged withParams:map];
}

- (void)chatroomAllMemberMuteChanged:(AgoraChatroom *)aChatroom
                    isAllMemberMuted:(BOOL)aMuted {
    NSDictionary *map = @{
        @"type" : @"onAllMemberMuteStateChanged",
        @"roomId" : aChatroom.chatroomId,
        @"isMuted" : @(aMuted)
    };
    [self onReceive:ExtSdkMethodKeyChatroomChanged withParams:map];
}

- (void)chatroomSpecificationDidUpdate:(AgoraChatroom *)aChatroom {
    NSDictionary *map = @{
        @"type" : @"onSpecificationChanged",
        @"room" : [aChatroom toJsonObject]
    };
    [self onReceive:ExtSdkMethodKeyChatroomChanged withParams:map];
}

- (void)chatroomAttributesDidUpdated:(NSString *_Nonnull)roomId
                        attributeMap:
                            (NSDictionary<NSString *, NSString *> *_Nonnull)
                                attributeMap
                                from:(NSString *_Nonnull)fromId {
    NSDictionary *map = @{
        @"type" : @"onAttributesUpdated",
        @"roomId" : roomId,
        @"attributes" : attributeMap,
        @"from" : fromId,
    };
    [self onReceive:ExtSdkMethodKeyChatroomChanged withParams:map];
}

- (void)chatroomAttributesDidRemoved:(NSString *_Nonnull)roomId
                          attributes:
                              (NSArray<__kindof NSString *> *_Nonnull)attributes
                                from:(NSString *_Nonnull)fromId {
    NSDictionary *map = @{
        @"type" : @"onAttributesRemoved",
        @"roomId" : roomId,
        @"removedKeys" : attributes,
        @"from" : fromId,
    };
    [self onReceive:ExtSdkMethodKeyChatroomChanged withParams:map];
}

#pragma mark - AgoraChatroom Pack Method

// 聊天室成员获取结果转字典
- (NSDictionary *)dictionaryWithCursorResult:(AgoraChatCursorResult *)cursorResult {
    NSDictionary *resultDict =
        @{@"data" : cursorResult.list, @"cursor" : cursorResult.cursor};
    return resultDict;
}

@end
