/**
 * External dependencies.
 */
import { memo } from '@wordpress/element';
import { __, sprintf } from '@wordpress/i18n';
import {
	InspectorControls,
	useSettings,
} from '@wordpress/block-editor';
import {
	__experimentalToolsPanel as ToolsPanel,
	__experimentalToolsPanelItem as ToolsPanelItem,
	__experimentalUnitControl as UnitControl,
	__experimentalUseCustomUnits as useCustomUnits,
	__experimentalVStack as VStack,
	__experimentalToggleGroupControl as ToggleGroupControl,
	__experimentalToggleGroupControlOption as ToggleGroupControlOption,
	__experimentalInputControl as InputControl,
	AnglePickerControl,
	ToggleControl,
} from '@wordpress/components';

/**
 * Internal dependencies.
 */
import IconPicker from '@spectra-components/icon-picker';
import InspectorColor from '@spectra-components/inspector-color';

/**
 * Element Sub-settings: General settings.
 *
 * @param {Object} props The element props.
 * @since x.x.x
 * @return {Element} The rendered block settings.
 */
const BlockSettings = memo( ( props ) => {

	// Destructure the required props.
	const { clientId, setAttributes, attributes } = props;

	const {
		icon,
		flipForRTL,
		rotation,
		accessibilityMode,
		accessibilityLabel,
	} = attributes;

	// Placehloder for the accessibility label based on the mode.
	let accessibilityPlaceholder;
	switch ( accessibilityMode ) {
		case 'svg':
			accessibilityPlaceholder = sprintf(
				/* translators: %s: The name of the SVG icon. */
				__( 'An icon named %s', 'spectra-pro' ),
				icon || 'circle-check',
			);
			break;
		case 'image':
			accessibilityPlaceholder = sprintf(
				/* translators: %s: The name of the SVG image. */
				__( 'An image named %s', 'spectra-pro' ),
				icon || 'circle-check',
			);
			break;
		default:
			accessibilityPlaceholder = '';
	}

	// Variable to determine if the accessibility label should be disabled or not.
	const requiresAccessibilityLabel = [ 'svg', 'image' ].includes( accessibilityMode );

	// Render the settings.
	return (
		<>
			<InspectorControls group="settings">
				<ToolsPanel
					label={ __( 'Icon', 'spectra-pro' ) }
					resetAll={ () => {
						setAttributes( {
							icon: undefined,
							flipForRTL: false,
							accessibilityMode: undefined,
							accessibilityLabel: undefined,
						} );
					} }
					panelId={ clientId }
				>
					{/* This tool panel item will require reset when any of these conditions are met:
					- The icon attribute is set. Default: undefined.
					- The flipForRTL attribute is true. Default: false.
					*/}
					<ToolsPanelItem
						hasValue={ () => ( !! icon || !! flipForRTL ) }
						label={ __( 'Icon', 'spectra-pro' ) }
						onDeselect={ () => setAttributes( {
							icon: undefined,
							flipForRTL: false,
						} ) }
						resetAllFilter={ () => ( {
							icon: undefined,
							flipForRTL: false,
						} ) }
						isShownByDefault
						panelId={ clientId }
					>
						<VStack spacing={ 4 }>
							<IconPicker
								value={ icon }
								onChange={ ( value ) => setAttributes( { icon: value } ) }
							/>
							<ToggleControl
								__nextHasNoMarginBottom
								checked={ flipForRTL }
								label={ __( 'Flip Icon for Right-To-Left', 'spectra-pro' ) }
								onChange={ () => setAttributes( { flipForRTL: ! flipForRTL } ) }
								help={ __( 'Enable this for your RTL visitors if you are using a direction-specific icon. Like \'Arrow Right\', \'Chart Line\', etc. ', 'spectra-pro' ) }
							/>
						</VStack>
					</ToolsPanelItem>
					{/* This tool panel item will require reset when any of these conditions are met:
					- The rotation attribute is set. Default: undefined.
					*/}
					<ToolsPanelItem
						hasValue={ () => !! rotation }
						label={ __( 'Rotation', 'spectra-pro' ) }
						onDeselect={ () => setAttributes( { rotation: undefined } ) }
						resetAllFilter={ () => ( {
							rotation: undefined,
						} ) }
						panelId={ clientId }
					>
						<AnglePickerControl
							label={ __( 'Rotation', 'spectra-pro' ) }
							onChange={ ( value ) => {
								setAttributes( { rotation: value } );
							} }
							value={ rotation }
						/>
					</ToolsPanelItem>
					{/* This tool panel item will require reset when any of these conditions are met:
					- The accessibilityMode attribute is set. Default: undefined.
					- The accessibilityLabel attribute is set. Default: undefined.
					*/}
					<ToolsPanelItem
						hasValue={ () => !! accessibilityMode }
						label={ __( 'Accessibility', 'spectra-pro' ) }
						onDeselect={ () => setAttributes( {
							accessibilityMode: undefined,
							accessibilityLabel: undefined,
						} ) }
						resetAllFilter={ () => ( {
							accessibilityMode: undefined,
							accessibilityLabel: undefined,
						} ) }
						panelId={ clientId }
					>
						<VStack spacing={ 4 }>
							<ToggleGroupControl
								__nextHasNoMarginBottom
								__next40pxDefaultSize
								label={ __( 'Accessibiltiy Mode', 'spectra-pro' ) }
								value={ accessibilityMode }
								onChange={ ( value ) => setAttributes( { accessibilityMode: value } ) }
								isBlock
							>
								<ToggleGroupControlOption value="svg" label="SVG" />
								<ToggleGroupControlOption value="image" label="Image" />
								<ToggleGroupControlOption value="decorative" label="Decorative" />
							</ToggleGroupControl>
							{ requiresAccessibilityLabel && (
								<InputControl
									__next40pxDefaultSize
									label={ __( 'Accessibiltiy Label', 'spectra-pro' ) }
									value={ accessibilityLabel }
									onChange={ ( value ) => setAttributes( { accessibilityLabel: value } ) }
									placeholder={ accessibilityPlaceholder }
								/>
							) }
						</VStack>
					</ToolsPanelItem>
				</ToolsPanel>
			</InspectorControls>
		</>
	);
} );

/**
 * Element Sub-settings: Color settings for icon.
 *
 * @param {Object} props The element props.
 * @since 2.0.0
 * @return {Element} The rendered block settings.
 */
const ColorSettings = memo( ( props ) => {

	// Destructure the required props.
	const {
		clientId,
		setAttributes,
		attributes: {
			textColor,
	
		},
		context = {},
	} = props;

	// Get parent context colors
	const parentIconColor = context['spectra-pro/form/iconColor'];
	const parentTextColor = context['spectra-pro/form/textColor'];

	return(
		<InspectorColor
			settings={ [
				{
					colorValue: textColor || parentIconColor || parentTextColor,
					label: __( 'Icon Color', 'spectra-pro' ),
					onColorChange: ( value ) => setAttributes( { textColor: value } ),
					resetAllFilter: () => setAttributes( { textColor: undefined } ),
				},

			] }
			panelId={ clientId }
		/>
	);
} );

/**
 * Element Sub-settings: Settings that are injected into Core's Dimensions panel.
 *
 * @param {Object} props The element props.
 * @since x.x.x
 * @return {Element} The rendered block settings.
 */
const DimensionSettings = memo( ( props ) => {

	// Destructure the requierd props.
	const {
		clientId,
		setAttributes,
		attributes: {
			size,
		},
		context = {},
	} = props;

	// Get parent context size
	const parentIconSize = context['spectra-pro/form/fieldsIconSize'];

	// Get the core provided units, else add the fallback.	
	const [ availableUnits ] = useSettings( 'spacing.units' );
	const units = useCustomUnits( {
		availableUnits: availableUnits || [ 'px', '%', 'vw', 'em', 'rem' ],
	} );

	return (
		<InspectorControls group="dimensions">
			<ToolsPanelItem
				hasValue={ () => !! size }
				label={ __( 'Size', 'spectra-pro' ) }
				onDeselect={ () => setAttributes( { size: undefined } ) }
				resetAllFilter={ () => ( {
					size: undefined,
				} ) }
				isShownByDefault
				panelId={ clientId }
			>
				<UnitControl
					__next40pxDefaultSize
					label={ __( 'Size', 'spectra-pro' ) }
					labelPosition="top"
					value={ size || parentIconSize }
					min={ 0 }
					onChange={ ( value ) => setAttributes( { size: value } ) }
					units={ units }
				/>
			</ToolsPanelItem>
		</InspectorControls>
	);
} );

/**
 * The Editor settings for this block.
 *
 * @param {Object} props The element props.
 * @since x.x.x
 * @return {Element} The rendered settings.
 */
const Settings = ( props ) => (
	<>
		<BlockSettings { ...{ ...props } } />
		<ColorSettings { ...{ ...props } } />
		<DimensionSettings { ...{ ...props } } />
	</>
);

export default memo( Settings );