/**
 * WordPress dependencies
 */
import { addFilter } from '@wordpress/hooks';
import { __ } from '@wordpress/i18n';
import {
	SelectControl,
	Flex,
	Button,
} from '@wordpress/components';
import { trash, plusCircle } from '@wordpress/icons';

/**
 * Internal dependencies
 */
import { isEmpty } from './../utils/index';

/**
 * Checks for WooCommerce Memberships Plans as part of the required PersonalizeWP logic.
 *
 * @param {Object} attributes All original PWP attributes
 * @return {boolean} Return True if the attributes validate for Segments
 */
const checkRequiredWooCommerceMembershipsPlans = ( required, attributes ) => {
	if (
		Object.hasOwn( attributes, 'integrations' ) &&
		'woocommerce-memberships' == attributes?.integrations?.plugin &&
		Object.hasOwn(
			attributes?.integrations,
			'woocommerce_memberships_plans'
		) &&
		0 <
			attributes?.integrations?.woocommerce_memberships_plans?.filter(
				Boolean
			).length
	) {
		return true;
	}
	// Return original
	return required;
};
addFilter(
	'personalizeWP.hasRequiredFields',
	'personalizewp/check-for-woocommerce-memberships-plans',
	checkRequiredWooCommerceMembershipsPlans
);

/**
 * Add WooCommerce Integrations Attributes to the attribute list.
 *
 * @param {Object} integrations attributes
 * @return {boolean} Return Iintegrations attributes with woocommerce_memberships_plans
 */
function addWooCommerceMembershipsIntegrationsAttributes(
	integrationsAttributes
) {
	integrationsAttributes.woocommerce_memberships_plans = {
		type: 'array',
		default: [],
	};
	return integrationsAttributes;
}
addFilter(
	'personalizeWP.integrations.attributes',
	'personalizewp/add-woocommerce-memberships-integrations-attributes',
	addWooCommerceMembershipsIntegrationsAttributes
);

/**
 * Render the Integrations WooCommerce Memberships Plans controls.
 *
 * @since 3.1.0
 *
 * @param {string} ret JSX The JSX content to be rendered.
 * @param {Object} props All the props passed to this function.
 * @param {string} integrationsPlugin Selected Integrations Plugin.
 * @param {function} Function to update attributes.
 *
 * @return {string} JSX to be rendered.
 */
function addWooCommerceMembershipsPlans( ret, props, integrationsPlugin, updatePluginOptions ) {
	const { blockAtts, setPersonalizeWPAtts, settings } = props;

	// Check for WooCommerce Memberships to use, awaiting loading.
	if (
		! settings?.integrations?.plugins &&
		! settings?.integrations?.woocommerce_memberships_plans
	) {
		return ret;
	}

	if ( 'woocommerce-memberships' !== integrationsPlugin ) {
		return ret;
	}

	// Process the plan into options we can use.
	const plansOptions = [
		{
			value: 0,
			label: __( '-- Select membership levels --', 'personalizewp' ),
		},
	].concat(
		...Array.from(
			settings.integrations.woocommerce_memberships_plans
		).map( function ( plan ) {
			return {
				value: parseInt( plan.value, 10 ),
				label: plan.label,
			};
		} )
	);

	let selectedPlans =
		blockAtts?.integrations?.woocommerce_memberships_plans ?? [];
	// This is required to ensure the first SelectControl appears
	if ( ! selectedPlans || isEmpty( selectedPlans ) ) {
		selectedPlans = [ 0 ];
	}

	/**
	 * Sanitizes a group of Plans, ensuring only valid, unique options.
	 * @param {Array} plans Array of Plans
	 */
	const sanitizePlans = ( plans ) => {
		// Internal use of ints
		plans = plans.map( ( num ) => parseInt( num, 10 ) );
		// Note: Don't attempt to remove "empty" entries from the array,
		// such as zero, as a 0 is required for the new dropdown entry.
		// And remove any duplicate Plans
		return [ ...new Set( plans ) ];
	};

	const updatePlansAttribute = ( selectedPlans ) => {
		let sanitizeSelectedPlans = sanitizePlans( selectedPlans );
		if ( isEmpty( sanitizeSelectedPlans ) ) {
			updatePluginOptions( {} );
		} else {
			updatePluginOptions( { woocommerce_memberships_plans: sanitizeSelectedPlans } );
		}
	};

	/**
	 * Regenerate the woocommerce_memberships_levels attribute when a Plan select control changes.
	 * @param {String} rule  Value of PlanID to update
	 */
	const updateBlockPlans = ( index, plan ) => {
		selectedPlans[ index ] = plan;
		updatePlansAttribute( selectedPlans );
	};

	/**
	 * Trigger the removal of another Plan select control, and updating the Plan attribute.
	 * @param {String} index Position of Plan to remove
	 */
	const removeBlockPlan = ( index ) => {
		// Remove this plan from the block
		selectedPlans.splice( index, 1 );
		updatePlansAttribute( selectedPlans );
	};

	/**
	 * Trigger the addition of another Plan select control, at the end, and updating the Plan attribute.
	 */
	const addBlockPlan = () => {
		// Add a plan to the end of the segments
		selectedPlans.splice( selectedPlans.length, 0, 0 );
		updatePlansAttribute( selectedPlans );
	};

	return (
		<>
			{ selectedPlans.map( ( planID, index ) => {
				return (
					<Flex
						direction="row"
						data-key={ 'i' + index }
						key={ 'pwp-membeships-plan-' + index }
						className="select-integrations-plan"
					>
						<SelectControl
							label={
								0 === index
									? __( 'Plans', 'personalizewp' )
									: ''
							}
							hideLabelFromVision={ true }
							value={ String( planID ) }
							options={ plansOptions }
							onChange={ ( value ) => {
								updateBlockPlans( index, value );
							} }
							__nextHasNoMarginBottom
						/>

						{
							// Only show this when there are at least 2 fields
							1 < selectedPlans.length && (
								<Button
									label={ __(
										'Delete field',
										'personalizewp'
									) }
									icon={ trash }
									onClick={ () => {
										removeBlockPlan( index );
									} }
								/>
							)
						}
					</Flex>
				);
			} ) }

			<div className="woocommerce-memberships-plan-set__add-woocommerce-memberships-plan">
				<Flex direction="row" align="center" justify="flex-end">
					{
						// Only show the plus if this is the last item, and it's not "no plan"
						0 !== selectedPlans[ selectedPlans.length - 1 ] && (
							<Button
								label={ __(
									'Add another',
									'personalizewp'
								) }
								icon={ plusCircle }
								onClick={ () => {
									addBlockPlan();
								} }
							/>
						)
					}
				</Flex>
			</div>
		</>
	);
}

addFilter(
	'personalizeWP.additionalIntegrationsControls',
	'personalizewp/add-woocommerce-memberships-inspector-integrations-controls',
	addWooCommerceMembershipsPlans
);
