import React, { Component } from 'react';
import _ from 'lodash';
import { FlatList, Platform } from 'react-native';
import PropTypes from 'prop-types';
import { checkInternetConnection } from 'react-native-offline';

const isIOS = Platform.OS === 'ios';

export class PaginationScroll extends Component {
	static propTypes = {
		asyncData: PropTypes.bool,
		data: PropTypes.array.isRequired,
		getData: PropTypes.func.isRequired,
		loading: PropTypes.bool.isRequired,
		numPerPage: PropTypes.number,
		onRefresh: PropTypes.func,
		extraData: PropTypes.any,
		style: PropTypes.any,
		hasMore: PropTypes.bool,
	}

	static defaultProps = {
		asyncData: false,
		numPerPage: 20,
		onRefresh: null,
		extraData: {},
		style: {},
		hasMore: false,
	}

	constructor(props) {
		super(props);

		this.state = {
			items: [],
			page: 1,
			numPerPage: props.numPerPage,
			refreshing: false,
			hasMore: true,
		};

		this.generateRenderData = this.generateRenderData.bind(this);
		this.refreshData = this.refreshData.bind(this);
		this.loadMoreData = this.loadMoreData.bind(this);
	}

	componentDidMount() {
		this.props.getData();
	}

	componentWillReceiveProps(nextProps) {
		if (!nextProps.loading && (_.isEqual(this.props.getData.name, nextProps.getData.name))) {
			if (this.props.asyncData) {
				this.setState({
					refreshing: false,
				});
			} else {
				this.generateRenderData(nextProps);
			}
		}
	}

	shouldComponentUpdate(nextProps) {
		if (_.isEqual(this.props.data, nextProps.data) &&
			_.isEqual(this.props.extraData, nextProps.extraData)) {
			return false;
		}
		return true;
	}

	generateRenderData(props = this.props) {
		const end = this.state.page * this.state.numPerPage;
		this.setState({
			refreshing: false,
			items: props.data.slice(0, end),
			hasMore: end < props.data.length,
		});
	}

	refreshData() {
		checkInternetConnection().then(isConnected => {
			if (isConnected) {
				if (this.state.refreshing) return;
				this.setState({
					page: 1,
					refreshing: true,
				}, () => {
					if (_.isFunction(this.props.onRefresh)) {
						this.props.onRefresh();
					} else {
						this.props.getData(this.state.page, this.state.numPerPage);
					}
				});
			} else {
				this.setState({ refreshing: false });
			}
		});
	}

	loadMoreData() {
		if ((this.props.asyncData && !this.props.hasMore && !this.state.refreshing) ||
			(!this.props.asyncData && !this.state.hasMore)) return;
		const nextPage = this.state.page + 1;
		if (this.props.asyncData) {
			this.props.getData(nextPage, this.state.numPerPage, ({ content }) => {
				this.setState({
					page: nextPage,
					refreshing: false,
					items: [...this.state.items, ...content],
				});
			});
		} else {
			this.setState({
				page: nextPage,
			}, () => {
				this.generateRenderData();
			});
		}
	}

	render() {
		return (
			<FlatList
				{...this.props}
				removeClippedSubviews={!isIOS}
				scrollEventThrottled={16}
				extraData={[this.state.items, this.props.extraData]}
				refreshing={this.state.refreshing}
				onRefresh={this.refreshData}
				onEndReached={this.loadMoreData}
				onEndReachedThreshold={2}
				initialNumToRender={8}
				maxToRenderPerBatch={3}
				style={[{ overflow: 'hidden' }, this.props.style]}
			/>
		);
	}
}
