import React, { Component } from 'react';
import {
	View,
	Dimensions,
	Platform,
	TouchableOpacity,
	Image as RNImage,
} from 'react-native';
import Video from 'react-native-video';
import { Image as UIKitImage } from 'nixplay-ui-kit';
import PropTypes from 'prop-types';
import _ from 'lodash';
import playButton from '~/images/general/play-button.png';
import withTransformable from '~/components/Photos/withTransformable';
import { isValidVideo } from '~/lib/validate';

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

const BasImage = (props) => (
	<View>
		{
			(Platform.OS === 'ios') && <RNImage {...props} />
		}
		{
			(Platform.OS === 'android') && <RNImage {...props} />
		}
	</View>


);
const Image = withTransformable(BasImage);

const styles = {
	slide: {
		flex: 1,
	},
	thumb: {
		flex: 1,
	},
	preview: {
		flex: 1,
		width,
		height,
	},
};

export class AssetPreview extends Component {
	constructor(props) {
		super(props);

		this.state = {
			uri: this.getVideoPath(),
			thumbnailPath: this.getImagePath(),
			paused: true,
			currentTime: props.startTime,
		};
	}

	async componentWillMount() {
		if (this.isVideo()) {
			if (Platform.OS === 'ios') {
				this.pauseVideo();
			} else {
				this.setState({ uri: this.getVideoPath(), paused: true });
			}
		}
	}

	// static getDerivedStateFromProps(props, state) {
	// 	if (!_.isEqual(props.paused, state.paused)) {
	// 		return { paused: props.paused };
	// 	}
	// 	return null;
	// }

	shouldComponentUpdate(nextProps, nextState) {
		if (!_.isEqual(nextState.paused, this.state.paused)) {
			return true;
		}
		if (!_.isEqual(nextProps.paused, this.props.paused)) {
			return true;
		}
		if (!_.isEqual(nextProps.startTime, this.props.startTime) || !_.isEqual(nextProps.endTime, this.props.endTime)) {
			return true;
		}
		if (!_.isEqual(this.state.uri, nextState.uri)) {
			return true;
		}
		return false;
	}

	componentDidUpdate(prevProps) {
		if (this.isVideo()) {
			if (!_.isEqual(prevProps.startTime, this.props.startTime)
				|| !_.isEqual(prevProps.endTime, this.props.endTime)) {
				// eslint-disable-next-line react/no-did-update-set-state
				this.setState({ paused: true, currentTime: this.props.startTime }, () => {
					if (this.player) this.player.seek(this.props.startTime);
				});
			}
			if (!_.isEqual(prevProps.paused, this.props.paused)) {
				// eslint-disable-next-line react/no-did-update-set-state
				this.setState({ paused: this.props.paused });
			}
		}
	}

	componentWillUnmount() {
		this.setState({ paused: true });
	}

	onEnd = () => {
		this.setState({ paused: true, currentTime: this.props.startTime });
	}

	onLoad = () => {
		if (this.props.startTime >= 0 && this.props.endTime > 0) {
			if (this.player) this.player.seek(this.state.currentTime);
		} else if (this.player) {
			this.player.seek(0);
		}
	}

	onProgress = ({
		currentTime,
	}) => {
		if (this.props.startTime >= 0 && this.props.endTime > 0) {
			if (currentTime >= this.props.endTime) {
				this.player.paused = true;
				this.setState({ paused: true, currentTime: this.props.startTime });
			} else {
				this.setState({ currentTime });
			}
		}
	}
	getVideoPath = () => {
		if (Platform.OS === 'android' && _.has(this.props.item, 'fullFilePath')) {
			const filePath = ((this.props.item.fullFilePath.indexOf('file://') < 0) ? 'file://' : '') + this.props.item.fullFilePath;
			return filePath;
		} else if (_.has(this.props.item, 'uri')) {
			return this.props.item.uri.replace('ph://', 'photos://');
		}
		return '';
	}

	getImagePath = () => {
		if (_.has(this.props.item, 'uri')) {
			return this.props.item.uri;
		} else if (_.has(this.props.item, 'previewUrl')) {
			return this.props.item.previewUrl;
		}
		return '';
	}

	getImagePreview() {
		if (this.isVideo() && !this.state.paused) {
			return (
				<TouchableOpacity
					activeOpacity={1.0}
					style={{
						flex: 1,
						width: '100%',
						height: '100%',
					}}
					onPress={this.toggleVideo}
				>
					<Video
						ref={(ref) => {
							this.player = ref;
						}}
						paused={this.state.paused}
						source={{ uri: this.state.uri, isAsset: true }}
						onLoad={this.onLoad}
						onEnd={this.onEnd}
						onProgress={this.onProgress}
						style={styles.thumb}
						resizeMode="contain"
						useTextureView={false}
					/>
				</TouchableOpacity>
			);
		} else if (Platform.OS === 'ios') {
			return (
				<Image
					source={{ uri: this.state.thumbnailPath }}
					minimumZoomScale={1}
					maximumZoomScale={3}
					androidScaleType="contain"
					style={styles.preview}
					resizeMethod="resize"
					resizeMode="contain"
					withProgress={_.has(this.state.thumbnailPath, 'http')}
				/>
			);
		}
		return (
			<UIKitImage
				source={{ uri: (this.isVideo() && Platform.OS === 'android' && _.has(this.props.item, 'fullFilePath')) ? this.props.item.fullFilePath : this.state.thumbnailPath }}
				style={styles.preview}
				withProgress
				resizeMethod="resize"
				resizeMode="contain"
			/>
		);
	}

	setZoomRef = (node) => {
		if (node) {
			this.zoomRef = node;
			this.scrollResponderRef = this.zoomRef.getScrollResponder();
		}
	}

	playVideo = () => {
		if (this.isVideo()) {
			if (this.state.currentTime !== this.props.startTime) {
				// continue currnet time
				this.setState({ paused: false });
			} else {
				// video never play or completed playback
				this.setState({ uri: this.getVideoPath(), paused: false });
				if (this.props.startTime > 0 && this.props.endTime > 0) {
					if (this.player) this.player.seek(this.state.currentTime);
				}
			}
			this.props.videoDidPlay({
				index: this.props.index,
				uri: this.getVideoPath(),
				AssetPreview: this,
			});
		}
	}

	pauseVideo = () => {
		if (this.isVideo()) {
			this.setState({ paused: true });
		}
	}
	toggleVideo = () => {
		if (this.isVideo()) {
			if (this.state.paused) {
				this.playVideo();
			} else {
				this.pauseVideo();
			}
		}
	}

	handleResetZoomScale = () => {
		this.scrollResponderRef.scrollResponderZoomTo({
			x: 0,
			y: 0,
			width: this.props.zoomWidth,
			height: this.props.zoomHeight,
			animated: true,
		});
	}

	isVideo = () => isValidVideo(this.props.item.type);

	render() {
		return (
			<View style={styles.slide}>
				{
					this.getImagePreview()
				}
				{
					this.isVideo() && this.state.paused &&
					<TouchableOpacity
						style={{
							position: 'absolute',
							left: (width / 2) - 50,
							top: (height / 2) - 50,
							bottom: 0,
							right: 0,
							width: 100,
							height: 100,
							justifyContent: 'center',
							alignItems: 'center',
						}}
						onPress={this.toggleVideo}
					>
						<RNImage
							source={playButton}
							style={{
								flex: 1,
								width: 52,
								height: 52,
							}}
							androidScaleType="center"
							resizeMode="contain"
							resizeMethod="resize"
						/>
					</TouchableOpacity>
				}
			</View>
		);
	}
}

AssetPreview.propTypes = {
	index: PropTypes.number,
	item: PropTypes.any,
	zoomHeight: PropTypes.number,
	zoomWidth: PropTypes.number,
	videoDidPlay: PropTypes.func,
	startTime: PropTypes.number,
	endTime: PropTypes.number,
	paused: PropTypes.bool,
};

AssetPreview.defaultProps = {
	item: {},
	index: 0,
	startTime: -1,
	endTime: -1,
	zoomHeight: width,
	zoomWidth: height,
	videoDidPlay: () => {},
	paused: true,
};
