import { React, PropTypes, classnames } from '@gravityforms/libraries';
import { aspectRatioToPadding, spacerClasses } from '@gravityforms/utils';
import Button from '../../elements/Button';
import Text from '../../elements/Text';

const { useState, forwardRef } = React;

/**
 * @module Video
 * @description A video component.
 *
 * @since 1.2.2
 *
 * @param {object}                     props                          Component props.
 * @param {string}                     props.aspectRatio              The aspect ratio for the video, needed if using placeholder.
 * @param {JSX.Element}                props.children                 React element children.
 * @param {boolean}                    props.placeholderButton        Whether to display a play button over the placeholder if passed.
 * @param {object}                     props.placeholderButtonProps   The props for the play button.
 * @param {string|Array|object}        props.placeholderCustomClasses Custom classes for the placeholder image container.
 * @param {string}                     props.placeholderImage         String for the placeholder image. Valid url or encoded inline image.
 * @param {string}                     props.placeholderText          Text to display over the placeholder.
 * @param {object}                     props.placeholderTextProps     Props for the text component displayed over the placeholder.
 * @param {JSX.Element|null}           props.player                   The video player component.
 * @param {string|number|Array|object} props.spacing                  The spacing for the component, as a string, number, array, or object.
 * @param {object}                     props.wrapperAttributes        Custom attributes for the wrapper component.
 * @param {string|Array|object}        props.wrapperClasses           Custom classes for the wrapper component.
 * @param {object|null}                ref                            Ref to the component.
 *
 * @return {JSX.Element} The Video component.
 *
 */
const Video = forwardRef( ( {
	aspectRatio = '',
	children = null,
	placeholderButton = false,
	placeholderButtonProps = {},
	placeholderCustomClasses = [],
	placeholderImage = '',
	placeholderText = '',
	placeholderTextProps = {},
	player = null,
	spacing = '',
	wrapperAttributes = {},
	wrapperClasses = [],
}, ref ) => {
	const [ videoPlaying, setVideoPlaying ] = useState( false );
	const [ videoRevealed, setVideoRevealed ] = useState( false );

	const wrapperProps = {
		className: classnames( {
			'gform-video__wrapper': true,
			'gform-video__wrapper--has-ratio': aspectRatio.length,
			'gform-video__wrapper--has-placeholder': placeholderImage.length,
			'gform-video__wrapper--playing': videoPlaying,
			'gform-video__wrapper--revealed': videoRevealed,
			...spacerClasses( spacing ),
		}, wrapperClasses ),
		style: {
			paddingTop: aspectRatio.length ? `${ aspectRatioToPadding( aspectRatio ) }%` : 0,
		},
		...wrapperAttributes,
	};

	const plhdrProps = {
		className: classnames( {
			'gform-video__placeholder': true,
		}, placeholderCustomClasses ),
		style: {
			backgroundImage: `url("${ placeholderImage }")`,
			paddingTop: aspectRatio.length ? `${ aspectRatioToPadding( aspectRatio ) }%` : 0,
		},
	};

	const plhdrButtonProps = {
		customClasses: [ 'gform-button--video-play' ],
		icon: 'play-arrow',
		iconPrefix: 'gform-common-icon',
		...placeholderButtonProps,
		onClick: () => {
			if ( typeof placeholderButtonProps.onClick === 'function' ) {
				placeholderButtonProps.onClick();
			}
			setTimeout( () => {
				setVideoPlaying( true );
			}, 300 );
			setTimeout( () => {
				setVideoRevealed( true );
			}, 900 );
		},
	};

	return (
		<div { ...wrapperProps } ref={ ref }>
			{ placeholderImage.length > 0 &&
				<div { ...plhdrProps }>
					<div className="gform-video__placeholder-inner">
						{ placeholderText.length > 0 &&
							<Text { ...placeholderTextProps } />
						}
						{ placeholderButton &&
							<Button { ...plhdrButtonProps } />
						}
					</div>
				</div>
			}
			{ player }
			{ children }
		</div>
	);
} );

Video.propTypes = {
	aspectRatio: PropTypes.string,
	children: PropTypes.oneOfType( [
		PropTypes.arrayOf( PropTypes.node ),
		PropTypes.node,
	] ),
	placeholderButton: PropTypes.bool,
	placeholderButtonProps: PropTypes.object,
	placeholderCustomClasses: PropTypes.oneOfType( [
		PropTypes.string,
		PropTypes.array,
		PropTypes.object,
	] ),
	placeholderImage: PropTypes.string,
	placeholderText: PropTypes.string,
	placeholderTextProps: PropTypes.object,
	player: PropTypes.node,
	spacing: PropTypes.oneOfType( [
		PropTypes.string,
		PropTypes.number,
		PropTypes.array,
		PropTypes.object,
	] ),
	wrapperAttributes: PropTypes.object,
	wrapperClasses: PropTypes.oneOfType( [
		PropTypes.string,
		PropTypes.array,
		PropTypes.object,
	] ),
};

Video.displayName = 'Video';

export default Video;
