/* eslint-disable */
import React, { PureComponent } from 'react';
import { View, Text, Image, ViewPropTypes, Dimensions } from 'react-native';
import PropTypes from 'prop-types';
import ViewTransformer from '../ViewTransformer';
import i18n from "~/locale/i18n";

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

export default class TransformableImage extends PureComponent {
	static propTypes = {
		image: PropTypes.shape({
			source: PropTypes.oneOfType([
				PropTypes.object,
				PropTypes.number
			]).isRequired,
			dimensions: PropTypes.shape({ width: PropTypes.number, height: PropTypes.number })
		}).isRequired,
		style: ViewPropTypes ? ViewPropTypes.style : View.propTypes.style,
		onLoad: PropTypes.func,
		onLoadStart: PropTypes.func,
		enableTransform: PropTypes.bool,
		enableScale: PropTypes.bool,
		enableTranslate: PropTypes.bool,
		onTransformGestureReleased: PropTypes.func,
		onViewTransformed: PropTypes.func,
		imageComponent: PropTypes.func,
		resizeMode: PropTypes.string,
		errorComponent: PropTypes.func,
		enableZoom: PropTypes.bool,
	};

	static defaultProps = {
		enableTransform: true,
		enableScale: true,
		enableTranslate: true,
		enableZoom: true,
		imageComponent: undefined,
		resizeMode: 'contain',
	};

	constructor (props) {
		super(props);

		this.onLayout = this.onLayout.bind(this);
		this.onLoad = this.onLoad.bind(this);
		this.onLoadStart = this.onLoadStart.bind(this);
		this.getViewTransformerInstance = this.getViewTransformerInstance.bind(this);
		this.renderError = this.renderError.bind(this);

		this.state = {
			viewWidth: 0,
			viewHeight: 0,
			imageLoaded: false,
			imageDimensions: props.image.dimensions,
			keyAcumulator: 1
		};
	}

	componentWillMount () {
		if (!this.state.imageDimensions) {
			this.getImageSize(this.props.image);
		}
	}

	componentDidMount () {
		this._mounted = true;
	}

	componentWillReceiveProps (nextProps) {
		if (!sameImage(this.props.image.source, nextProps.image.source)) {
			// image source changed, clear last image's imageDimensions info if any
			this.setState({ imageDimensions: nextProps.image.dimensions, keyAcumulator: this.state.keyAcumulator + 1 });
			if (!nextProps.image.dimensions) { // if we don't have image dimensions provided in source
				this.getImageSize(nextProps.image);
			}
		}
	}

	componentWillUnmount () {
		this._mounted = false;
	}

	onLoadStart (e) {
		this.props.onLoadStart && this.props.onLoadStart(e);
		if (this.state.imageLoaded) {
			this.setState({ imageLoaded: false });
		}
	}

	onLoad (e) {
		this.props.onLoad && this.props.onLoad(e);
		if (!this.state.imageLoaded) {
			this.setState({ imageLoaded: true });
		}
	}

	onLayout (e) {
		let {width, height} = e.nativeEvent.layout;
		if (this.state.viewWidth !== width || this.state.viewHeight !== height) {
			this.setState({ viewWidth: width, viewHeight: height });
		}
	}

	getImageSize (image) {
		if (!image) {
			return;
		}
		const { source, dimensions } = image;
		const { pageData } = this.props;
		const { rotation } = pageData;
		if (dimensions) {
			this.setState({ imageDimensions: dimensions });
			return;
		}

		if (source && source.uri) {
			Image.getSize(
				source.uri,
				(width, height) => {
					if (width && height) {
						const adjustedWidth = screenWidth;
						let adjustedHeight;
						let originalWidth;
						let originalHeight;
						if (rotation === 0 || rotation % 180 === 0) {
							const aspectRatio = screenWidth / width;
							adjustedHeight = aspectRatio * height;
							originalWidth = width;
							originalHeight = height;
						} else {
							const aspectRatio = screenWidth / height;
							adjustedHeight = aspectRatio * width;
							originalWidth = height;
							originalHeight = width;
						}
						if (this.state.imageDimensions && this.state.imageDimensions.width === adjustedWidth && this.state.imageDimensions.height === adjustedHeight) {
							// no need to update state
						} else {
							this._mounted && this.setState({ imageDimensions: { width: adjustedWidth, height: adjustedHeight, originalWidth, originalHeight, rotation } });
						}
					}
				},
				() => {
					this._mounted && this.setState({ error: true });
				}
			);
		} else {
			console.warn('react-native-image-gallery', 'Please provide dimensions of your local images');
		}
	}

	getViewTransformerInstance () {
		return this.refs['viewTransformer'];
	}

	renderError () {
		return (this.props.errorComponent && this.props.errorComponent()) || (
			<View style={{ flex: 1, backgroundColor: 'black', alignItems: 'center', justifyContent: 'center' }}>
				 <Text style={{ color: 'white', fontSize: 15, fontStyle: 'italic' }}>{i18n.t('playlists.thisImageCannotBeDisplayed')}</Text>
			</View>
		);
	}

	render () {
		const { imageDimensions, viewWidth, viewHeight, error, keyAccumulator, imageLoaded } = this.state;
		const { style, image, pageData, imageComponent, resizeMode, enableTransform, enableScale, enableTranslate, onTransformGestureReleased, onViewTransformed, enableZoom } = this.props;
		// console.log('imageComponent: ', imageComponent)
		// console.log('pageData: ', this.props.pageData)
		let maxScale = 1;
		let contentAspectRatio;
		let width, height, originalWidth, originalHeight; // imageDimensions


		if (imageDimensions) {
			width = imageDimensions.width;
			height = imageDimensions.height;
			originalWidth = imageDimensions.originalWidth;
			originalHeight = imageDimensions.originalHeight;
		}

		if (originalWidth && originalHeight) {
			contentAspectRatio = originalWidth / originalHeight;
			if (viewWidth && viewHeight) {
				maxScale = Math.max(originalWidth / viewWidth, originalHeight / viewHeight);
				maxScale = Math.max(1, maxScale);
			}
		}

		const imageProps = {
			...this.props,
			imageLoaded,
			source: image.source,
			style: [style, { backgroundColor: 'transparent' }],
			resizeMode: resizeMode,
			onLoadStart: this.onLoadStart,
			onLoad: this.onLoad,
			capInsets: { left: 0.1, top: 0.1, right: 0.1, bottom: 0.1 }
		};

		const content = imageComponent ? imageComponent(imageProps, imageDimensions, pageData) : <Image { ...imageProps } />;
		// console.log('content: ', content)
		return (
			<ViewTransformer
			  ref={'viewTransformer'}
			  key={'viewTransformer#' + keyAccumulator} // when image source changes, we should use a different node to avoid reusing previous transform state
			  enableTransform={!pageData.videoUrl && enableTransform && imageLoaded && enableZoom} // disable transform until image is loaded
			  enableScale={!pageData.videoUrl && enableScale && enableZoom}
			  enableTranslate={!pageData.videoUrl && enableTranslate && enableZoom}
			  enableResistance={true}
			  onTransformGestureReleased={onTransformGestureReleased}
			  onViewTransformed={onViewTransformed}
			  maxScale={maxScale}
			  contentAspectRatio={contentAspectRatio}
			  onLayout={this.onLayout}
			  style={style}>
				{ error ? this.renderError() : content }
			</ViewTransformer>
		);
	}
}

function sameImage (source, nextSource) {
	if (source === nextSource) {
		return true;
	}
	if (source && nextSource) {
		if (source.uri && nextSource.uri) {
			return source.uri === nextSource.uri;
		}
	}
	return false;
}
/* eslint-enable */
