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

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

/**
 * Checks for Segments as part of required PersonalizeWP logic.
 *
 * @param {Object} attributes All original PWP attributes
 * @return {boolean} Return True if the attributes validate for Segments
 */
const checkRequiredSegments = ( required, attributes ) => {
	if ( Object.hasOwn( attributes, 'segments' ) && 0 < attributes.segments.filter(Boolean).length ) {
		return true;
	}
	// Return original
	return required;
}
addFilter(
	'personalizeWP.hasRequiredFields',
	'personalizewp/check-for-segments',
	checkRequiredSegments
);

/**
 * Render the Segments inspector controls.
 *
 * @since 2.6.0
 * @param {Object} props All the props passed to this function
 */
export default function SegmentsControls( props ) {
	const {
		blockAtts,
		setPersonalizeWPAtts,
		settings
	} = props;

	// Check for segments to use, awaiting loading.
	if ( ! settings?.segments || 0 >= settings.segments.length ) {
		return null;
	}

	// Process the segments into options we can use.
	const segmentOptions = [
			{
				value: 0,
				label: __( '-- Select a segment --', 'personalizewp' ),
			},
		].concat(
			...Array.from(settings.segments).map(
				function(seg) {
					return {
						value: parseInt( seg.id, 10 ),
						label: seg.name,
						disabled: !seg.is_usable,
					}
				} )
		);

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

	/**
	 * Sanitizes a group of Segments, ensuring only valid, unique options.
	 * @param {Array} segments Array of Segments
	 */
	const sanitizeSegments = (segments) => {
		// Internal use of ints
		segments = segments.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 Segments
		return [...new Set(segments)];
	};

	/**
	 * Regenerate the Segments attribute, when a Segment select control changes.
	 * @param {String} index Position of Segment to update
	 * @param {String} rule  Value of SegmentID to update
	 */
	const updateBlockSegments = (index, segment) => {
		selectedSegments[ index ] = segment;
		setPersonalizeWPAtts( {
			segments: sanitizeSegments( selectedSegments ),
		} );
	};

	/**
	 * Trigger the removal of another Segment select control, and updating the Segment attribute.
	 * @param {String} index Position of Segment to remove
	 */
	const removeBlockSegment = (index) => {
		// Remove this rule from the block
		selectedSegments.splice( index, 1 );
		setPersonalizeWPAtts( {
			segments: sanitizeSegments( selectedSegments ),
		} );
	};

	/**
	 * Trigger the addition of another Segment select control, at the end, and updating the Segment attribute.
	 */
	const addBlockSegment = () => {
		// Add a segment to the end of the segments
		selectedSegments.splice( selectedSegments.length, 0, 0 );
		setPersonalizeWPAtts( {
			segments: sanitizeSegments( selectedSegments ),
		} );
	};

	// These controls can be marked as inert if settings have been made elsewhere.
	const inert = hasOtherBlockAtts( blockAtts, [ 'segments' ] );

	return (
		<div className="pwp-panel segments">
			<Flex direction="row" align="flex-start">
				<h3>{ __( 'Segments', 'personalizewp' )}</h3>
				<Tooltip
					delay={200}
					text={__("This will return true if the user is in the chosen segment.", "personalizewp")}
					className="pwp-tooltip"
					placement="bottom-end">
					<div>
						<Icon icon={ help } size={ 20 } />
					</div>
				</Tooltip>
			</Flex>

			{ selectedSegments.map( (segmentID, index ) => {
				return (
					<Flex
						direction="row"
						data-key={"i" + index}
						key={"pwp-segment-" + index}
						className="select-rule"
						inert={ inert ? 'true' : undefined }
					>
						<SelectControl
							label={ 0 === index ? __( 'Segments', 'personalizewp' ) : '' }
							hideLabelFromVision={true}
							value={ String(segmentID) }
							options={ segmentOptions }
							onChange={ ( value ) => {
								updateBlockSegments( index, value );
							} }
							__nextHasNoMarginBottom
							disabled={ inert }
						/>

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

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