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

/**
 * External dependencies
 */
import { trim } from 'lodash';
import { CodeEditor } from '@nab/code-editor';
import { ConversionActionScopeView } from '@nab/components';
import { store as NAB_DATA } from '@nab/data';
import type { CAViewProps, ConversionActionScope, Dict } from '@nab/types';

/**
 * Internal dependencies
 */
import type { Attributes } from './types';

export const View = ( props: CAViewProps< Attributes > ): JSX.Element => (
	<>
		<div>
			<ActualView { ...props } />
		</div>
		<ConversionActionScopeView scope={ props.scope } />
	</>
);

const ActualView = ( {
	attributes: { snippet, ...attributes },
	...props
}: CAViewProps< Attributes > ): JSX.Element => {
	const [ isSnippetVisible, showSnippet ] = useState( false );
	const status = useSelect( ( select ) => {
		const exp = select( NAB_DATA ).getPageAttribute(
			'editor/activeExperiment'
		);
		return exp
			? select( NAB_DATA ).getExperimentAttribute( exp, 'status' )
			: undefined;
	}, [] );

	// DEPRECATED. We’re now using JS functions and not eventNames.
	// @ts-expect-error This is an old attribute that may still exist?
	const { eventName } = attributes;
	if ( !! eventName || undefined === snippet ) {
		return <OldView attributes={ attributes } { ...props } />;
	}

	const { scope } = props;
	if ( 'running' !== status && 'finished' !== status ) {
		return <>{ getLabel( scope ) }</>;
	}

	return (
		<>
			{ getLabel( scope ) + ' ' }
			<Button variant="link" onClick={ () => showSnippet( true ) }>
				{ _x( 'View Code', 'command', 'nelio-ab-testing' ) }
			</Button>
			{ isSnippetVisible && (
				<Modal
					title={ _x(
						'Custom Tracking Code',
						'text',
						'nelio-ab-testing'
					) }
					onRequestClose={ () => showSnippet( false ) }
				>
					<CodeEditor
						language="javascript"
						value={ snippet }
						readOnly
					/>
				</Modal>
			) }
		</>
	);
};

// DEPRECATED. We should remove this view at some point.
const OldView = ( {
	attributes: { eventName },
	experimentId,
	goalIndex,
}: CAViewProps< Dict< string > > ): JSX.Element => {
	if ( ! experimentId || undefined === goalIndex ) {
		return (
			<>
				{ _x(
					'A conversion is programmatically sent to Nelio’s cloud via JavaScript.',
					'text',
					'nelio-ab-testing'
				) }
			</>
		);
	}

	const value = !! trim( eventName )
		? `nab.<wbr />trigger(<wbr />'${ trim( eventName ) }')`
		: `nab.<wbr />convert(<wbr />${ experimentId },<wbr />${ goalIndex })`;

	const sentence = !! trim( eventName )
		? /* translators: %s: Javascript snippet. */
		  _x(
				'A custom JavaScript event is triggered using %s.',
				'text',
				'nelio-ab-testing'
		  )
		: /* translators: %s: Javascript snippet. */
		  _x(
				'A conversion is programmatically generated in JavaScript using %s.',
				'text',
				'nelio-ab-testing'
		  );

	return (
		<>
			{ createInterpolateElement(
				sprintf( sentence, `<code>${ value }</code>` ),
				{ code: <code />, wbr: <wbr /> }
			) }
		</>
	);
};

// =======
// HELPERS
// =======

function getLabel( scope: ConversionActionScope ): string {
	switch ( scope.type ) {
		case 'all-pages':
			return _x(
				'A script that runs on any page triggers a conversion.',
				'text',
				'nelio-ab-testing'
			);

		case 'test-scope':
			return _x(
				'A script that runs only on a tested page triggers a conversion.',
				'text',
				'nelio-ab-testing'
			);

		case 'urls':
		case 'post-ids':
		case 'php-function':
			return _x(
				'A script that runs only on certain pages triggers a conversion.',
				'text',
				'nelio-ab-testing'
			);
	}
}
