/**
 * WordPress dependencies
 */
import { useEffect, useState } from '@safe-wordpress/element';
import { _x } from '@safe-wordpress/i18n';

/**
 * External dependencies
 */
import clsx from 'clsx';

/**
 * Internal dependencies
 */
import './style.scss';
import { LoadingAnimation } from '../loading-animation';

export type PreviewProps = {
	readonly className?: string;
	readonly url: string;
	readonly caption?: string;
};

export const Preview = ( {
	className,
	url,
	caption,
}: PreviewProps ): JSX.Element => {
	const [ status, setStatus ] = useUrlStatus( url );

	const isBusy = 'loading' === status || 'checking' === status;
	const isError = 'error' === status;
	const hasIFrame = 'loading' === status || 'ready' === status;

	return (
		<figure className={ clsx( [ 'nab-preview', className ] ) }>
			{ isBusy && (
				<div className="nab-preview__textual-feedback">
					{
						<LoadingAnimation
							text={ _x(
								'Loading…',
								'text',
								'neliko-ab-testing'
							) }
						/>
					}
				</div>
			) }

			{ isError && (
				<div className="nab-preview__textual-feedback">
					{ _x( 'No Preview', 'text', 'nelio-ab-testing' ) }
				</div>
			) }

			{ hasIFrame && (
				<iframe
					tabIndex={ -1 }
					className={ `nab-preview__image--${ status }` }
					src={ url }
					title={ caption }
					onLoad={ () => setStatus( 'ready' ) }
				></iframe>
			) }

			{ !! caption && (
				<figcaption className="nab-preview__caption screen-reader-text">
					{ _x( 'Test screenshot.', 'text', 'nelio-ab-testing' ) }
				</figcaption>
			) }
		</figure>
	);
};

// =====
// HOOKS
// =====

type Url = string;
type UrlStatus = 'checking' | 'loading' | 'error' | 'ready';

const useUrlStatus = ( url: Url ) => {
	const [ status, setStatus ] = useState< UrlStatus >( 'checking' );

	useEffect( () => {
		if ( ! url ) {
			setStatus( 'error' );
			return;
		}
		setStatus( 'checking' );
		fetch( url )
			.then( ( r ) => setStatus( r.ok ? 'loading' : 'error' ) )
			.catch( () => setStatus( 'error' ) );
	}, [ url, setStatus ] );

	return [ status, setStatus ] as const;
};
