
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

#import "WXRecyclerComponent.h"
#import "WXComponent_internal.h"
#import "WXSDKInstance_private.h"
#import "WXRecyclerDataController.h"
#import "WXRecyclerUpdateController.h"
#import "WXMultiColumnLayout.h"
#import "WXHeaderComponent.h"
#import "WXFooterComponent.h"
#import "WXCellComponent.h"
#import "WXAssert.h"
#import "WXConvert.h"
#import "WXUtility.h"
#import "WXMonitor.h"
#import "NSObject+WXSwizzle.h"
#import "WXComponent+Events.h"
#import "WXRecyclerDragController.h"
#import "WXComponent+Layout.h"

static NSString * const kCollectionCellReuseIdentifier = @"WXRecyclerCell";
static NSString * const kCollectionHeaderReuseIdentifier = @"WXRecyclerHeader";
static float const kRecyclerNormalColumnGap = 32;

typedef enum : NSUInteger {
    WXRecyclerLayoutTypeMultiColumn,
    WXRecyclerLayoutTypeFlex,
    WXRecyclerLayoutTypeGrid,
} WXRecyclerLayoutType;

@interface WXCollectionView : UICollectionView

@end

@implementation WXCollectionView

- (void)dealloc
{
    self.delegate = nil;
    self.dataSource = nil;
    if ([self.collectionViewLayout isKindOfClass:[WXMultiColumnLayout class]]) {
        WXMultiColumnLayout* wxLayout = (WXMultiColumnLayout *)self.collectionViewLayout;
        wxLayout.weak_collectionView = nil;
    }
}

- (void)insertSubview:(UIView *)view atIndex:(NSInteger)index
{
    [super insertSubview:view atIndex:index];
}

- (void)layoutSubviews
{
    [super layoutSubviews];
    [self.wx_component layoutDidFinish];
}

- (void)setContentOffset:(CGPoint)contentOffset
{
    // FIXME: side effect caused by hooking _adjustContentOffsetIfNecessary.
    // When UICollectionView is pulled down and finger releases，contentOffset will be set from -xxxx to about -0.5(greater than -0.5), then contentOffset will be reset to zero by calling _adjustContentOffsetIfNecessary.
    // So hooking _adjustContentOffsetIfNecessary will always cause remaining 1px space between list's top and navigator.
    // Demo: http://dotwe.org/895630945793a9a044e49abe39cbb77f
    // Have to reset contentOffset to zero manually here.
    if (fabs(contentOffset.y) < 0.5) {
        contentOffset.y = 0;
    }
    if (isnan(contentOffset.x)) {
        contentOffset.x = 0;
    }
    if(isnan(contentOffset.y)) {
        contentOffset.y = 0;
    }
    
    [super setContentOffset:contentOffset];
}

@end

@interface WXCollectionViewCell : UICollectionViewCell

@end

@implementation WXCollectionViewCell

- (void)prepareForReuse
{
    [super prepareForReuse];
    
    WXCellComponent *cellComponent = (WXCellComponent *)self.wx_component;
    if (cellComponent.isRecycle && [cellComponent isViewLoaded] && [self.contentView.subviews containsObject:cellComponent.view]) {
        [cellComponent _unloadViewWithReusing:YES];
    }
}

@end

@interface WXRecyclerComponent () <UICollectionViewDataSource, UICollectionViewDelegate, WXMultiColumnLayoutDelegate, WXRecyclerUpdateControllerDelegate, WXCellRenderDelegate, WXHeaderRenderDelegate, WXRecyclerDragControllerDelegate>

@property (nonatomic, strong, readonly) WXRecyclerDataController *dataController;
@property (nonatomic, strong, readonly) WXRecyclerUpdateController *updateController;
@property (nonatomic, weak, readonly) UICollectionView *collectionView;
@property (nonatomic, strong) WXRecyclerDragController *dragController;

@end

@implementation WXRecyclerComponent
{
    WXRecyclerLayoutType _layoutType;
    UICollectionViewLayout *_collectionViewlayout;
    
    UIEdgeInsets _padding;
    NSUInteger _previousLoadMoreCellNumber;
}

- (instancetype)initWithRef:(NSString *)ref type:(NSString *)type styles:(NSDictionary *)styles attributes:(NSDictionary *)attributes events:(NSArray *)events weexInstance:(WXSDKInstance *)weexInstance
{
    if (self = [super initWithRef:ref type:type styles:styles attributes:attributes events:events weexInstance:weexInstance]) {
        [self _fillPadding];
        
        if ([type isEqualToString:@"waterfall"] || (attributes[@"layout"] && [attributes[@"layout"] isEqualToString:@"multi-column"])) {
            // TODO: abstraction
            _layoutType = WXRecyclerLayoutTypeMultiColumn;
            CGFloat scaleFactor = weexInstance.pixelScaleFactor;
            _collectionViewlayout = [WXMultiColumnLayout new];
            WXMultiColumnLayout *layout = (WXMultiColumnLayout *)_collectionViewlayout;
            layout.columnWidth = [WXConvert WXLength:attributes[@"columnWidth"] isFloat:YES scaleFactor:scaleFactor] ? : [WXLength lengthWithFloat:0.0 type:WXLengthTypeAuto];
            layout.columnCount = [WXConvert WXLength:attributes[@"columnCount"] isFloat:NO scaleFactor:1.0] ? : [WXLength lengthWithInt:1 type:WXLengthTypeFixed];
            if (attributes[@"leftGap"]) {
                layout.leftGap = [WXConvert WXPixelType:attributes[@"leftGap"] scaleFactor:scaleFactor];
            }
            if (attributes[@"rightGap"]) {
                layout.rightGap = [WXConvert WXPixelType:attributes[@"rightGap"] scaleFactor:scaleFactor];
            }
            layout.columnGap = [self _floatValueForColumnGap:([WXConvert WXLength:attributes[@"columnGap"] isFloat:YES scaleFactor:scaleFactor] ? : [WXLength lengthWithFloat:0.0 type:WXLengthTypeNormal])];
            
            layout.delegate = self;
        } else {
            _collectionViewlayout = [UICollectionViewLayout new];
        }
        
        _dataController = [WXRecyclerDataController new];
        _updateController = [WXRecyclerUpdateController new];
        _updateController.delegate = self;
        [self fixFlicker];
        
        if ([attributes[@"draggable"] boolValue]) {
            // lazy load
            _dragController = [WXRecyclerDragController new];
            _dragController.delegate = self;
            if([attributes[@"dragTriggerType"]  isEqual: @"pan"]){
                _dragController.dragTriggerType = WXRecyclerDragTriggerPan;
            }
            _dragController.isDragable = YES;
        }
    }
    
    return self;
}

- (void)dealloc
{
    _collectionView.delegate = nil;
    _collectionView.dataSource = nil;
    if ([_collectionViewlayout isKindOfClass:[WXMultiColumnLayout class]]) {
        WXMultiColumnLayout* wxLayout = (WXMultiColumnLayout *)_collectionViewlayout;
        wxLayout.weak_collectionView = nil;
    }
}

#pragma mark - Public Subclass Methods

- (UIView *)loadView
{
    return [[WXCollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:_collectionViewlayout];
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    _collectionView = (UICollectionView *)self.view;
    _collectionView.allowsSelection = NO;
    _collectionView.allowsMultipleSelection = NO;
    _collectionView.dataSource = self;
    _collectionView.delegate = self;
    if ([_collectionViewlayout isKindOfClass:[WXMultiColumnLayout class]]) {
        WXMultiColumnLayout* wxLayout = (WXMultiColumnLayout *)_collectionViewlayout;
        wxLayout.weak_collectionView = _collectionView;
    }
    [_collectionView registerClass:[WXCollectionViewCell class] forCellWithReuseIdentifier:kCollectionCellReuseIdentifier];
    [_collectionView registerClass:[UICollectionReusableView class] forSupplementaryViewOfKind:kCollectionSupplementaryViewKindHeader withReuseIdentifier:kCollectionHeaderReuseIdentifier];
    
    _dragController.dragingCell = [[WXCollectionViewCell alloc] initWithFrame:CGRectMake(0, 0, 100, 100/2.0f)];
    _dragController.collectionView = _collectionView;
    
    [self performUpdatesWithCompletion:^(BOOL finished) {
        
    }];
}

- (void)viewWillUnload
{
    [super viewWillUnload];
    
    _collectionView.dataSource = nil;
    _collectionView.delegate = nil;
    if ([_collectionViewlayout isKindOfClass:[WXMultiColumnLayout class]]) {
        WXMultiColumnLayout* wxLayout = (WXMultiColumnLayout *)_collectionViewlayout;
        wxLayout.weak_collectionView = nil;
    }
}

- (void)updateAttributes:(NSDictionary *)attributes
{
    [super updateAttributes:attributes];
    
    if (_layoutType == WXRecyclerLayoutTypeMultiColumn) {
        CGFloat scaleFactor = self.weexInstance.pixelScaleFactor;
        WXMultiColumnLayout *layout = (WXMultiColumnLayout *)_collectionViewlayout;
        BOOL needUpdateLayout = NO;
        
        if ([attributes[@"draggable"] boolValue]) {
            if (!_dragController) {  // lazy load
                _dragController = [WXRecyclerDragController new];
                _dragController.delegate = self;
            }
            if([attributes[@"dragTriggerType"]  isEqual: @"pan"]){
                _dragController.dragTriggerType = WXRecyclerDragTriggerPan;
            }
            _dragController.isDragable = YES;
        } else {
            _dragController.isDragable = NO;
        }
        
        if (attributes[@"columnWidth"]) {
            WXLength* columnWidth = [WXConvert WXLength:attributes[@"columnWidth"] isFloat:YES scaleFactor:scaleFactor];
            if (![columnWidth isEqualToLength:layout.columnWidth]) {
                layout.columnWidth = columnWidth;
                needUpdateLayout = YES;
            }
        }
        
        if (attributes[@"columnCount"]) {
            WXLength* columCount = [WXConvert WXLength:attributes[@"columnCount"] isFloat:NO scaleFactor:1.0];
            if (![columCount isEqualToLength:layout.columnCount]) {
                layout.columnCount = columCount;
                needUpdateLayout = YES;
            }
        }
        if (attributes[@"columnGap"]) {
            float columnGap = [self _floatValueForColumnGap:([WXConvert WXLength:attributes[@"columnGap"] isFloat:YES scaleFactor:scaleFactor])];
            if (columnGap != layout.columnGap) {
                layout.columnGap = columnGap;
                needUpdateLayout = YES;
            }
        }
        if (attributes[@"leftGap"]) {
            layout.leftGap = [WXConvert WXPixelType:attributes[@"leftGap"] scaleFactor:scaleFactor];
        }
        if (attributes[@"rightGap"]) {
            layout.rightGap = [WXConvert WXPixelType:attributes[@"rightGap"] scaleFactor:scaleFactor];
        }
        
        if (needUpdateLayout) {
            for (WXComponent *component in self.subcomponents) {
                [component setNeedsLayout];
            }
            
            [self.collectionView reloadData];
            [self.collectionView.collectionViewLayout invalidateLayout];
        }
    }
    
}

- (void)setContentSize:(CGSize)contentSize
{
    // Do Nothing
}

- (void)adjustSticky
{
    // Do Nothing, sticky is adjusted by layout
}

#pragma mark - Private Subclass Methods

- (void)_updateStylesOnComponentThread:(NSDictionary *)styles resetStyles:(NSMutableArray *)resetStyles isUpdateStyles:(BOOL)isUpdateStyles
{
    [super _updateStylesOnComponentThread:styles resetStyles:resetStyles isUpdateStyles:isUpdateStyles];
    
    [self _fillPadding];
}

- (void)_handleFirstScreenTime
{
    // Do Nothing， firstScreenTime is set by cellDidRendered:
}

- (void)scrollToComponent:(WXComponent *)component withOffset:(CGFloat)offset animated:(BOOL)animated
{
    CGPoint contentOffset = _collectionView.contentOffset;
    CGFloat contentOffsetY = 0;
    
    CGRect rect;
    while (component) {
        if ([component isKindOfClass:[WXCellComponent class]]) {
            NSIndexPath *toIndexPath = [self.dataController indexPathForCell:(WXCellComponent *)component];
            UICollectionViewLayoutAttributes *attributes = [_collectionView layoutAttributesForItemAtIndexPath:toIndexPath];
            rect = attributes.frame;
            break;
        }
        if ([component isKindOfClass:[WXHeaderComponent class]]) {
            NSUInteger toIndex = [self.dataController indexForHeader:(WXHeaderComponent *)component];
            UICollectionViewLayoutAttributes *attributes = [_collectionView layoutAttributesForSupplementaryElementOfKind:kCollectionSupplementaryViewKindHeader atIndexPath:[NSIndexPath indexPathWithIndex:toIndex]];
            rect = attributes.frame;
            break;
        }
        contentOffsetY += component.calculatedFrame.origin.y;
        component = component.supercomponent;
    }
    
    contentOffsetY += rect.origin.y;
    contentOffsetY += offset * self.weexInstance.pixelScaleFactor;
    
    if (_collectionView.contentSize.height >= _collectionView.frame.size.height && contentOffsetY > _collectionView.contentSize.height - _collectionView.frame.size.height) {
        contentOffset.y = _collectionView.contentSize.height - _collectionView.frame.size.height;
    } else {
        contentOffset.y = contentOffsetY;
    }
    
    [_collectionView setContentOffset:contentOffset animated:animated];
    
}

- (void)performUpdatesWithCompletion:(void (^)(BOOL finished))completion
{
    WXAssertMainThread();
    
    //TODO: support completion
    
    if (![self isViewLoaded]) {
        completion(NO);
    }
    
    NSArray *oldData = [self.dataController.sections copy];
    NSArray *newData = [self _sectionArrayFromComponents:self.subcomponents];
    
    [_updateController performUpdatesWithNewData:newData oldData:oldData view:_collectionView];
}

- (BOOL)_insertSubcomponent:(WXComponent *)subcomponent atIndex:(NSInteger)index
{
    if ([subcomponent isKindOfClass:[WXCellComponent class]]) {
        ((WXCellComponent *)subcomponent).delegate = self;
    } else if ([subcomponent isKindOfClass:[WXHeaderComponent class]]) {
        ((WXHeaderComponent *)subcomponent).delegate = self;
    }
    
    BOOL inserted = [super _insertSubcomponent:subcomponent atIndex:index];
    
    if (![subcomponent isKindOfClass:[WXHeaderComponent class]]
        && ![subcomponent isKindOfClass:[WXCellComponent class]]) {
        return inserted;
    }
    
    WXPerformBlockOnMainThread(^{
        [self performUpdatesWithCompletion:^(BOOL finished) {
            // void
        }];
    });
    
    return inserted;
}

- (void)insertSubview:(WXComponent *)subcomponent atIndex:(NSInteger)index
{
    //Here will not insert cell/header/footer's view again
    if (![subcomponent isKindOfClass:[WXCellComponent class]]
        && ![subcomponent isKindOfClass:[WXHeaderComponent class]]
        && ![subcomponent isKindOfClass:[WXFooterComponent class]]) {
        [super insertSubview:subcomponent atIndex:index];
    }
}

#pragma mark - WXRecyclerUpdateControllerDelegate

- (void)updateController:(WXRecyclerUpdateController *)controller willPerformUpdateWithNewData:(NSArray<WXSectionDataController *> *)newData
{
    if (newData) {
        [self.dataController updateData:newData];
    }
}

- (void)updateController:(WXRecyclerUpdateController *)controller didPerformUpdateWithFinished:(BOOL)finished
{
    
}

#pragma mark - UICollectionViewDataSource

- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
    WXLogDebug(@"section number:%li", (long)[self.dataController numberOfSections]);
    return [self.dataController numberOfSections];
}

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
    NSInteger numberOfItems = [self.dataController numberOfItemsInSection:section];
    
    WXLogDebug(@"Number of items is %ld in section:%ld", (long)numberOfItems, (long)section);
    
    return numberOfItems;
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    WXLogDebug(@"Getting cell at indexPath:%@", indexPath);
    
    WXCollectionViewCell *cellView = [_collectionView dequeueReusableCellWithReuseIdentifier:kCollectionCellReuseIdentifier forIndexPath:indexPath];
    
    UIView *contentView = [self.dataController cellForItemAtIndexPath:indexPath];
    
    cellView.wx_component = contentView.wx_component;
    
    [self.dragController goThroughAnchor:cellView.wx_component indexPath:indexPath];
    
    if (contentView.superview == cellView.contentView) {
        return cellView;
    }
    
    for (UIView *view in cellView.contentView.subviews) {
        [view removeFromSuperview];
    }
    
    [cellView.contentView addSubview:contentView];
    [cellView setAccessibilityIdentifier:contentView.accessibilityIdentifier];
    
    return cellView;
}

- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
{
    UICollectionReusableView *reusableView = nil;
    if ([kind isEqualToString:kCollectionSupplementaryViewKindHeader]) {
        reusableView = [collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:kCollectionHeaderReuseIdentifier forIndexPath:indexPath];
        UIView *contentView = [self.dataController viewForHeaderAtIndexPath:indexPath];
        if (contentView.superview != reusableView) {
            for (UIView *view in reusableView.subviews) {
                [view removeFromSuperview];
            }
            
            [reusableView addSubview:contentView];
        }
    }
    
    return reusableView;
}

#pragma mark - UICollectionViewDelegate

- (void)collectionView:(UICollectionView *)collectionView willDisplayCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath
{
    WXLogDebug(@"will display cell:%@, at index path:%@", cell, indexPath);
}

- (void)collectionView:(UICollectionView *)collectionView didEndDisplayingCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath
{
    WXLogDebug(@"Did end displaying cell:%@, at index path:%@", cell, indexPath);
}

#pragma mark - WXMultiColumnLayoutDelegate

- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView insetForLayout:(UICollectionViewLayout *)collectionViewLayout
{
    return _padding;
}

- (CGFloat)collectionView:(UICollectionView *)collectionView contentWidthForLayout:(UICollectionViewLayout *)collectionViewLayout
{
    return [self safeContainerStyleWidth];
}

- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout heightForItemAtIndexPath:(NSIndexPath *)indexPath
{
    CGSize itemSize = [self.dataController sizeForItemAtIndexPath:indexPath];
    return itemSize.height;
}

- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout heightForHeaderInSection:(NSInteger)section
{
    CGSize headerSize = [self.dataController sizeForHeaderAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:section]];
    return headerSize.height;
}

- (BOOL)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout hasHeaderInSection:(NSInteger)section
{
    return [self.dataController hasHeaderInSection:section];
}

- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout isNeedStickyForHeaderInSection:(NSInteger)section
{
    return [self.dataController isStickyForHeaderAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:section]];
}

#pragma mark - WXHeaderRenderDelegate

- (float)headerWidthForLayout:(WXHeaderComponent *)header
{
    if (_layoutType == WXRecyclerLayoutTypeMultiColumn) {
        return ((WXMultiColumnLayout *)_collectionViewlayout).computedHeaderWidth;
    }
    
    return 0.0;
}

- (void)headerDidLayout:(WXHeaderComponent *)header
{
    WXPerformBlockOnMainThread(^{
        [self.collectionView.collectionViewLayout invalidateLayout];
    });
}

- (void)headerDidRemove:(WXHeaderComponent *)header
{
    WXPerformBlockOnMainThread(^{
        [self performUpdatesWithCompletion:^(BOOL finished) {
            
        }];
    });
}

#pragma mark - WXCellRenderDelegate

- (float)containerWidthForLayout:(WXCellComponent *)cell
{
    if (_layoutType == WXRecyclerLayoutTypeMultiColumn) {
        return ((WXMultiColumnLayout *)_collectionViewlayout).computedColumnWidth;
    }
    
    return 0.0;
}

- (void)cellDidLayout:(WXCellComponent *)cell
{
    BOOL previousLayoutComplete = cell.isLayoutComplete;
    cell.isLayoutComplete = YES;
    WXPerformBlockOnMainThread(^{
        if (previousLayoutComplete) {
            [self.updateController reloadItemsAtIndexPath:[self.dataController indexPathForCell:cell]];
        } else {
            [self performUpdatesWithCompletion:^(BOOL finished) {
            }];
        }
    });
}

- (void)cellDidRendered:(WXCellComponent *)cell
{
    if (WX_MONITOR_INSTANCE_PERF_IS_RECORDED(WXPTFirstScreenRender, self.weexInstance) && !self.weexInstance.onRenderProgress) {
        return;
    }
    
    NSIndexPath *indexPath = [self.dataController indexPathForCell:cell];
    
    UICollectionViewLayoutAttributes *attributes = [self.collectionView layoutAttributesForItemAtIndexPath:indexPath];
    CGRect cellRect = attributes.frame;
    if (cellRect.origin.y + cellRect.size.height >= _collectionView.frame.size.height) {
        WX_MONITOR_INSTANCE_PERF_END(WXPTFirstScreenRender, self.weexInstance);
    }
    
    if (self.weexInstance.onRenderProgress) {
        CGRect renderRect = [_collectionView convertRect:cellRect toView:self.weexInstance.rootView];
        self.weexInstance.onRenderProgress(renderRect);
    }
}

- (void)cellDidRemove:(WXCellComponent *)cell
{
    if (cell.isLayoutComplete) {
        WXPerformBlockOnMainThread(^{
            [self performUpdatesWithCompletion:^(BOOL finished) {
            }];
        });
    }
}

- (void)cell:(WXCellComponent *)cell didMoveToIndex:(NSUInteger)index
{
    if (cell.isLayoutComplete) {
        WXPerformBlockOnMainThread(^{
            [self performUpdatesWithCompletion:^(BOOL finished) {
            }];
        });
    }
}

#pragma mark - Load More Event

- (void)setLoadmoreretry:(NSUInteger)loadmoreretry
{
    if (loadmoreretry != self.loadmoreretry) {
        _previousLoadMoreCellNumber = 0;
    }
    
    [super setLoadmoreretry:loadmoreretry];
}

- (void)loadMore
{
    [super loadMore];
    
    _previousLoadMoreCellNumber = [self totalNumberOfCells];
}

- (BOOL)isNeedLoadMore
{
    BOOL superNeedLoadMore = [super isNeedLoadMore];
    return superNeedLoadMore && _previousLoadMoreCellNumber != [self totalNumberOfCells];
}

- (NSUInteger)totalNumberOfCells
{
    NSUInteger cellNumber = 0;
    NSUInteger sectionCount = [_collectionView numberOfSections];
    for (int section = 0; section < sectionCount; section ++) {
        cellNumber += [_collectionView numberOfItemsInSection:section];
    }
    
    return cellNumber;
}

- (void)resetLoadmore{
    [super resetLoadmore];
    _previousLoadMoreCellNumber = 0;
}

#pragma mark - Private

- (float)_floatValueForColumnGap:(WXLength *)gap
{
    if (gap.isNormal) {
        return kRecyclerNormalColumnGap * self.weexInstance.pixelScaleFactor;
    } else {
        return gap.floatValue;
    }
}

- (void)_fillPadding
{
    if (self.flexCssNode == nullptr) {
        return;
    }
    
    UIEdgeInsets padding = {
            WXFloorPixelValue(self.flexCssNode->getPaddingTop() + self.flexCssNode->getBorderWidthTop()),
            WXFloorPixelValue(self.flexCssNode->getPaddingLeft() + self.flexCssNode->getBorderWidthLeft()),
            WXFloorPixelValue(self.flexCssNode->getPaddingBottom() + self.flexCssNode->getBorderWidthBottom()),
            WXFloorPixelValue(self.flexCssNode->getPaddingRight() + self.flexCssNode->getBorderWidthRight())
        };
    
    
    if (!UIEdgeInsetsEqualToEdgeInsets(padding, _padding)) {
        _padding = padding;
        [self setNeedsLayout];
        
        for (WXComponent *component in self.subcomponents) {
            [component setNeedsLayout];
        }
        
        if (_collectionView) {
            WXPerformBlockOnMainThread(^{
                [_collectionView.collectionViewLayout invalidateLayout];
            });
        }
    }
}

- (NSArray<WXSectionDataController *> *)_sectionArrayFromComponents:(NSArray<WXComponent *> *)components
{
    NSMutableArray<WXSectionDataController *> *sectionArray = [NSMutableArray array];
    NSMutableArray<WXCellComponent *> *cellArray = [NSMutableArray array];
    WXSectionDataController *currentSection;
    
    for (int i = 0; i < components.count; i++) {
        if (!currentSection) {
            currentSection = [WXSectionDataController new];
        }
        
        WXComponent* component = components[i];
        
        if ([component isKindOfClass:[WXHeaderComponent class]]) {
            if (i != 0 && (currentSection.headerComponent || cellArray.count > 0)) {
                currentSection.cellComponents = [cellArray copy];
                [sectionArray addObject:currentSection];
                currentSection = [WXSectionDataController new];
                [cellArray removeAllObjects];
            }
            currentSection.headerComponent = (WXHeaderComponent *)component;
        } else if ([component isKindOfClass:[WXCellComponent class]]
                   && ((WXCellComponent *)component).isLayoutComplete) {
            [cellArray addObject:(WXCellComponent *)component];
        } else if ([component isKindOfClass:[WXFooterComponent class]]) {
            currentSection.footerComponent = component;
        } else {
            continue;
        }
    }
    
    if (cellArray.count > 0 || currentSection.headerComponent) {
        currentSection.cellComponents = [cellArray copy];
        [sectionArray addObject:currentSection];
    }
    
    return sectionArray;
}

- (void)fixFlicker
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        // FIXME:(ง •̀_•́)ง┻━┻ Stupid scoll view, always reset content offset to zero by calling _adjustContentOffsetIfNecessary after insert cells.
        // So if you pull down list while list is rendering, the list will be flickering.
        // Demo:
        // Have to hook _adjustContentOffsetIfNecessary here.
        // Any other more elegant way?
        NSString *a = @"ntOffsetIfNe";
        NSString *b = @"adjustConte";
        
        NSString *originSelector = [NSString stringWithFormat:@"_%@%@cessary", b, a];
        [[self class] weex_swizzle:[WXCollectionView class] Method:NSSelectorFromString(originSelector) withMethod:@selector(fixedFlickerSelector)];
    });
}

#define mark dragControllerDelegate

- (void)updateDataSource{
    NSMutableArray *oldComponents = [[NSMutableArray alloc] initWithArray:self.dataController.sections[self.dragController.startIndexPath.section].cellComponents];
    if(oldComponents.count > 1){
        WXCellComponent *startComponent = self.dataController.sections[self.dragController.startIndexPath.section].cellComponents[self.dragController.startIndexPath.item];
        [oldComponents removeObject:startComponent];
        [oldComponents insertObject:startComponent atIndex:self.dragController.targetIndexPath.item];
        self.dataController.sections[self.dragController.startIndexPath.section].cellComponents = oldComponents;
    }
}

- (void)dragFireEvent:(NSString *)eventName params:(NSDictionary *)params{
    [self fireEvent:eventName params:params];
}

- (void)fixedFlickerSelector
{
    // DO NOT delete this method.
}

@end
