//
//  TUIVideoMessageCell.m
//  UIKit
//
//  Created by annidyfeng on 2019/5/30.
//  Copyright © 2023 Tencent. All rights reserved.
//

#import "TUIVideoMessageCell.h"
#import <TIMCommon/TIMDefine.h>
#import "TUICircleLodingView.h"
#import "TUIMessageProgressManager.h"

@interface TUIVideoMessageCell () <TUIMessageProgressManagerDelegate>

@property(nonatomic, strong) UIView *animateHighlightView;

@property(nonatomic, strong) TUICircleLodingView *animateCircleView;

@property(nonatomic, strong) UIImageView *downloadImage;

@end

@implementation TUIVideoMessageCell

- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        _thumb = [[UIImageView alloc] init];
        _thumb.layer.cornerRadius = 5.0;
        [_thumb.layer setMasksToBounds:YES];
        _thumb.contentMode = UIViewContentModeScaleAspectFill;
        _thumb.backgroundColor = [UIColor clearColor];
        [self.bubbleView addSubview:_thumb];
        _thumb.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

        CGSize playSize = TVideoMessageCell_Play_Size;
        _play = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, playSize.width, playSize.height)];
        _play.contentMode = UIViewContentModeScaleAspectFit;
        _play.image = [[TUIImageCache sharedInstance] getResourceFromCache:TUIChatImagePath(@"play_normal")];
        _play.hidden = YES;
        [_thumb addSubview:_play];

        _downloadImage = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, playSize.width, playSize.height)];
        _downloadImage.contentMode = UIViewContentModeScaleAspectFit;
        _downloadImage.image = [[TUIImageCache sharedInstance] getResourceFromCache:TUIChatImagePath(@"download")];
        _downloadImage.hidden = YES;
        [_thumb addSubview:_downloadImage];

        _duration = [[UILabel alloc] init];
        _duration.textColor = [UIColor whiteColor];
        _duration.font = [UIFont systemFontOfSize:12];
        [_thumb addSubview:_duration];

        _animateCircleView = [[TUICircleLodingView alloc] initWithFrame:CGRectMake(0, 0, kScale390(40), kScale390(40))];
        _animateCircleView.progress = 0;
        [_thumb addSubview:_animateCircleView];
    
        _progress = [[UILabel alloc] init];
        _progress.textColor = [UIColor whiteColor];
        _progress.font = [UIFont systemFontOfSize:15];
        _progress.textAlignment = NSTextAlignmentCenter;
        _progress.layer.cornerRadius = 5.0;
        _progress.hidden = YES;
        _progress.backgroundColor = TVideoMessageCell_Progress_Color;
        [_progress.layer setMasksToBounds:YES];
        [self.container addSubview:_progress];
        _progress.mm_fill();
        _progress.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
        [TUIMessageProgressManager.shareManager addDelegate:self];
    }
    return self;
}

- (void)fillWithData:(TUIVideoMessageCellData *)data;
{
    // set data
    [super fillWithData:data];
    self.videoData = data;
    _thumb.image = nil;
    
    BOOL hasRiskContent = self.messageData.innerMessage.hasRiskContent;
    if (hasRiskContent) {
        self.thumb.image = TIMCommonBundleThemeImage(@"", @"icon_security_strike");
        self.securityStrikeView.textLabel.text = TIMCommonLocalizableString(TUIKitMessageTypeSecurityStrikeImage);
        self.duration.text = @"";
        self.play.hidden = YES;
        self.downloadImage.hidden = YES;
        self.indicator.hidden = YES;
        self.animateCircleView.hidden = YES;
        return;
    }
    if (data.thumbImage == nil) {
        [data downloadThumb];
    }
    if (data.isPlaceHolderCellData) {
        //show placeHolder
        _thumb.backgroundColor = [UIColor grayColor];
        _animateCircleView.progress = (data.videoTranscodingProgress *100);
        self.duration.text = @"";
        self.play.hidden = YES;
        self.downloadImage.hidden = YES;
        self.indicator.hidden = YES;
        self.animateCircleView.hidden = NO;
        @weakify(self);
        [[RACObserve(data, videoTranscodingProgress) takeUntil:self.rac_prepareForReuseSignal] subscribeNext:^(NSNumber *x) {
            // The transcoded animation can display up to 30% at maximum,
            // and the upload progress increases from 30% to 100%.
            @strongify(self);
            double progress = [x doubleValue];
            double factor  = 0.3;
            double resultProgress = (progress *100) * factor;
            self.animateCircleView.progress = resultProgress;
        }];
        if (data.thumbImage) {
            self.thumb.image = data.thumbImage;
        }
        // tell constraints they need updating
        [self setNeedsUpdateConstraints];

        // update constraints now so we can animate the change
        [self updateConstraintsIfNeeded];

        [self layoutIfNeeded];

        return;
    }

    @weakify(self);
    [[RACObserve(data, thumbImage) takeUntil:self.rac_prepareForReuseSignal] subscribeNext:^(UIImage *thumbImage) {
      @strongify(self);
      if (thumbImage) {
          self.thumb.image = thumbImage;
      }
    }];

    _duration.text = [NSString stringWithFormat:@"%02ld:%02ld", (long)data.videoItem.duration / 60, (long)data.videoItem.duration % 60];

    self.play.hidden = YES;
    self.downloadImage.hidden = YES;
    self.indicator.hidden = YES;
    if (data.direction == MsgDirectionIncoming) {
        [[[RACObserve(data, thumbProgress) takeUntil:self.rac_prepareForReuseSignal] distinctUntilChanged] subscribeNext:^(NSNumber *x) {
          @strongify(self);
          // Cover download progress callback
          int progress = [x intValue];
          self.progress.text = [NSString stringWithFormat:@"%d%%", progress];
          self.progress.hidden = (progress >= 100 || progress == 0);
          self.animateCircleView.progress = progress;
          if (progress >= 100 || progress == 0) {
              // The progress of cover download is called back and the download video icon is displayed when the cover progress is 100.
              if ([data isVideoExist]) {
                  self.play.hidden = NO;
              } else {
                  self.downloadImage.hidden = NO;
              }
          } else {
              self.play.hidden = YES;
              self.downloadImage.hidden = YES;
          }
        }];

        // Video resource download progress callback
        [[[RACObserve(data, videoProgress) takeUntil:self.rac_prepareForReuseSignal] distinctUntilChanged] subscribeNext:^(NSNumber *x) {
          @strongify(self);
          int progress = [x intValue];
          self.animateCircleView.progress = progress;
          if (progress >= 100 || progress == 0) {
              self.play.hidden = NO;
              self.animateCircleView.hidden = YES;
          } else {
              self.play.hidden = YES;
              self.downloadImage.hidden = YES;
              self.animateCircleView.hidden = NO;
          }
        }];

    } else {
        if ([data isVideoExist]) {
            [[[RACObserve(data, uploadProgress) takeUntil:self.rac_prepareForReuseSignal] distinctUntilChanged] subscribeNext:^(NSNumber *x) {
              @strongify(self);
              int progress = [x intValue];
              if (data.placeHolderCellData.videoTranscodingProgress > 0) {
                  progress = MAX(progress, 30);//the upload progress increases from 30% to 100%.
              }
              self.animateCircleView.progress = progress;
              if (progress >= 100 || progress == 0) {
                  [self.indicator stopAnimating];
                  self.play.hidden = NO;
                  self.animateCircleView.hidden = YES;
              } else {
                  [self.indicator startAnimating];
                  self.play.hidden = YES;
                  self.animateCircleView.hidden = NO;
              }
            }];

        } else {
            [[[RACObserve(data, thumbProgress) takeUntil:self.rac_prepareForReuseSignal] distinctUntilChanged] subscribeNext:^(NSNumber *x) {
              @strongify(self);
              // Cover download progress callback
              int progress = [x intValue];
              self.progress.text = [NSString stringWithFormat:@"%d%%", progress];
              self.progress.hidden = (progress >= 100 || progress == 0);
              self.animateCircleView.progress = progress;
              if (progress >= 100 || progress == 0) {
                  // The download video icon is displayed when the cover progress reaches 100
                  if ([data isVideoExist]) {
                      self.play.hidden = NO;
                  } else {
                      self.downloadImage.hidden = NO;
                  }
              } else {
                  self.play.hidden = YES;
                  self.downloadImage.hidden = YES;
              }
            }];

            // Video resource download progress callback
            [[[RACObserve(data, videoProgress) takeUntil:self.rac_prepareForReuseSignal] distinctUntilChanged] subscribeNext:^(NSNumber *x) {
              @strongify(self);
              int progress = [x intValue];
              self.animateCircleView.progress = progress;
              if (progress >= 100 || progress == 0) {
                  self.play.hidden = NO;
                  self.animateCircleView.hidden = YES;
              } else {
                  self.play.hidden = YES;
                  self.downloadImage.hidden = YES;
                  self.animateCircleView.hidden = NO;
              }
            }];
        }
    }
    // tell constraints they need updating
    [self setNeedsUpdateConstraints];

    // update constraints now so we can animate the change
    [self updateConstraintsIfNeeded];

    [self layoutIfNeeded];

}

+ (BOOL)requiresConstraintBasedLayout {
    return YES;
}

// this is Apple's recommended place for adding/updating constraints
- (void)updateConstraints {

    [super updateConstraints];
    if (self.messageData.messageContainerAppendSize.height > 0) {
        CGFloat topMargin = 10;
        CGFloat tagViewTopMargin = 6;
        CGFloat thumbHeight = self.bubbleView.mm_h - topMargin - self.messageData.messageContainerAppendSize.height - tagViewTopMargin;
        CGSize size = [self.class getContentSize:self.messageData];
        [self.thumb mas_remakeConstraints:^(MASConstraintMaker *make) {
            make.height.mas_equalTo(thumbHeight);
            make.width.mas_equalTo(size.width);
            make.centerX.mas_equalTo(self.bubbleView);
            make.top.mas_equalTo(self.container).mas_offset(topMargin);
        }];
        [self.duration mas_remakeConstraints:^(MASConstraintMaker *make) {
            make.trailing.mas_equalTo(self.thumb.mas_trailing).mas_offset(-2);
            make.width.mas_greaterThanOrEqualTo(20);
            make.height.mas_equalTo(20);
            make.bottom.mas_equalTo(self.thumb.mas_bottom);
        }];
    } else {
        [self.thumb mas_remakeConstraints:^(MASConstraintMaker *make) {
            make.top.mas_equalTo(self.bubbleView).mas_offset(self.messageData.cellLayout.bubbleInsets.top);
            make.bottom.mas_equalTo(self.bubbleView).mas_offset(- self.messageData.cellLayout.bubbleInsets.bottom);
            make.leading.mas_equalTo(self.bubbleView).mas_offset(self.messageData.cellLayout.bubbleInsets.left);
            make.trailing.mas_equalTo(self.bubbleView).mas_offset(- self.messageData.cellLayout.bubbleInsets.right);
        }];
        [self.duration mas_remakeConstraints:^(MASConstraintMaker *make) {
            make.trailing.mas_equalTo(self.thumb.mas_trailing).mas_offset(-2);
            make.width.mas_greaterThanOrEqualTo(20);
            make.height.mas_equalTo(20);
            make.bottom.mas_equalTo(self.thumb.mas_bottom);
        }];
    }
    
    
    BOOL hasRiskContent = self.messageData.innerMessage.hasRiskContent;
    if (hasRiskContent ) {
        [self.thumb mas_remakeConstraints:^(MASConstraintMaker *make) {
            make.top.mas_equalTo(self.bubbleView).mas_offset(12);
            make.size.mas_equalTo(CGSizeMake(150, 150));
            make.centerX.mas_equalTo(self.bubbleView);
        }];
        
        [self.securityStrikeView mas_remakeConstraints:^(MASConstraintMaker *make) {
            make.top.mas_equalTo(self.thumb.mas_bottom);
            make.width.mas_equalTo(self.bubbleView);
            if(self.messageData.messageContainerAppendSize.height>0) {
                make.bottom.mas_equalTo(self.container).mas_offset(-self.messageData.messageContainerAppendSize.height);
            }
            else {
                make.bottom.mas_equalTo(self.container).mas_offset(-12);
            }
        }];
    }

    [self.play mas_remakeConstraints:^(MASConstraintMaker *make) {
        make.size.mas_equalTo(TVideoMessageCell_Play_Size);
        make.center.mas_equalTo(self.thumb);
    }];
    [self.downloadImage mas_remakeConstraints:^(MASConstraintMaker *make) {
        make.size.mas_equalTo(TVideoMessageCell_Play_Size);
        make.center.mas_equalTo(self.thumb);
    }];

    [self.animateCircleView mas_remakeConstraints:^(MASConstraintMaker *make) {
        make.center.mas_equalTo(self.thumb);
        make.size.mas_equalTo(CGSizeMake(kScale390(40), kScale390(40)));
    }];
}

- (void)layoutSubviews {
    [super layoutSubviews];
}

- (void)highlightWhenMatchKeyword:(NSString *)keyword {
    if (keyword) {
        if (self.highlightAnimating) {
            return;
        }
        [self animate:3];
    }
}

- (void)animate:(int)times {
    times--;
    if (times < 0) {
        [self.animateHighlightView removeFromSuperview];
        self.highlightAnimating = NO;
        return;
    }
    self.highlightAnimating = YES;
    self.animateHighlightView.frame = self.container.bounds;
    self.animateHighlightView.alpha = 0.1;
    [self.container addSubview:self.animateHighlightView];
    [UIView animateWithDuration:0.25
        animations:^{
          self.animateHighlightView.alpha = 0.5;
        }
        completion:^(BOOL finished) {
          [UIView animateWithDuration:0.25
              animations:^{
                self.animateHighlightView.alpha = 0.1;
              }
              completion:^(BOOL finished) {
                if (!self.videoData.highlightKeyword) {
                    [self animate:0];
                    return;
                }
                [self animate:times];
              }];
        }];
}

- (UIView *)animateHighlightView {
    if (_animateHighlightView == nil) {
        _animateHighlightView = [[UIView alloc] init];
        _animateHighlightView.backgroundColor = [UIColor orangeColor];
    }
    return _animateHighlightView;
}

#pragma mark - TUIMessageProgressManagerDelegate
- (void)onUploadProgress:(NSString *)msgID progress:(NSInteger)progress {
    if (![msgID isEqualToString:self.videoData.msgID]) {
        return;
    }
    if (self.videoData.direction == MsgDirectionOutgoing) {
        self.videoData.uploadProgress = progress;
    }
}

#pragma mark - TUIMessageCellProtocol
+ (CGSize)getContentSize:(TUIMessageCellData *)data {
    NSAssert([data isKindOfClass:TUIVideoMessageCellData.class], @"data must be kind of TUIVideoMessageCellData");
    TUIVideoMessageCellData *videoCellData = (TUIVideoMessageCellData *)data;
    CGSize size = CGSizeZero;
    BOOL isDir = NO;
    if (![videoCellData.snapshotPath isEqualToString:@""] && [[NSFileManager defaultManager] fileExistsAtPath:videoCellData.snapshotPath isDirectory:&isDir]) {
        if (!isDir) {
            size = [UIImage imageWithContentsOfFile:videoCellData.snapshotPath].size;
        }
    } else {
        size = videoCellData.snapshotItem.size;
    }
    if (CGSizeEqualToSize(size, CGSizeZero)) {
        return size;
    }
    if (size.height > size.width) {
        size.width = size.width / size.height * TVideoMessageCell_Image_Height_Max;
        size.height = TVideoMessageCell_Image_Height_Max;
    } else {
        size.height = size.height / size.width * TVideoMessageCell_Image_Width_Max;
        size.width = TVideoMessageCell_Image_Width_Max;
    }
    BOOL hasRiskContent = videoCellData.innerMessage.hasRiskContent;
    if (hasRiskContent) {
        CGFloat bubbleTopMargin = 12;
        CGFloat bubbleBottomMargin = 12;
        size.height = MAX(size.height, 150);// width must more than  TIMCommonBundleThemeImage(@"", @"icon_security_strike");
        size.width = MAX(size.width, 200);// width must more than  TIMCommonLocalizableString(TUIKitMessageTypeSecurityStrike)
        size.height += bubbleTopMargin;
        size.height += kTUISecurityStrikeViewTopLineMargin;
        size.height += kTUISecurityStrikeViewTopLineToBottom;
        size.height += bubbleBottomMargin;
    }
    return size;
}

@end
