/**
 * WordPress dependencies
 */
import { Button } from '@safe-wordpress/components';
import { useSelect } from '@safe-wordpress/data';
import { _x } from '@safe-wordpress/i18n';
import { addQueryArgs } from '@safe-wordpress/url';

/**
 * External dependencies
 */
import { addFreeTracker } from '@nab/utils';
import { store as NAB_DATA, usePluginSetting } from '@nab/data';
import type { Maybe, SubscriptionPlan } from '@nab/types';

/**
 * Internal dependencies
 */
import './style.scss';

export type PremiumFeatureProps = {
	readonly className?: string;
	readonly feature: keyof typeof FEATURES | ( string & {} );
	readonly requiredPlan?: SubscriptionPlan | ( string & {} );
	readonly children?: JSX.Element;
	readonly size?: Button.Props[ 'size' ];
};

export const PremiumFeature = ( {
	className = '',
	children,
	feature: featureName,
	requiredPlan = '',
	size,
}: PremiumFeatureProps ): JSX.Element | null => {
	const feature = useFeature( featureName, requiredPlan );

	if ( ! feature?.locked ) {
		return children || null;
	}

	return (
		<Button
			className={ `nab-premium-feature ${ className }` }
			icon="lock"
			size={ size }
			href={ feature.url }
			target="_blank"
		>
			{ feature.label }
		</Button>
	);
};

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

const useFeature = (
	featureName: string,
	requiredPlan: string
): Maybe< {
	readonly locked: boolean;
	readonly url: string;
	readonly label: string;
} > => {
	const originalFeature: Maybe<
		( typeof FEATURES )[ keyof typeof FEATURES ]
	> = FEATURES[ featureName as keyof typeof FEATURES ];
	const feature =
		'setting' === originalFeature
			? {
					requiredPlan,
					subscribeLabel: 'premium',
					upgradeLabel: requiredPlan ?? 'premium',
			  }
			: originalFeature;

	const isSubscribed = !! usePluginSetting( 'subscription' );
	const hasRequiredPlan = useIsSubscribedTo( feature?.requiredPlan );
	const accountUrl = useSelect(
		( select ) =>
			select( NAB_DATA ).getAdminUrl(
				'admin.php?page=nelio-ab-testing-account'
			),
		[]
	);

	if ( ! isSubscriptionPlan( feature.requiredPlan ) ) {
		return undefined;
	}

	return {
		locked: ! hasRequiredPlan,
		url: isSubscribed
			? accountUrl
			: addFreeTracker(
					addQueryArgs(
						'https://neliosoftware.com/testing/pricing/',
						{
							plan: getPlanName( feature.requiredPlan ),
						}
					)
			  ),
		label: isSubscribed ? feature.upgradeLabel : feature.subscribeLabel,
	};
};

const useIsSubscribedTo = ( plan: Maybe< string > ): boolean =>
	useSelect(
		( select ) =>
			isSubscriptionPlan( plan ) &&
			select( NAB_DATA ).isSubscribedTo( plan ),
		[ plan ]
	);

function getPlanName( plan: SubscriptionPlan ): string {
	switch ( plan ) {
		case 'basic':
			return 'nab-basic-monthly';
		case 'professional':
			return 'nab-pro-monthly';
		case 'enterprise':
			return 'nab-enterprise-monthly';
	}
}

const isSubscriptionPlan = ( plan = '' ): plan is SubscriptionPlan =>
	[ 'basic', 'professional', 'enterprise' ].includes( plan );

// ====
// DATA
// ====

const FEATURES = {
	'unique-results': {
		requiredPlan: 'professional' as const,
		subscribeLabel: _x(
			'View unique results (Professional)',
			'user',
			'nelio-ab-testing'
		),
		upgradeLabel: _x(
			'View unique results (Professional)',
			'user',
			'nelio-ab-testing'
		),
	},
	'setting:excluded_ips': 'setting' as const,
	'setting:google_analytics_tracking': 'setting' as const,
	'setting:notifications-setup': 'setting' as const,
	'setting:percentage_of_tested_visitors': 'setting' as const,
};
