
//  Created by Tencent on 2023/06/09.
//  Copyright © 2023 Tencent. All rights reserved.

#import "TUIMessageController_Minimalist.h"
#import <TIMCommon/TIMDefine.h>
#import <TUICore/TUIGlobalization.h>
#import <TUICore/TUIThemeManager.h>
#import <TUICore/UIView+TUILayout.h>
#import "TUIBaseMessageController_Minimalist+ProtectedAPI.h"
#import "TUIChatConfig.h"
#import "TUIChatModifyMessageHelper.h"
#import "TUIChatSmallTongueView_Minimalist.h"
#import "TUIMessageSearchDataProvider.h"
#import "TUIReferenceMessageCell_Minimalist.h"
#import "TUIReplyMessageCellData.h"
#import "TUIReplyMessageCell_Minimalist.h"
#import "TUITextMessageCell_Minimalist.h"

#define MSG_GET_COUNT 20

@interface TUIMessageController_Minimalist () <TUIChatSmallTongueViewDelegate_Minimalist>
@property(nonatomic, strong) UIActivityIndicatorView *bottomIndicatorView;
@property(nonatomic, assign) uint64_t locateGroupMessageSeq;
@property(nonatomic, strong) TUIChatSmallTongueView_Minimalist *tongueView;
@property(nonatomic, strong) NSMutableArray *receiveMsgs;
@property(nonatomic, weak) UIImageView *backgroudView;
@end

@implementation TUIMessageController_Minimalist

#pragma mark - Life Cycle
- (void)viewDidLoad {
    [super viewDidLoad];

    self.bottomIndicatorView =
        [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(0, 0, self.tableView.frame.size.width, TMessageController_Header_Height)];
    self.bottomIndicatorView.activityIndicatorViewStyle = UIActivityIndicatorViewStyleGray;
    self.tableView.tableFooterView = self.bottomIndicatorView;

    self.tableView.backgroundColor = UIColor.clearColor;

    [NSNotificationCenter.defaultCenter addObserver:self selector:@selector(keyboardWillShow) name:UIKeyboardWillShowNotification object:nil];

    self.receiveMsgs = [NSMutableArray array];
    
    dispatch_async(dispatch_get_main_queue(), ^{
        if (self.conversationData.atMsgSeqs.count > 0) {
            TUIChatSmallTongue_Minimalist *tongue = [[TUIChatSmallTongue_Minimalist alloc] init];
            tongue.type = TUIChatSmallTongueType_SomeoneAt;
            tongue.parentView = self.view.superview;
            tongue.atMsgSeqs = [self.conversationData.atMsgSeqs copy];
            [TUIChatSmallTongueManager_Minimalist showTongue:tongue delegate:self];
        }
    });

}

- (void)dealloc {
    [TUIChatSmallTongueManager_Minimalist removeTongue];
    [NSNotificationCenter.defaultCenter removeObserver:self];
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [TUIChatSmallTongueManager_Minimalist hideTongue:NO];
}

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    [TUIChatSmallTongueManager_Minimalist hideTongue:YES];
}

#pragma mark - Notification

- (void)keyboardWillShow {
    if (![self messageSearchDataProvider].isNewerNoMoreMsg) {
        [[self messageSearchDataProvider] removeAllSearchData];
        [self.tableView reloadData];
        [self loadMessages:YES];
    }
}

#pragma mark - Overrider
- (void)willShowMediaMessage:(TUIMessageCell *)cell {
    [TUIChatSmallTongueManager_Minimalist hideTongue:YES];
}

- (void)didCloseMediaMessage:(TUIMessageCell *)cell {
    [TUIChatSmallTongueManager_Minimalist hideTongue:NO];
}

- (void)onDelete:(TUIMessageCell *)cell {
    TUIMessageCellData *cellData = cell.messageData;
    @weakify(self);
    UIAlertController *vc = [UIAlertController alertControllerWithTitle:nil
                                                                message:TIMCommonLocalizableString(ConfirmDeleteMessage)
                                                         preferredStyle:UIAlertControllerStyleActionSheet];
    [vc tuitheme_addAction:[UIAlertAction actionWithTitle:TIMCommonLocalizableString(Delete)
                                                    style:UIAlertActionStyleDestructive
                                                  handler:^(UIAlertAction *_Nonnull action) {
                                                    @strongify(self);
                                                    [self.messageDataProvider deleteUIMsgs:@[ cellData ]
                                                        SuccBlock:^{
                                                          [self updateAtMeTongue:cellData];
                                                        }
                                                        FailBlock:^(int code, NSString *desc) {
                                                          NSLog(@"remove msg failed!");
                                                          NSAssert(NO, desc);
                                                        }];
                                                  }]];
    [vc tuitheme_addAction:[UIAlertAction actionWithTitle:TIMCommonLocalizableString(Cancel) style:UIAlertActionStyleCancel handler:nil]];
    [self presentViewController:vc animated:YES completion:nil];
}

- (void)updateAtMeTongue:(TUIMessageCellData *)deleteCellData {
    uint64_t deleteSeq = deleteCellData.innerMessage.seq;
    if ([self.conversationData.atMsgSeqs containsObject:@(deleteSeq)]) {
        [self.conversationData.atMsgSeqs removeObject:@(deleteSeq)];
        if (self.conversationData.atMsgSeqs.count > 0) {
            TUIChatSmallTongue_Minimalist *tongue = [[TUIChatSmallTongue_Minimalist alloc] init];
            tongue.type = TUIChatSmallTongueType_SomeoneAt;
            tongue.parentView = self.view.superview;
            tongue.atMsgSeqs = [self.conversationData.atMsgSeqs copy];
            [TUIChatSmallTongueManager_Minimalist showTongue:tongue delegate:self];
        } else {
            [TUIChatSmallTongueManager_Minimalist removeTongue:TUIChatSmallTongueType_SomeoneAt];
        }
    }
}

#pragma mark - UIScrollViewDelegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    [super scrollViewDidScroll:scrollView];
    if (scrollView.contentOffset.y <= TMessageController_Header_Height && ![self messageSearchDataProvider].isOlderNoMoreMsg) {
        /**
         * Display pull-to-refresh icon
         */
        if (!self.indicatorView.isAnimating) {
            [self.indicatorView startAnimating];
        }
    } else if ([self isScrollToBottomIndicatorViewY:scrollView]) {
        if (![self messageSearchDataProvider].isNewerNoMoreMsg) {
            /**
             * Display pull-up-loading icon
             */
            if (!self.bottomIndicatorView.isAnimating) {
                [self.bottomIndicatorView startAnimating];
            }
        }
        /**
         * Remove the "back to the latest position", "xxx new message" bottom-banner-tips
         */
        if (self.isInVC) {
            [TUIChatSmallTongueManager_Minimalist removeTongue:TUIChatSmallTongueType_ScrollToBoom];
            [TUIChatSmallTongueManager_Minimalist removeTongue:TUIChatSmallTongueType_ReceiveNewMsg];
        }
    } else if (self.isInVC && 0 == self.receiveMsgs.count && self.tableView.contentSize.height - self.tableView.contentOffset.y >= Screen_Height * 2.0) {
        CGPoint point = [scrollView.panGestureRecognizer translationInView:scrollView];
        /**
         * When swiping, add a "back to last position" bottom-banner-tips
         */
        if (point.y > 0) {
            TUIChatSmallTongue_Minimalist *tongue = [[TUIChatSmallTongue_Minimalist alloc] init];
            tongue.type = TUIChatSmallTongueType_ScrollToBoom;
            tongue.parentView = self.view.superview;
            [TUIChatSmallTongueManager_Minimalist showTongue:tongue delegate:self];
        }
    } else if (self.isInVC && self.tableView.contentSize.height - self.tableView.contentOffset.y >= 20) {
        /**
         * Remove the "someone @ me" bottom-banner-tips
         */
        [TUIChatSmallTongueManager_Minimalist removeTongue:TUIChatSmallTongueType_SomeoneAt];
    } else {
        if (self.indicatorView.isAnimating) {
            [self.indicatorView stopAnimating];
        }
        if (self.bottomIndicatorView.isAnimating) {
            [self.bottomIndicatorView stopAnimating];
        }
    }
}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    [super scrollViewDidEndDecelerating:scrollView];
    if (scrollView.contentOffset.y <= TMessageController_Header_Height && ![self messageSearchDataProvider].isOlderNoMoreMsg) {
        /**
         * Pull old news
         */
        [self loadMessages:YES];
    } else if ([self isScrollToBottomIndicatorViewY:scrollView] && ![self messageSearchDataProvider].isNewerNoMoreMsg) {
        /**
         * Load latese message
         */
        [self loadMessages:NO];
    }
}

- (BOOL)isScrollToBottomIndicatorViewY:(UIScrollView *)scrollView {
    /**
     * +2 pixels when scrolling to critical point
     */
    return (scrollView.contentOffset.y + self.tableView.mm_h + 2) > (scrollView.contentSize.height - self.indicatorView.mm_h);
}

#pragma mark - Getters & Setters
- (void)setConversation:(TUIChatConversationModel *)conversationData {
    self.conversationData = conversationData;
    self.messageDataProvider = [[TUIMessageSearchDataProvider alloc] initWithConversationModel:self.conversationData];
    self.messageDataProvider.dataSource = self;
    self.messageDataProvider.mergeAdjacentMsgsFromTheSameSender = YES;
    if (self.locateMessage) {
        [self loadAndScrollToLocateMessages:NO isHighlight:YES];
    } else {
        [[self messageSearchDataProvider] removeAllSearchData];
        [self loadMessages:YES];
    }
    [self loadGroupInfo];
}

#pragma mark - Private Methods
- (TUIMessageSearchDataProvider *)messageSearchDataProvider {
    return (TUIMessageSearchDataProvider *)self.messageDataProvider;
}

- (void)loadAndScrollToLocateMessages:(BOOL)scrollToBoom isHighlight:(BOOL)isHighlight{
    if (!self.locateMessage && self.locateGroupMessageSeq == 0) {
        return;
    }
    @weakify(self);
    [[self messageSearchDataProvider]
        loadMessageWithSearchMsg:self.locateMessage
                    SearchMsgSeq:self.locateGroupMessageSeq
                ConversationInfo:self.conversationData
     SucceedBlock:^(BOOL isOlderNoMoreMsg, BOOL isNewerNoMoreMsg, NSArray<TUIMessageCellData *> *_Nonnull newMsgs) {
        @strongify(self);
        [self.indicatorView stopAnimating];
        [self.bottomIndicatorView stopAnimating];
        self.indicatorView.mm_h = 0;
        self.bottomIndicatorView.mm_h = 0;
        [self.tableView reloadData];
        [self.tableView layoutIfNeeded];
        
        dispatch_async(dispatch_get_main_queue(), ^{
            @strongify(self);
            [self scrollToLocateMessage:scrollToBoom];
            if (isHighlight) {
                [self highlightKeyword];
            }
        });
    }
    FailBlock:^(int code, NSString *desc){}];
}

- (void)scrollToLocateMessage:(BOOL)scrollToBoom {
    /**
     *  locateMsg 
     * First find the coordinate offset of locateMsg
     */
    CGFloat offsetY = 0;
    NSInteger index = 0;
    for (TUIMessageCellData *uiMsg in [self messageSearchDataProvider].uiMsgs) {
        if ([self isLocateMessage:uiMsg]) {
            break;
        }
        offsetY += [self getHeightFromMessageCellData:uiMsg];
        index++;
    }

    /**
     * 
     * The locateMsg not found
     */
    if (index == [self messageSearchDataProvider].uiMsgs.count) {
        return;
    }

    /**
     *  tableview 
     * Offset half the height of the tableview
     */
    offsetY -= self.tableView.frame.size.height / 2.0;
    if (offsetY <= TMessageController_Header_Height) {
        offsetY = TMessageController_Header_Height + 0.1;
    }

    if (offsetY > TMessageController_Header_Height) {
        [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:index inSection:0]
                              atScrollPosition:UITableViewScrollPositionMiddle
                                      animated:YES];
    }
}

- (void)highlightKeyword {
    TUIMessageCellData *cellData = nil;
    for (TUIMessageCellData *tmp in [self messageSearchDataProvider].uiMsgs) {
        if ([self isLocateMessage:tmp]) {
            cellData = tmp;
            break;
        }
    }
    if (cellData == nil || cellData.innerMessage.elemType == V2TIM_ELEM_TYPE_GROUP_TIPS) {
        return;
    }

    @weakify(self);
    dispatch_async(dispatch_get_main_queue(), ^{
      @strongify(self);
      NSIndexPath *indexPath = [NSIndexPath indexPathForRow:[[self messageDataProvider].uiMsgs indexOfObject:cellData] inSection:0];
      cellData.highlightKeyword = self.hightlightKeyword.length ? self.hightlightKeyword : @"hightlight";
      TUIMessageCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
      [cell fillWithData:cellData];
      [cell layoutSubviews];
      @weakify(self);
      dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        @strongify(self);
        NSIndexPath *indexPath = [NSIndexPath indexPathForRow:[[self messageDataProvider].uiMsgs indexOfObject:cellData] inSection:0];
        cellData.highlightKeyword = nil;
        TUIMessageCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
        [cell fillWithData:cellData];
        [cell layoutSubviews];
      });
    });
}

- (BOOL)isLocateMessage:(TUIMessageCellData *)uiMsg {
    if (self.locateMessage) {
        if ([uiMsg.innerMessage.msgID isEqualToString:self.locateMessage.msgID]) {
            return YES;
        }
    } else {
        if (self.conversationData.groupID.length > 0 && uiMsg.innerMessage && uiMsg.innerMessage.seq == self.locateGroupMessageSeq) {
            return YES;
        }
    }
    return NO;
}

- (void)loadMessages:(BOOL)order {
    if ([self messageSearchDataProvider].isLoadingData) {
        return;
    }

    if (order && [self messageSearchDataProvider].isOlderNoMoreMsg) {
        [self.indicatorView stopAnimating];
        return;
    }
    if (!order && [self messageSearchDataProvider].isNewerNoMoreMsg) {
        [self.bottomIndicatorView stopAnimating];
        return;
    }

    @weakify(self);
    [[self messageSearchDataProvider]
        loadMessageWithIsRequestOlderMsg:order
                        ConversationInfo:self.conversationData
                            SucceedBlock:^(BOOL isOlderNoMoreMsg, BOOL isNewerNoMoreMsg, BOOL isFirstLoad, NSArray<TUIMessageCellData *> *_Nonnull newUIMsgs) {
                              @strongify(self);

                              [self.indicatorView stopAnimating];
                              [self.bottomIndicatorView stopAnimating];
                              if (isOlderNoMoreMsg) {
                                  self.indicatorView.mm_h = 0;
                              } else {
                                  self.indicatorView.mm_h = TMessageController_Header_Height;
                              }
                              if (isNewerNoMoreMsg) {
                                  self.bottomIndicatorView.mm_h = 0;
                              } else {
                                  self.bottomIndicatorView.mm_h = TMessageController_Header_Height;
                              }

                              [self.tableView reloadData];
                              [self.tableView layoutIfNeeded];

                              [newUIMsgs enumerateObjectsWithOptions:NSEnumerationReverse
                                                          usingBlock:^(TUIMessageCellData *_Nonnull obj, NSUInteger idx, BOOL *_Nonnull stop) {
                                                            if (obj.direction == MsgDirectionIncoming) {
                                                                self.C2CIncomingLastMsg = obj.innerMessage;
                                                                *stop = YES;
                                                            }
                                                          }];

                              if (isFirstLoad) {
                                  [self scrollToBottom:NO];
                              } else {
                                  if (order) {
                                      NSInteger index = 0;
                                      if (newUIMsgs.count > 0) {
                                          index = newUIMsgs.count - 1;
                                      }
                                      if (self.messageDataProvider.uiMsgs.count > 0) {
                                          [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:index inSection:0]
                                                                atScrollPosition:UITableViewScrollPositionTop
                                                                        animated:NO];
                                      }
                                  }
                              }
                            }
                               FailBlock:^(int code, NSString *desc){

                               }];
}

- (void)showReplyMessage:(TUIReplyMessageCell_Minimalist *)cell {
    NSString *originMsgID = @"";
    NSString *msgAbstract = @"";
    if ([cell isKindOfClass:TUIReplyMessageCell_Minimalist.class]) {
        TUIReplyMessageCell_Minimalist *acell = (TUIReplyMessageCell_Minimalist *)cell;
        TUIReplyMessageCellData *cellData = acell.replyData;
        originMsgID = cellData.messageRootID;
        msgAbstract = cellData.msgAbstract;
    } else if ([cell isKindOfClass:TUIReferenceMessageCell_Minimalist.class]) {
        TUIReferenceMessageCell_Minimalist *acell = (TUIReferenceMessageCell_Minimalist *)cell;
        TUIReferenceMessageCellData *cellData = acell.referenceData;
        originMsgID = cellData.originMsgID;
        msgAbstract = cellData.msgAbstract;
    }

    [(TUIMessageSearchDataProvider *)self.messageDataProvider
        findMessages:@[ originMsgID ?: @"" ]
            callback:^(BOOL success, NSString *_Nonnull desc, NSArray<V2TIMMessage *> *_Nonnull msgs) {
              if (!success) {
                  [TUITool makeToast:TIMCommonLocalizableString(TUIKitReplyMessageNotFoundOriginMessage)];
                  return;
              }
              V2TIMMessage *message = msgs.firstObject;
              if (message == nil) {
                  [TUITool makeToast:TIMCommonLocalizableString(TUIKitReplyMessageNotFoundOriginMessage)];
                  return;
              }

              if (message.status == V2TIM_MSG_STATUS_HAS_DELETED || message.status == V2TIM_MSG_STATUS_LOCAL_REVOKED) {
                  [TUITool makeToast:TIMCommonLocalizableString(TUIKitReplyMessageNotFoundOriginMessage)];
                  return;
              }

              if ([cell isKindOfClass:TUIReplyMessageCell_Minimalist.class]) {
                  [self jumpDetailPageByMessage:message];
              } else if ([cell isKindOfClass:TUIReferenceMessageCell_Minimalist.class]) {
                  [self locateAssignMessage:message matchKeyWord:msgAbstract];
              }
            }];
}

- (void)jumpDetailPageByMessage:(V2TIMMessage *)message {
    NSMutableArray *uiMsgs = [self.messageDataProvider transUIMsgFromIMMsg:@[ message ]];
    if (uiMsgs.count == 0) {
        return;
    }
    [self.messageDataProvider preProcessMessage:uiMsgs
                                       callback:^{
                                         for (TUIMessageCellData *cellData in uiMsgs) {
                                             if ([cellData.innerMessage.msgID isEqual:message.msgID]) {
                                                 [self onJumpToRepliesDetailPage:cellData];
                                                 return;
                                             }
                                         }
                                       }];
}

- (void)locateAssignMessage:(V2TIMMessage *)message matchKeyWord:(NSString *)keyword {
    if (message == nil) {
        return;
    }
    self.locateMessage = message;
    self.hightlightKeyword = keyword;

    BOOL memoryExist = NO;
    for (TUIMessageCellData *cellData in self.messageDataProvider.uiMsgs) {
        if ([cellData.innerMessage.msgID isEqual:message.msgID]) {
            memoryExist = YES;
            break;
        }
    }
    if (memoryExist) {
        [self scrollToLocateMessage:NO];
        [self highlightKeyword];
        return;
    }

    TUIMessageSearchDataProvider *provider = (TUIMessageSearchDataProvider *)self.messageDataProvider;
    provider.isNewerNoMoreMsg = NO;
    provider.isOlderNoMoreMsg = NO;
    [self loadAndScrollToLocateMessages:NO isHighlight:YES];
}

- (void)findMessages:(NSArray<NSString *> *)msgIDs callback:(void (^)(BOOL success, NSString *desc, NSArray<V2TIMMessage *> *messages))callback {
    TUIMessageSearchDataProvider *provider = (TUIMessageSearchDataProvider *)self.messageDataProvider;
    if (provider) {
        [provider findMessages:msgIDs callback:callback];
    }
}

#pragma mark - TUIMessageBaseDataProviderDataSource
- (void)dataProvider:(TUIMessageDataProvider *)dataProvider ReceiveNewUIMsg:(TUIMessageCellData *)uiMsg {
    [super dataProvider:dataProvider ReceiveNewUIMsg:uiMsg];
    /**
     * When viewing historical messages, if you scroll more than two screens, after receiving a new message, add a "xxx new message" bottom-banner-tips
     */
    if (self.tableView.contentSize.height - self.tableView.contentOffset.y >= Screen_Height * 2.0) {
        [self.receiveMsgs addObject:uiMsg];
        TUIChatSmallTongue_Minimalist *tongue = [[TUIChatSmallTongue_Minimalist alloc] init];
        tongue.type = TUIChatSmallTongueType_ReceiveNewMsg;
        tongue.parentView = self.view.superview;
        tongue.unreadMsgCount = self.receiveMsgs.count;
        [TUIChatSmallTongueManager_Minimalist showTongue:tongue delegate:self];
    }

    if (self.isInVC) {
        self.C2CIncomingLastMsg = uiMsg.innerMessage;
    }
}

- (void)dataProvider:(TUIMessageDataProvider *)dataProvider ReceiveRevokeUIMsg:(TUIMessageCellData *)uiMsg {
    /**
     * Recalled messages need to be removed from "xxx new messages" bottom-banner-tips
     */
    [super dataProvider:dataProvider ReceiveRevokeUIMsg:uiMsg];
    if ([self.receiveMsgs containsObject:uiMsg]) {
        [self.receiveMsgs removeObject:uiMsg];
        TUIChatSmallTongue_Minimalist *tongue = [[TUIChatSmallTongue_Minimalist alloc] init];
        tongue.type = TUIChatSmallTongueType_ReceiveNewMsg;
        tongue.parentView = self.view.superview;
        tongue.unreadMsgCount = self.receiveMsgs.count;
        if (tongue.unreadMsgCount != 0) {
            [TUIChatSmallTongueManager_Minimalist showTongue:tongue delegate:self];
        } else {
            [TUIChatSmallTongueManager_Minimalist removeTongue:TUIChatSmallTongueType_ReceiveNewMsg];
        }
    }

    /*
     *  When the retracted message is a "reply" type of message, go to the root message to delete the currently retracted message.
     */

    if ([uiMsg isKindOfClass:TUIReplyMessageCellData.class]) {
        TUIReplyMessageCellData *cellData = (TUIReplyMessageCellData *)uiMsg;
        NSString *messageRootID = @"";
        NSString *revokeMsgID = @"";
        messageRootID = cellData.messageRootID;
        revokeMsgID = cellData.msgID;

        [(TUIMessageSearchDataProvider *)self.messageDataProvider
            findMessages:@[ messageRootID ?: @"" ]
                callback:^(BOOL success, NSString *_Nonnull desc, NSArray<V2TIMMessage *> *_Nonnull msgs) {
                  if (success) {
                      V2TIMMessage *message = msgs.firstObject;
                      [[TUIChatModifyMessageHelper defaultHelper] modifyMessage:message revokeMsgID:revokeMsgID];
                  }
                }];
    }
    
    for (TUIMessageCellData * cellData in self.messageDataProvider.uiMsgs) {
        if ([cellData isKindOfClass:TUIReplyMessageCellData.class]) {
            TUIReplyMessageCellData *replyMessageData = (TUIReplyMessageCellData *)cellData;
            if ([replyMessageData.originMessage.msgID isEqualToString:uiMsg.msgID]) {
                [self.messageDataProvider processQuoteMessage:@[replyMessageData]];
            }
        }
    }
}

#pragma mark - TUIChatSmallTongueViewDelegate
- (void)onChatSmallTongueClick:(TUIChatSmallTongue_Minimalist *)tongue {
    switch (tongue.type) {
        case TUIChatSmallTongueType_ScrollToBoom: {
            @weakify(self)
            [self.messageDataProvider getLastMessage:YES succ:^(V2TIMMessage * _Nonnull message) {
                @strongify(self)
                if (!message) return;
                self.locateMessage = message;
                for (TUIMessageCellData *cellData in self.messageDataProvider.uiMsgs) {
                    if ([self isLocateMessage:cellData]) {
                        [self scrollToLocateMessage:YES];
                        return;
                    }
                }
                [self loadAndScrollToLocateMessages:YES isHighlight:NO];
            } fail:^(int code, NSString *desc) {
                NSLog(@"getLastMessage failed");
            }];
        } break;
        case TUIChatSmallTongueType_ReceiveNewMsg: {
            [TUIChatSmallTongueManager_Minimalist removeTongue:TUIChatSmallTongueType_ReceiveNewMsg];
            TUIMessageCellData *cellData = self.receiveMsgs.firstObject;
            if (cellData) {
                self.locateMessage = cellData.innerMessage;
                [self scrollToLocateMessage:YES];
                [self highlightKeyword];
            }
            [self.receiveMsgs removeAllObjects];
        } break;
        case TUIChatSmallTongueType_SomeoneAt: {
            [TUIChatSmallTongueManager_Minimalist removeTongue:TUIChatSmallTongueType_SomeoneAt];
            [self.conversationData.atMsgSeqs removeAllObjects];
            ;
            self.locateGroupMessageSeq = [tongue.atMsgSeqs.firstObject integerValue];
            for (TUIMessageCellData *cellData in self.messageDataProvider.uiMsgs) {
                if ([self isLocateMessage:cellData]) {
                    [self scrollToLocateMessage:YES];
                    [self highlightKeyword];
                    return;
                }
            }
            [self loadAndScrollToLocateMessages:YES isHighlight:YES];
        } break;
        default:
            break;
    }
}

@end
