/**
 * WordPress dependencies
 */
import { DropdownMenu, MenuItem } from '@safe-wordpress/components';
import { useDispatch, useSelect } from '@safe-wordpress/data';
import { _x } from '@safe-wordpress/i18n';

/**
 * External dependencies
 */
import { store as NAB_DATA } from '@nab/data';
import { store as NAB_EXPERIMENTS } from '@nab/experiments';
import { isDefined } from '@nab/utils';
import type { Opportunity } from '@nab/types';

export type CreateExperimentFromOpportunityButtonProps = {
	readonly labels?: {
		readonly action: string;
		readonly busy: string;
	};
	readonly isBusy?: boolean;
	readonly isDisabled?: boolean;
	readonly opportunity: Opportunity;
	readonly variant: 'primary' | 'secondary' | 'link';
};

export function CreateExperimentFromOpportunityButton( {
	labels = {
		action: _x( 'Create Test', 'command', 'nelio-ab-testing' ),
		busy: _x( 'Creating Test…', 'text', 'nelio-ab-testing' ),
	},
	isBusy,
	isDisabled,
	opportunity,
	variant,
}: CreateExperimentFromOpportunityButtonProps ): JSX.Element {
	const experimentTypes = useValidExperimentTypes( opportunity );

	const { instantiateOpportunityAsExperiment } = useDispatch( NAB_DATA );
	const label = isBusy ? labels.busy : labels.action;

	return (
		<DropdownMenu
			icon={ null }
			label={ label }
			toggleProps={ {
				variant,
				isBusy,
				disabled: isDisabled,
				children: label,
			} }
			children={ ( { onClose } ) =>
				experimentTypes.map( ( { name, title, icon: Icon } ) => (
					<MenuItem
						key={ name }
						role="menuitem"
						icon={ Icon && <Icon /> }
						{ ...{ iconPosition: 'left' } }
						onClick={ () => {
							onClose();
							void instantiateOpportunityAsExperiment(
								name,
								opportunity
							);
						} }
					>
						{ title }
					</MenuItem>
				) )
			}
		/>
	);
}

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

function useValidExperimentTypes( opportunity: Opportunity ): ReadonlyArray< {
	readonly name:
		| 'nab/url'
		| 'nab/page'
		| 'nab/post'
		| 'nab/custom-post-type'
		| 'nab/headline'
		| 'nab/css'
		| 'nab/javascript'
		| 'nab/php';
	readonly title: string;
	readonly icon?: () => JSX.Element;
} > {
	const validTypes = [
		...// eslint-disable-next-line no-nested-ternary
		( opportunity.target.type === 'url'
			? [ 'nab/url' as const ]
			: // eslint-disable-next-line no-nested-ternary
			opportunity.target.postType === 'page'
			? [ 'nab/page' as const ]
			: opportunity.target.postType === 'post'
			? [ 'nab/post' as const, 'nab/headline' as const ]
			: [ 'nab/custom-post-type' as const ] ),
		'nab/css' as const,
		'nab/javascript' as const,
		'nab/php' as const,
	];

	const types = useSelect(
		( select ) => select( NAB_EXPERIMENTS ).getExperimentTypes(),
		[]
	);

	return validTypes
		.map( ( name ) => [ name, types[ name ] ] as const )
		.map( ( [ name, type ] ) =>
			type
				? {
						name,
						title: type.title,
						icon: type.icon,
				  }
				: undefined
		)
		.filter( isDefined );
}
