import React, { Component } from 'react';
import { View, Dimensions } from 'react-native';
import PropTypes from 'prop-types';
import { RecyclerListView, DataProvider, LayoutProvider } from 'recyclerlistview';
import _ from 'lodash';
import { ContentPreview } from '~/components/Photos/contentPreview';
import { AssetPreview } from './AssetPreview';

const { width: screenWidth, height: screenHeight } = Dimensions.get('window');

export class PreviewPager extends Component {
	static propTypes = {
		data: PropTypes.array.isRequired,
		onPagerIndexChanged: PropTypes.func,
		onPagerScroll: PropTypes.func,
		paused: PropTypes.bool,
		style: PropTypes.any.isRequired,
		selectedIndex: PropTypes.number,
	};

	static defaultProps = {
		onPagerIndexChanged: () => {},
		onPagerScroll: () => {},
		paused: true,
		selectedIndex: 0,
	};

	constructor(props) {
		super(props);

		this.scrollToIndex = this.scrollToIndex.bind(this);
		this.refRecyclerListView = this.refRecyclerListView.bind(this);
		this.onVisibleIndexesChanged = this.onVisibleIndexesChanged.bind(this);
		this.updateData = this.updateData.bind(this);
		this.getItemIndex = this.getItemIndex.bind(this);
		this.getProperIndex = this.getProperIndex.bind(this);
		this.pauseVideo = this.pauseVideo.bind(this);
		this.layoutProvider = new LayoutProvider(
			() => 0,
			// eslint-disable-next-line no-param-reassign
			(type, dim) => { dim.width = screenWidth; dim.height = screenHeight; },
		);
		this.rowRenderer = this.rowRenderer.bind(this);

		this.state = {
			dataProvider: new DataProvider((r1, r2) => !_.isEqual(r1, r2)).cloneWithRows(props.data),
			paused: true,
			index: 0,
		};
	}

	componentWillReceiveProps(nextProps) {
		if (!_.isEqual(nextProps.data.map(a => a.uri), this.props.data.map(a => a.uri))
			&& _.size(nextProps.data) > 0) {
			const nextLen = _.size(nextProps.data);
			const propsLen = _.size(this.props.data);
			this.pauseVideo();
			let toIndex = this.state.index;
			const diffLen = nextLen - propsLen;
			const curItem = this.props.data[this.state.index];
			const lastItemIndex = this.getItemIndex(curItem, nextProps.data);
			switch (diffLen) {
				case -1:
					if (lastItemIndex === -1) {
						if (toIndex === (propsLen - 1)) {
							toIndex = nextLen - 1;
							// if remove item at the tail
						} else {
							toIndex = this.state.index;
							// if remove item at the head or middle
						}
					} else {
						toIndex = lastItemIndex;
					}
					break;
				default:
					toIndex = nextLen - 1;
					break;
			}
			this.updateData(nextProps.data, toIndex, (diffLen >= 0));
		} else if (!_.isEqual(nextProps.data, this.props.data)) {
			// if  selected asset meta changed, update AssetPreview, e.g. trimmed time
			this.setState({
				dataProvider: this.state.dataProvider.cloneWithRows(nextProps.data),
				paused: true,
			});
		}
	}

	shouldComponentUpdate(nextProps, nextState) {
		if (!_.isEqual(nextProps.data, this.props.data)) {
			return true;
		}
		if (!_.isEqual(nextProps.paused, this.props.paused)) {
			return true;
		}
		if (!_.isEqual(nextState.paused, this.state.paused)) {
			return true;
		}
		if (!_.isEqual(nextState.index, this.state.index)) {
			return true;
		}
		return false;
	}

	onVisibleIndexesChanged= (all) => {
		// console.log('onVisibleIndexesChanged', all);
		if (_.size(all) === 1) {
			this.setState({ index: all[0], paused: true }, () => {
				this.pauseVideo();
				this.props.onPagerIndexChanged(this.state.index);
			});
		}
	}

	onMomentumScrollEnd = (event) => {
		const index = _.round(event.nativeEvent.contentOffset.x / screenWidth);
		if (this.state.index !== index) {
			this.pauseVideo();
			this.setState({ index, paused: true }, () => {
				this.props.onPagerIndexChanged(this.state.index);
			});
		}
	}

	getItemIndex = (item, array) => {
		if (typeof item === 'object') {
			return _.findIndex(array, item);
		}
		return -1;
	}

	getProperIndex = (index) => ((index - 1) > 0 ? index - 1 : 0);

	pauseVideo = () => {
		if (this.assetPreviewRef && this.assetPreviewRef instanceof AssetPreview) {
			this.assetPreviewRef.pauseVideo();
			this.assetPreviewRef = null;
		}
	}

	updateData = (newData, toIndex, more) => {
		const prvIndex = this.state.index;
		// console.log('prvIndex', prvIndex, 'toIndex', toIndex);
		// const indexDidNotChanged = (Math.abs(prvIndex - toIndex) === 0);
		const dataProvider = this.state.dataProvider.cloneWithRows(newData);
		if (more) {
			this.setState({
				index: toIndex,
				dataProvider,
			}, () => {
				setTimeout(() => {
					if (!_.isEmpty(this.recyclerListView)) {
						this.recyclerListView.scrollToIndex(
							this.state.index,
							Math.abs(this.state.index, prvIndex) < 2,
						);
						this.props.onPagerIndexChanged(this.state.index);
					}
				}, 50);
			});
		} else {
			this.setState({
				index: toIndex,
				dataProvider,
			}, () => {
				if (!_.isEmpty(this.recyclerListView)) {
					const targetIndex = toIndex >= 0 ? toIndex : Math.max(0, _.size(newData) - 1);
					const topRowNewOffset =
					this.recyclerListView._virtualRenderer // eslint-disable-line no-underscore-dangle
						.getLayoutManager()
						.getOffsetForIndex(targetIndex);
					setTimeout(
						() => {
							// console.log('this.recyclerListView.scrollToOffset');
							this.recyclerListView.scrollToOffset(
								topRowNewOffset.x,
								0,
								Math.abs(toIndex - prvIndex) < 2,
							);
							this.props.onPagerIndexChanged(toIndex);
							// console.log(`this.props.onPagerIndexChanged(${toIndex});`);
						},
						50,
					);
				}
			});
		}
	}

	scrollToIndex(param) {
		const animated = (param.animated && typeof param.animated === 'boolean')
			? param.animated : Math.abs(this.state.index - param.index) < 2;
		this.pauseVideo();
		if (this.state.index !== param.index) {
			this.setState({ index: param.index, paused: true }, () => {
				if (!_.isEmpty(this.recyclerListView)) {
					this.recyclerListView.scrollToIndex(param.index, animated);
				}
			});
		}
	}

	rowRenderer = (type, item, index) => {
		if (item) {
			return _.has(item, 'previewUrl') ?
				(
					<ContentPreview
						item={item}
					/>
				) :
				(
					<AssetPreview
						paused={this.state.paused}
						style={{
							width: '100%',
							height: '100%',
							paddingLeft: 2,
							paddingRight: 2,
							overflow: 'hidden',
						}}
						{...item}
						key={item.uri}
						item={item}
						videoDidPlay={(param) => { this.assetPreviewRef = param.AssetPreview; }}
						index={index}
					/>
				);
		}
		return (
			<View />
		);
	};

	// handleScroll = (event) => {
	// 	/
	// 	// this.props.onPagerScroll(event);
	// 	if (this.assetPreviewRef && this.assetPreviewRef instanceof AssetPreview) {
	// 		this.assetPreviewRef.pauseVideo();
	// 	}
	// }

	refRecyclerListView(ref) {
		this.recyclerListView = ref;
	}

	render() {
		return (
			<RecyclerListView
				style={this.props.style}
				ref={this.refRecyclerListView}
				initialRenderIndex={this.props.selectedIndex}
				scrollEventThrottle={250}
				pagingEnabled
				isHorizontal
				layoutProvider={this.layoutProvider}
				dataProvider={this.state.dataProvider}
				rowRenderer={this.rowRenderer}
				// onScroll={this.handleScroll}
				onMomentumScrollEnd={this.onMomentumScrollEnd}
				onVisibleIndexesChanged={this.onVisibleIndexesChanged}
				removeClippedSubviews
			/>
		);
	}
}
