#import "FFFastImageView.h"
#import <YYWebImage/YYWebImage.h>

@implementation FFFastImageView {
    BOOL hasSentOnLoadStart;
    BOOL hasCompleted;
    BOOL hasErrored;
    NSDictionary* onLoadEvent;
}

- (id) init {
    self = [super init];
    self.resizeMode = RCTResizeModeCover;
    self.clipsToBounds = YES;
    return self;
}

- (void)setResizeMode:(RCTResizeMode)resizeMode
{
    if (_resizeMode != resizeMode) {
        _resizeMode = resizeMode;
        self.contentMode = (UIViewContentMode)resizeMode;
    }
}

- (void)setOnFastImageLoadEnd:(RCTBubblingEventBlock)onFastImageLoadEnd {
    _onFastImageLoadEnd = onFastImageLoadEnd;
    if (hasCompleted) {
        _onFastImageLoadEnd(@{});
    }
}

- (void)setOnFastImageLoad:(RCTBubblingEventBlock)onFastImageLoad {
    _onFastImageLoad = onFastImageLoad;
    if (hasCompleted) {
        _onFastImageLoad(onLoadEvent);
    }
}

- (void)setOnFastImageError:(RCTDirectEventBlock)onFastImageError {
    _onFastImageError = onFastImageError;
    if (hasErrored) {
        _onFastImageError(@{});
    }
}

- (void)setOnFastImageLoadStart:(RCTBubblingEventBlock)onFastImageLoadStart {
    if (_source && !hasSentOnLoadStart) {
        _onFastImageLoadStart = onFastImageLoadStart;
        onFastImageLoadStart(@{});
        hasSentOnLoadStart = YES;
    } else {
        _onFastImageLoadStart = onFastImageLoadStart;
        hasSentOnLoadStart = NO;
    }
}

- (void)setSource:(FFFastImageSource *)source {
    if (_source != source) {
        _source = source;
        
        if (_onFastImageLoadStart) {
            _onFastImageLoadStart(@{});
            hasSentOnLoadStart = YES;
        } else {
            hasSentOnLoadStart = NO;
        }
        hasCompleted = NO;
        hasErrored = NO;
        
        [self yy_setImageWithURL:_source.uri
                     placeholder:nil
                         options:YYWebImageOptionSetImageWithFadeAnimation
                        progress:^(NSInteger receivedSize, NSInteger expectedSize) {
                            if (_onFastImageProgress) {
                                _onFastImageProgress(@{@"loaded": @(receivedSize), @"total": @(expectedSize)});
                            }
                        }
                       transform:nil
                      completion:^(UIImage *image, NSURL *url, YYWebImageFromType from, YYWebImageStage stage, NSError *error) {
                          if (stage == YYWebImageStageFinished) {
                              if (error) {
                                  hasErrored = YES;
                                  if (_onFastImageError) {
                                      _onFastImageError(@{@"error": error.description});
                                  }
                              } else {
                                  hasCompleted = YES;
                                  NSDictionary *dict = @{
                                                         @"width": @(image.size.width),
                                                         @"height": @(image.size.height),
                                                         @"url": url.absoluteString,
                                                         };
                                  onLoadEvent = @{ @"source": dict };
                                  
                                  if (_onFastImageLoad) {
                                      _onFastImageLoad(onLoadEvent);
                                  }
                              }
                          }
                          
                          if (_onFastImageLoadEnd) {
                              _onFastImageLoadEnd(@{});
                          }
                      }
         ];
    }
}

@end

