//
//  ExtSdkChatThreadManagerWrapper.m
//  im_flutter_sdk
//
//  Created by asterisk on 2022/5/25.
//

#import "ExtSdkChatThreadManagerWrapper.h"
#import "ExtSdkMethodTypeObjc.h"
#import "ExtSdkToJson.h"

@interface ExtSdkChatThreadManagerWrapper () <AgoraChatThreadManagerDelegate>

@end

@implementation ExtSdkChatThreadManagerWrapper

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

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

- (void)fetchChatThreadDetail:(NSDictionary *)param
               withMethodType:(NSString *)aChannelName
                       result:(nonnull id<ExtSdkCallbackObjc>)result {
    __weak typeof(self) weakSelf = self;
    NSString *threadId = param[@"threadId"];
    [AgoraChatClient.sharedClient.threadManager
        getChatThreadFromSever:threadId
                    completion:^(AgoraChatThread *_Nonnull thread,
                                 AgoraChatError *_Nonnull aError) {
                      [weakSelf onResult:result
                          withMethodType:aChannelName
                               withError:aError
                              withParams:[thread toJsonObject]];
                    }];
}

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

- (void)fetchChatThreadsWithParentId:(NSDictionary *)param
                      withMethodType:(NSString *)aChannelName
                              result:(nonnull id<ExtSdkCallbackObjc>)result {
    __weak typeof(self) weakSelf = self;
    NSString *parentId = param[@"parentId"];
    NSString *cursor = param[@"cursor"];
    NSNumber *pageSize = param[@"pageSize"];
    [AgoraChatClient.sharedClient.threadManager
        getChatThreadsFromServerWithParentId:parentId
                                      cursor:cursor
                                    pageSize:pageSize.intValue
                                  completion:^(AgoraChatCursorResult *_Nonnull aResult,
                                               AgoraChatError *_Nonnull aError) {
                                    [weakSelf onResult:result
                                        withMethodType:aChannelName
                                             withError:aError
                                            withParams:[aResult toJsonObject]];
                                  }];
}

- (void)fetchJoinedChatThreadsWithParentId:(NSDictionary *)param
                            withMethodType:(NSString *)aChannelName
                                    result:
                                        (nonnull id<ExtSdkCallbackObjc>)result {
    __weak typeof(self) weakSelf = self;
    NSString *parentId = param[@"parentId"];
    NSString *cursor = param[@"cursor"];
    NSNumber *pageSize = param[@"pageSize"];
    [AgoraChatClient.sharedClient.threadManager
        getJoinedChatThreadsFromServerWithParentId:parentId
                                            cursor:cursor
                                          pageSize:pageSize.intValue
                                        completion:^(
                                            AgoraChatCursorResult *_Nonnull aResult,
                                            AgoraChatError *_Nonnull aError) {
                                          [weakSelf onResult:result
                                              withMethodType:aChannelName
                                                   withError:aError
                                                  withParams:[aResult
                                                                 toJsonObject]];
                                        }];
}

- (void)fetchChatThreadMember:(NSDictionary *)param
               withMethodType:(NSString *)aChannelName
                       result:(nonnull id<ExtSdkCallbackObjc>)result {
    __weak typeof(self) weakSelf = self;
    NSString *threadId = param[@"threadId"];
    NSString *cursor = param[@"cursor"];
    NSNumber *pageSize = param[@"pageSize"];
    [AgoraChatClient.sharedClient.threadManager
        getChatThreadMemberListFromServerWithId:threadId
                                         cursor:cursor
                                       pageSize:pageSize.intValue
                                     completion:^(
                                         AgoraChatCursorResult *_Nonnull aResult,
                                         AgoraChatError *_Nonnull aError) {
                                       [weakSelf onResult:result
                                           withMethodType:aChannelName
                                                withError:aError
                                               withParams:[aResult
                                                              toJsonObject]];
                                     }];
}

- (void)fetchLastMessageWithChatThreads:(NSDictionary *)param
                         withMethodType:(NSString *)aChannelName
                                 result:(nonnull id<ExtSdkCallbackObjc>)result {
    __weak typeof(self) weakSelf = self;
    NSArray *ids = param[@"threadIds"];
    [AgoraChatClient.sharedClient.threadManager
        getLastMessageFromSeverWithChatThreads:ids
                                    completion:^(NSDictionary<NSString *,
                                                              AgoraChatMessage *>
                                                     *_Nonnull messageMap,
                                                 AgoraChatError *_Nonnull aError) {
                                      NSMutableDictionary *ret =
                                          [NSMutableDictionary
                                              dictionaryWithCapacity:0];
                                      for (NSString *key in messageMap
                                               .allKeys) {
                                          AgoraChatMessage *msg = messageMap[key];
                                          [ret setValue:[msg toJsonObject]
                                                 forKey:key];
                                      }
                                      [weakSelf onResult:result
                                          withMethodType:aChannelName
                                               withError:aError
                                              withParams:ret];
                                    }];
}

- (void)removeMemberFromChatThread:(NSDictionary *)param
                    withMethodType:(NSString *)aChannelName
                            result:(nonnull id<ExtSdkCallbackObjc>)result {
    __weak typeof(self) weakSelf = self;
    NSString *threadId = param[@"threadId"];
    NSString *memberId = param[@"memberId"];
    [AgoraChatClient.sharedClient.threadManager
        removeMemberFromChatThread:threadId
                          threadId:memberId
                        completion:^(AgoraChatError *_Nonnull aError) {
                          [weakSelf onResult:result
                              withMethodType:aChannelName
                                   withError:aError
                                  withParams:nil];
                        }];
}

- (void)updateChatThreadSubject:(NSDictionary *)param
                 withMethodType:(NSString *)aChannelName
                         result:(nonnull id<ExtSdkCallbackObjc>)result {
    __weak typeof(self) weakSelf = self;
    NSString *threadId = param[@"threadId"];
    NSString *name = param[@"name"];
    [AgoraChatClient.sharedClient.threadManager
        updateChatThreadName:name
                    threadId:threadId
                  completion:^(AgoraChatError *_Nonnull aError) {
                    [weakSelf onResult:result
                        withMethodType:aChannelName
                             withError:aError
                            withParams:nil];
                  }];
}

- (void)createChatThread:(NSDictionary *)param
          withMethodType:(NSString *)aChannelName
                  result:(nonnull id<ExtSdkCallbackObjc>)result {
    __weak typeof(self) weakSelf = self;
    NSString *name = param[@"name"];
    NSString *messageId = param[@"messageId"];
    NSString *parentId = param[@"parentId"];
    [AgoraChatClient.sharedClient.threadManager
        createChatThread:name
               messageId:messageId
                parentId:parentId
              completion:^(AgoraChatThread *_Nonnull thread,
                           AgoraChatError *_Nonnull aError) {
                [weakSelf onResult:result
                    withMethodType:aChannelName
                         withError:aError
                        withParams:[thread toJsonObject]];
              }];
}

- (void)joinChatThread:(NSDictionary *)param
        withMethodType:(NSString *)aChannelName
                result:(nonnull id<ExtSdkCallbackObjc>)result {
    __weak typeof(self) weakSelf = self;
    NSString *threadId = param[@"threadId"];
    [AgoraChatClient.sharedClient.threadManager
        joinChatThread:threadId
            completion:^(AgoraChatThread *_Nonnull thread,
                         AgoraChatError *_Nonnull aError) {
              [weakSelf onResult:result
                  withMethodType:aChannelName
                       withError:aError
                      withParams:[thread toJsonObject]];
            }];
}

- (void)leaveChatThread:(NSDictionary *)param
         withMethodType:(NSString *)aChannelName
                 result:(nonnull id<ExtSdkCallbackObjc>)result {
    __weak typeof(self) weakSelf = self;
    NSString *threadId = param[@"threadId"];
    [AgoraChatClient.sharedClient.threadManager
        leaveChatThread:threadId
             completion:^(AgoraChatError *_Nonnull aError) {
               [weakSelf onResult:result
                   withMethodType:aChannelName
                        withError:aError
                       withParams:nil];
             }];
}

- (void)destroyChatThread:(NSDictionary *)param
           withMethodType:(NSString *)aChannelName
                   result:(nonnull id<ExtSdkCallbackObjc>)result {
    __weak typeof(self) weakSelf = self;
    NSString *threadId = param[@"threadId"];
    [AgoraChatClient.sharedClient.threadManager
        destroyChatThread:threadId
               completion:^(AgoraChatError *_Nonnull aError) {
                 [weakSelf onResult:result
                     withMethodType:aChannelName
                          withError:aError
                         withParams:nil];
               }];
}

- (void)getChatThread:(NSDictionary *)param
       withMethodType:(NSString *)aChannelName
               result:(nonnull id<ExtSdkCallbackObjc>)result {
    NSString *msgId = param[@"msgId"];
    AgoraChatMessage *msg =
        [AgoraChatClient.sharedClient.chatManager getMessageWithMessageId:msgId];
    if ([self getMessageParams:result
                withMethodType:aChannelName
                   withMessage:msg]) {
        return;
    }
    [self onResult:result
        withMethodType:aChannelName
             withError:nil
            withParams:msg.chatThread != nil ? [msg.chatThread toJsonObject]
                                             : nil];
}

- (void)getThreadConversation:(NSDictionary *)param
               withMethodType:(NSString *)aChannelName
                       result:(nonnull id<ExtSdkCallbackObjc>)result {
    __weak typeof(self) weakSelf = self;
    NSString *conId = param[@"convId"];
    BOOL needCreate = [param[@"createIfNeed"] boolValue];
    AgoraChatConversation *conv;
    if (!param[@"isChatThread"]) {
        NSMutableDictionary *newParam =
            [[NSMutableDictionary alloc] initWithDictionary:param];
        newParam[@"isChatThread"] = @(YES);
        AgoraChatConversation *conv = [self getConversation:newParam];

    } else {
        AgoraChatConversation *conv = [self getConversation:param];
    }
    if (conv) {
        [weakSelf onResult:result
            withMethodType:aChannelName
                 withError:nil
                withParams:[conv toJsonObject]];
    } else {
        AgoraChatError *aError = [AgoraChatError errorWithDescription:@"no have conversation"
                                                   code:1];
        [weakSelf onResult:result
            withMethodType:aChannelName
                 withError:aError
                withParams:nil];
    }
}

#pragma mark - AgoraChatThreadManagerDelegate

- (void)onChatThreadCreate:(AgoraChatThreadEvent *)event {
    [self onReceive:ExtSdkMethodKeyChatOnChatThreadCreated
         withParams:[event toJsonObject]];
}

- (void)onChatThreadUpdate:(AgoraChatThreadEvent *)event {
    [self onReceive:ExtSdkMethodKeyChatOnChatThreadUpdated
         withParams:[event toJsonObject]];
}

- (void)onChatThreadDestroy:(AgoraChatThreadEvent *)event {
    [self onReceive:ExtSdkMethodKeyChatOnChatThreadDestroyed
         withParams:[event toJsonObject]];
}

- (void)onUserKickOutOfChatThread:(AgoraChatThreadEvent *)event {
    [self onReceive:ExtSdkMethodKeyChatOnChatThreadUserRemoved
         withParams:[event toJsonObject]];
}

@end
