/**
 * WordPress dependencies
 */
import { Button } from '@safe-wordpress/components';
import { useSelect } from '@safe-wordpress/data';
import { createInterpolateElement } from '@safe-wordpress/element';
import { _x, _nx, sprintf } from '@safe-wordpress/i18n';

/**
 * External dependencies
 */
import { clsx } from 'clsx';
import { store as NAB_EXPERIMENTS } from '@nab/experiments';
import { formatNumber } from '@nab/i18n';
import { getLetter } from '@nab/utils';
import type { RunningExperimentSummary } from '@nab/types';

/**
 * Internal dependencies
 */
import './style.scss';
import { useResults } from '../../hooks';
import type { Results } from '../../hooks';

type RunningExperimentProps = {
	readonly experiment: RunningExperimentSummary;
};

export function RunningExperiment( {
	experiment,
}: RunningExperimentProps ): JSX.Element | null {
	const experimentType = useSelect(
		( select ) =>
			select( NAB_EXPERIMENTS ).getExperimentType( experiment.type ),
		[ experiment.type ]
	);
	const results = useResults( experiment.id );

	if ( ! experimentType || 'error' === results.status ) {
		return null;
	}

	const conversionRate =
		'ready' === results.status && results.views > 0
			? ( results.conversions / results.views ) * 100
			: 0;

	const Icon = experimentType.icon;
	return (
		<li className="nab-running-test">
			<div className={ `nab-running-test__icon` } aria-hidden="true">
				<Icon />
			</div>

			<div className="nab-running-test__main">
				<strong className="nab-running-test__name">
					{ experiment.name }
				</strong>
				<span className="nab-running-test__date">
					{ formatRelativeDate( experiment.startedAt ) }
				</span>
			</div>

			<div className="nab-running-test__stats">
				<span className="nab-running-test__views">
					{ createInterpolateElement(
						sprintf(
							/* translators: %s: Number of views. */
							_x( '%s Views', 'text', 'nelio-ab-testing' ),
							`<strong>${
								'ready' === results.status
									? formatNumber( results.views )
									: '█'
							}</strong>`
						),
						{
							strong: (
								<strong
									className={ clsx( {
										'nab-experiment__loading-value':
											'loading' === results.status,
									} ) }
								/>
							),
						}
					) }
				</span>
				<span className="nab-running-test__conversions">
					{ createInterpolateElement(
						sprintf(
							/* translators: %s: Number of conversions. */
							_x( '%s Convs.', 'text', 'nelio-ab-testing' ),
							`<strong>${
								'ready' === results.status
									? formatNumber( results.conversions )
									: '█'
							}</strong>`
						),
						{
							strong: (
								<strong
									className={ clsx( {
										'nab-experiment__loading-value':
											'loading' === results.status,
									} ) }
								/>
							),
						}
					) }
				</span>
				<span className="nab-running-test__conv-rate">
					{ createInterpolateElement(
						sprintf(
							/* translators: %s: Conversion rate. */
							_x( '%s Conv. rate', 'text', 'nelio-ab-testing' ),
							`<strong>${
								'ready' === results.status
									? conversionRate.toFixed( 1 ) + '%'
									: '█'
							}</strong>`
						),
						{
							strong: (
								<strong
									className={ clsx( {
										'nab-experiment__loading-value':
											'loading' === results.status,
									} ) }
								/>
							),
						}
					) }
				</span>

				<span
					className={ clsx( [
						'nab-running-test__leader',
						`nab-running-test__leader--winning-${
							'ready' === results.status &&
							undefined !== results.currentLeader
								? getLetter( results.currentLeader )
								: 'none'
						}`.toLowerCase(),
					] ) }
				>
					<strong
						className={ clsx( {
							'nab-experiment__loading-value':
								'loading' === results.status,
						} ) }
					>
						{ formatImprovement( results ) }
					</strong>
					{ getLeaderLabel( results, experiment.alternativeCount ) }
				</span>
			</div>

			<Button
				variant="secondary"
				className="nab-running-test__button"
				href={ experiment.resultUrl }
				icon="chart-bar"
				aria-label={ sprintf(
					/* translators: %s: Experiment name. */
					_x( 'View %s', 'command (experiment)', 'nelio-ab-testing' ),
					experiment.name
				) }
			/>
		</li>
	);
}

function formatRelativeDate( value: string ): string {
	const date = new Date( value );
	const days = Math.max(
		0,
		Math.round( ( Date.now() - date.getTime() ) / 86400000 )
	);

	if ( ! days ) {
		return _x( 'Started today', 'text', 'nelio-ab-testing' );
	}

	if ( 1 === days ) {
		return _x( 'Started yesterday', 'text', 'nelio-ab-testing' );
	}

	if ( days < 30 ) {
		return sprintf(
			/* translators: %d: Number of days. */
			_nx(
				'Started %d day ago',
				'Started %d days ago',
				days,
				'text',
				'nelio-ab-testing'
			),
			days
		);
	}

	if ( days < 90 ) {
		const weeks = Math.round( days / 7 );
		return sprintf(
			/* translators: %d: Number of weeks. */
			_nx(
				'Started %d week ago',
				'Started %d weeks ago',
				weeks,
				'text',
				'nelio-ab-testing'
			),
			weeks
		);
	}

	const months = Math.round( days / 30 );
	return sprintf(
		/* translators: %d: Number of months. */
		_nx(
			'Started %d month ago',
			'Started %d months ago',
			months,
			'text',
			'nelio-ab-testing'
		),
		months
	);
}

function formatImprovement( results: Results ): string {
	if ( 'ready' !== results.status ) {
		return '█';
	}

	if ( undefined === results.currentLeader ) {
		return '–';
	}
	const value = Math.abs( results.improvement );
	const sign = 0 === results.currentLeader ? '↓' : '↑';
	return `${ sign }${ value.toFixed( 1 ) }%`;
}

function getLeaderLabel( results: Results, alternativeCount: number ) {
	if ( 'ready' !== results.status ) {
		return '';
	}

	if ( undefined === results.currentLeader ) {
		return _x( 'No clear leader yet', 'text', 'nelio-ab-testing' );
	}

	if ( ! results.currentLeader ) {
		return alternativeCount > 2
			? _x( 'All variants behind', 'text', 'nelio-ab-testing' )
			: _x( 'Variant B behind', 'text', 'nelio-ab-testing' );
	}

	const letter = getLetter( results.currentLeader );
	return sprintf(
		/* translators: %s: Variant letter. */
		_x( 'Variant %s ahead', 'text', 'nelio-ab-testing' ),
		letter
	);
}
