//
//  TUIImageMessageCellData.m
//  TXIMSDK_TUIKit_iOS
//
//  Created by annidyfeng on 2019/5/21.
//  Copyright © 2023 Tencent. All rights reserved.
//

#import "TUIImageMessageCellData.h"
#import <TIMCommon/TIMDefine.h>
#import <TUICore/NSString+TUIUtil.h>

@interface TUIImageMessageCellData ()
@property(nonatomic, assign) BOOL isDownloading;
@property(nonatomic, copy) TUIImageMessageDownloadCallback onFinish;
@end

@implementation TUIImageMessageCellData

+ (TUIMessageCellData *)getCellData:(V2TIMMessage *)message {
    V2TIMImageElem *elem = message.imageElem;
    TUIImageMessageCellData *imageData = [[TUIImageMessageCellData alloc] initWithDirection:(message.isSelf ? MsgDirectionOutgoing : MsgDirectionIncoming)];
    imageData.path = [elem.path safePathString];
    imageData.items = [NSMutableArray array];
    for (V2TIMImage *item in elem.imageList) {
        TUIImageItem *itemData = [[TUIImageItem alloc] init];
        itemData.uuid = item.uuid;
        itemData.size = CGSizeMake(item.width, item.height);
        //        itemData.url = item.url;
        if (item.type == V2TIM_IMAGE_TYPE_THUMB) {
            itemData.type = TImage_Type_Thumb;
        } else if (item.type == V2TIM_IMAGE_TYPE_LARGE) {
            itemData.type = TImage_Type_Large;
        } else if (item.type == V2TIM_IMAGE_TYPE_ORIGIN) {
            itemData.type = TImage_Type_Origin;
        }
        [imageData.items addObject:itemData];
    }
    imageData.reuseId = TImageMessageCell_ReuseId;
    return imageData;
}

+ (NSString *)getDisplayString:(V2TIMMessage *)message {
    return TIMCommonLocalizableString(TUIkitMessageTypeImage);  // @"[Image]";
}

- (Class)getReplyQuoteViewDataClass {
    return NSClassFromString(@"TUIImageReplyQuoteViewData");
}

- (Class)getReplyQuoteViewClass {
    return NSClassFromString(@"TUIImageReplyQuoteView");
}

- (instancetype)initWithDirection:(TMsgDirection)direction {
    self = [super initWithDirection:direction];
    if (self) {
        _uploadProgress = 100;
        if (direction == MsgDirectionIncoming) {
            self.cellLayout = [TUIMessageCellLayout incommingImageMessageLayout];
        } else {
            self.cellLayout = [TUIMessageCellLayout outgoingImageMessageLayout];
        }
    }
    return self;
}

- (NSString *)getImagePath:(TUIImageType)type isExist:(BOOL *)isExist {
    NSString *path = nil;
    BOOL isDir = NO;
    *isExist = NO;
    if (self.direction == MsgDirectionOutgoing) {
        path = [NSString stringWithFormat:@"%@%@", TUIKit_Image_Path, _path.lastPathComponent];
        if ([[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:&isDir]) {
            if (!isDir) {
                *isExist = YES;
            }
        }
    }

    if (!*isExist) {
        TUIImageItem *tImageItem = [self getTImageItem:type];
        path = [NSString stringWithFormat:@"%@%@_%ld", TUIKit_Image_Path, tImageItem.uuid, (long)tImageItem.type];
        if ([[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:&isDir]) {
            if (!isDir) {
                *isExist = YES;
            }
        }
    }

    return path;
}

- (void)downloadImage:(TUIImageType)type finish:(TUIImageMessageDownloadCallback)finish {
    self.onFinish = finish;
    [self downloadImage:type];
}

- (void)downloadImage:(TUIImageType)type {
    BOOL isExist = NO;
    NSString *path = [self getImagePath:type isExist:&isExist];
    if (isExist) {
        [self decodeImage:type];
        return;
    }

    if (self.isDownloading) {
        return;
    }
    self.isDownloading = YES;

    V2TIMImage *imImage = [self getIMImage:type];

    @weakify(self);
    [imImage downloadImage:path
        progress:^(NSInteger curSize, NSInteger totalSize) {
          @strongify(self);
          NSInteger progress = curSize * 100 / totalSize;
          [self updateProgress:MIN(progress, 99) withType:type];
        }
        succ:^{
          @strongify(self);
          self.isDownloading = NO;
          [self updateProgress:100 withType:type];
          [self decodeImage:type];
        }
        fail:^(int code, NSString *msg) {
          @strongify(self);
          self.isDownloading = NO;
          /**
           * If the uuid of the picture is the same (the same user sends
           * the same picture continuously), the same path may trigger multiple download operations. Except for the first time, subsequent downloads will report
           * an error. At this time, it is necessary to judge whether the local file exists.
           */
          [self decodeImage:type];
        }];
}

- (void)updateProgress:(NSUInteger)progress withType:(TUIImageType)type {
    dispatch_async(dispatch_get_main_queue(), ^{
      if (type == TImage_Type_Thumb) self.thumbProgress = progress;
      if (type == TImage_Type_Large) self.largeProgress = progress;
      if (type == TImage_Type_Origin) self.originProgress = progress;
    });
}

- (void)decodeImage:(TUIImageType)type {
    BOOL isExist = NO;
    NSString *path = [self getImagePath:type isExist:&isExist];
    if (!isExist) {
        return;
    }

    __weak typeof(self) weakSelf = self;
    void (^finishBlock)(UIImage *) = ^(UIImage *image) {
      if (type == TImage_Type_Thumb) {
          weakSelf.thumbImage = image;
          weakSelf.thumbProgress = 100;
          weakSelf.uploadProgress = 100;
      }
      if (type == TImage_Type_Large) {
          weakSelf.largeImage = image;
          weakSelf.largeProgress = 100;
      }
      if (type == TImage_Type_Origin) {
          weakSelf.originImage = image;
          weakSelf.originProgress = 100;
      }
      if (weakSelf.onFinish) {
          weakSelf.onFinish();
      }
    };

    NSString *cacheKey = [path substringFromIndex:TUIKit_Image_Path.length];

    UIImage *cacheImage = [[SDImageCache sharedImageCache] imageFromCacheForKey:cacheKey];
    if (cacheImage) {
        finishBlock(cacheImage);
    } else {
        [TUITool asyncDecodeImage:path
                         complete:^(NSString *path, UIImage *image) {
                           dispatch_async(dispatch_get_main_queue(), ^{
                               NSLog(@"image.sd_imageFormat: %ld path:%@ image.sd_imageData.length :%lu",(long)image.sd_imageFormat,path,(unsigned long)image.sd_imageData.length);
                             if (![path tui_containsString:@".gif"] || (image.sd_imageFormat != SDImageFormatGIF) ) {
                                     [[SDImageCache sharedImageCache] storeImageToMemory:image forKey:cacheKey];
                             }
                             else {
                                 /**
                                  * The gif image is too large to be cached in memory
                                  * Only cache images less than 1M
                                  */
                                 if (image.sd_imageData.length < 1 * 1024 * 1024) {
                                     [[SDImageCache sharedImageCache] storeImageToMemory:image forKey:cacheKey];
                                 }
                             }
                             finishBlock(image);
                           });
                         }];
    }
}

- (TUIImageItem *)getTImageItem:(TUIImageType)type {
    for (TUIImageItem *item in self.items) {
        if (item.type == type) {
            return item;
        }
    }
    return nil;
}

- (V2TIMImage *)getIMImage:(TUIImageType)type {
    V2TIMMessage *imMsg = self.innerMessage;
    if (imMsg.elemType == V2TIM_ELEM_TYPE_IMAGE) {
        for (V2TIMImage *imImage in imMsg.imageElem.imageList) {
            if (type == TImage_Type_Thumb && imImage.type == V2TIM_IMAGE_TYPE_THUMB) {
                return imImage;
            } else if (type == TImage_Type_Origin && imImage.type == V2TIM_IMAGE_TYPE_ORIGIN) {
                return imImage;
            } else if (type == TImage_Type_Large && imImage.type == V2TIM_IMAGE_TYPE_LARGE) {
                return imImage;
            }
        }
    }
    return nil;
}

@end
