/**
 * External dependencies
 */
import { useEffect } from '@wordpress/element';
import { useSettings, InspectorControls } from '@wordpress/block-editor';
import {
	__experimentalToolsPanelItem as ToolsPanelItem,
    __experimentalToolsPanel as ToolsPanel,
    __experimentalUnitControl as UnitControl,
    __experimentalUseCustomUnits as useCustomUnits,
	TextControl,
    ToggleControl,
    RangeControl,
    SelectControl,
} from '@wordpress/components';
import { __ } from '@wordpress/i18n';

/**
 * Modal content settings panel (Pro)
 *
 * Provides additional modal controls in Pro.
 *
 * @param {Object} props - Component props.
 * @return {JSX.Element} modal options panel component.
 */
export const ModalContentSettings = ( props ) => {
	const { 
        setAttributes,
        clientId,
        attributes: { 
            openModalAs,
            appearEffect,
            modalPosition,
            closeIconPosition,
            hPos,
            vPos
        }
    } = props;

	const repositionCloseButton = ( isLeft = false, allowWindowPos = false ) => {
		const positions = isLeft
			? {
				oldPos: 'left',
				oldWindowPos: allowWindowPos ? '' : 'left',
				newPos: 'right',
			  }
			: {
				oldPos: 'right',
				oldWindowPos: allowWindowPos ? '' : 'right',
				newPos: 'left',
			  };
		if (
			`window-top-${ positions.oldWindowPos }` === closeIconPosition ||
			`popup-top-${ positions.oldPos }` === closeIconPosition
		) {
			setAttributes( { closeIconPosition: `popup-top-${ positions.newPos }` } );
		}
	};

	useEffect( () => {
		switch ( openModalAs ) {
			case 'popup':
				switch ( modalPosition ) {
					case 'top-left':
						repositionCloseButton( true );
						break;
					case 'top-right':
						repositionCloseButton();
						break;
					case 'bottom-left':
						repositionCloseButton( true, true );
						break;
					case 'bottom-right':
						repositionCloseButton( false, true );
						break;
				}
				break;
			case 'left-off-canvas':
				repositionCloseButton( true );
				break;
			case 'right-off-canvas':
				repositionCloseButton();
				break;
		}
	}, [ openModalAs, modalPosition ] );

	// 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="settings">
			<ToolsPanel
				label={ __( 'Modal Content', 'spectra-pro' ) }
				resetAll={ () => {
					setAttributes( {
						openModalAs: 'popup',
						appearEffect: 'spectra-effect-default',
						modalPosition: 'centered',
						hPos: undefined,
						vPos: undefined,

					} );
				} }
				panelId={ clientId }
			>
				<ToolsPanelItem
					hasValue={ () => !! openModalAs }
					label={ __( 'Open Modal as a', 'spectra-pro' ) }
					onDeselect={ () => setAttributes( { openModalAs: 'popup' } ) }
					resetAllFilter={ () => ( {
						openModalAs: 'popup',
					} ) }
					isShownByDefault
					panelId={ clientId }
				>
					<SelectControl
						label={ __( 'Open Modal as a', 'spectra-pro' ) }
						value={ openModalAs }
						options={ [
							{ value: 'popup', label: __( 'Popup', 'spectra-pro' ) },
							{ value: 'left-off-canvas', label: __( 'Left Off-canvas', 'spectra-pro' ) },
							{ value: 'right-off-canvas', label: __( 'Right Off-canvas', 'spectra-pro' ) },
						] }
						onChange={ ( value ) => setAttributes( { openModalAs: value } ) }
					/>
				</ToolsPanelItem>
				<ToolsPanelItem
					hasValue={ () => !! appearEffect }
					label={ __( 'Appear Effect', 'spectra-pro' ) }
		  			onDeselect={ () => setAttributes( { appearEffect: 'spectra-effect-default', } ) }
					resetAllFilter={ () => ( {
						appearEffect: 'spectra-effect-default',
					} ) }
					isShownByDefault
					panelId={ clientId }
				>
					<SelectControl
						label={ __( 'Appear Effect', 'spectra-pro' ) }
						value={ appearEffect }
						options={ [
							{ value: 'spectra-effect-default', label: __( 'Default Effects', 'spectra-pro' ) },
							{ value: 'spectra-effect-1', label: __( 'Scale', 'spectra-pro' ) },
							{ value: 'spectra-effect-3', label: __( 'Scale In', 'spectra-pro' ) },
						] }
						onChange={ ( value ) => setAttributes( { appearEffect: value } ) }
						help= { __( "Note: Above setting will only take effect on frontend, and not while you're editing.", 'spectra-pro' ) }
					/>
				</ToolsPanelItem>
				{ 'popup' === openModalAs && (
					<ToolsPanelItem
						hasValue={ () => !! modalPosition }
						label={ __( 'Position', 'spectra-pro' ) }
						onDeselect={ () => setAttributes( { modalPosition: 'centered' } ) }
						resetAllFilter={ () => ( {
							modalPosition: 'centered',
						} ) }
						isShownByDefault
						panelId={ clientId }
					>
						<SelectControl
							label={ __( 'Position', 'spectra-pro' ) }
							value={ modalPosition }
							options={ [
								{ value: 'centered', label: __( 'Centered', 'spectra-pro' ) },
								{ value: 'top-left', label: __( 'Top Left', 'spectra-pro' ) },
								{ value: 'top-right', label: __( 'Top Right', 'spectra-pro' ) },
								{ value: 'bottom-left', label: __( 'Bottom Left', 'spectra-pro' ) },
								{ value: 'bottom-right', label: __( 'Bottom Right', 'spectra-pro' ) },
								{ value: 'custom', label: __( 'Custom', 'spectra-pro' ) },
							] }
							onChange={ ( value ) => setAttributes( { modalPosition: value } ) }
						/>
					</ToolsPanelItem>
				)}
				{ 'popup' === openModalAs && 'custom' === modalPosition && (
					<>
						<ToolsPanelItem
							hasValue={ () => !! hPos }
							label={ __( 'Horizontal Offset', 'spectra-pro' ) }
							onDeselect={ () => setAttributes( { hPos: undefined } ) }
							resetAllFilter={ () => ( {
								hPos: undefined,
							} ) }
							isShownByDefault
							panelId={clientId}
						>
							<UnitControl
								__next40pxDefaultSize
								label={ __( 'Horizontal Offset', 'spectra-pro' ) }
								labelPosition="top"
								value={ hPos }
								min={ 0 }
								max={ 1000 }
								onChange={ ( value ) => setAttributes( { hPos: value } ) }
								units={ units }
							/>
						</ToolsPanelItem>
						<ToolsPanelItem
							hasValue={ () => !! vPos }
							label={ __( 'Vertical Offset', 'spectra-pro' ) }
							onDeselect={ () => setAttributes( { vPos: undefined } ) }
							resetAllFilter={ () => ( {
								vPos: undefined,
							} ) }
							isShownByDefault
							panelId={clientId}
						>
							<UnitControl
								__next40pxDefaultSize
								label={ __( 'Vertical Offset', 'spectra-pro' ) }
								labelPosition="top"
								value={ vPos }
								min={ 0 }
								max={ 1000 }
								onChange={ ( value ) => setAttributes( { vPos: value } ) }
								units={ units }
								help= { __( "Note: Above setting will only take effect on frontend, and not while you're editing.", 'spectra-pro' ) }
							/>
						</ToolsPanelItem>
					</>
				) }
			</ToolsPanel>
		</InspectorControls>
	);
};

/**
 * Trigger Options Panel (Pro)
 *
 * Provides additional animation controls in Pro.
 *
 * @param {Object} props - Component props.
 * @return {JSX.Element} Trigger options panel component.
 */
export const TriggerSettings = ( props ) => {
    const {
        setAttributes,
		clientId,
        attributes: { 
            modalTrigger,
            cssClass,
            cssId,
            exitIntent,
            showAfterSeconds,
            enableCookies,
            noOfSecondsToShow,
            setCookiesOn,
            hideForDays,
        }
    } = props;

	return (
		<>
            { 'custom-class' === modalTrigger && (
				<ToolsPanelItem
					hasValue={ () => !! cssClass }
					label={ __( 'Custom Class', 'spectra-pro' ) }
					onDeselect={ () => setAttributes( { cssClass: undefined } ) }
					resetAllFilter={ () => ( {
						cssClass: undefined,
					} ) }
					isShownByDefault
					panelId={clientId}
			    >
					<TextControl
						__next40pxDefaultSize
						__nextHasNoMarginBottom
						value={cssClass}
						label={ __( 'Custom Class', 'spectra-pro' ) }
						setAttributes={ setAttributes }
						onChange={ ( value ) =>
							setAttributes( {
								cssClass: value,
							} )
						}
						help={ __(
							'Add your custom class without the dot. e.g: my-class. To edit the Modal content, please add this class to the desired trigger element and initialize modal from it.',
							'spectra-pro'
						) }
					/>
				</ToolsPanelItem>
            )}
            { 'custom-id' === modalTrigger && (
				<ToolsPanelItem
					hasValue={ () => !! cssId }
					label={ __( 'Custom ID', 'spectra-pro' ) }
					onDeselect={ () => setAttributes( { cssId: undefined } ) }
					resetAllFilter={ () => ( {
						cssId: undefined,
					} ) }
					isShownByDefault
					panelId={clientId}
				>
					<TextControl
						__next40pxDefaultSize
						__nextHasNoMarginBottom
						value={cssId}
						label={ __( 'Custom ID', 'spectra-pro' ) }
						setAttributes={ setAttributes }
						onChange={ ( value ) =>
							setAttributes( {
								cssId: value,
							} )
						}
						help={ __(
							'Add your custom id without the Pound key. e.g: my-id. This trigger works in the front-end only - add this id to the desired trigger element.',
							'spectra-pro'
						) }
					/>
				</ToolsPanelItem>
            ) }
            { 'automatic' === modalTrigger && (
                <>
					<ToolsPanelItem
						hasValue={ () => !! exitIntent }
						label={ __( 'Exit Intent', 'spectra-pro' ) }
						onDeselect={ () => setAttributes( { exitIntent: false } ) }
						resetAllFilter={ () => ( {
							exitIntent: false,
						} ) }
						isShownByDefault
						panelId={clientId}
					>
						<ToggleControl
							label={ __( 'Exit Intent', 'spectra-pro' ) }
							checked={ exitIntent }
							onChange={ () =>
								setAttributes( {
									exitIntent: ! exitIntent,
								} )
							}
						/>
					</ToolsPanelItem>
					<ToolsPanelItem
						hasValue={ () => !! showAfterSeconds }
						label={ __( 'Display After Seconds', 'spectra-pro' ) }
						onDeselect={ () => setAttributes( { showAfterSeconds: false } ) }
						resetAllFilter={ () => ( {
							showAfterSeconds: false,
						} ) }
						isShownByDefault
						panelId={clientId}
					>
						<ToggleControl
							label={ __( 'Display After Seconds', 'spectra-pro' ) }
							checked={ showAfterSeconds }
							onChange={ () =>
								setAttributes( {
									showAfterSeconds: ! showAfterSeconds,
								} )
							}
                    	/>
					</ToolsPanelItem>
                    { showAfterSeconds && (
						<ToolsPanelItem
							hasValue={ () => !! noOfSecondsToShow }
							label={ __( 'Number of Seconds', 'spectra-pro' ) }
							onDeselect={ () => setAttributes( { noOfSecondsToShow: 5 } ) }
							resetAllFilter={ () => ( {
								noOfSecondsToShow: 5,
							} ) }
							isShownByDefault
							panelId={clientId}
						>
							 <RangeControl
								__nextHasNoMarginBottom
								__next40pxDefaultSize
								initialPosition={ 5 }
								label={ __( 'Number of Seconds', 'spectra-pro' ) }
								max={ 1000 }
								min={ 0 }
								value={ noOfSecondsToShow }
								onChange={ ( value ) =>
									setAttributes( {
										noOfSecondsToShow: value
									} )
								}
							/>
						</ToolsPanelItem>
                    ) }
					<ToolsPanelItem
						hasValue={ () => !! enableCookies }
						label={ __( 'Enable Cookies', 'spectra-pro' ) }
						onDeselect={ () => setAttributes( { enableCookies: false } ) }
						resetAllFilter={ () => ( {
							enableCookies: false,
						} ) }
						isShownByDefault
						panelId={clientId}
					>
						<ToggleControl
							label={ __( 'Enable Cookies', 'spectra-pro' ) }
							checked={ enableCookies }
							onChange={ () =>
								setAttributes( {
									enableCookies: ! enableCookies,
								} )
							}
						/>
					</ToolsPanelItem>
                    { enableCookies && (
                        <>
							<ToolsPanelItem
								hasValue={ () => !! setCookiesOn }
								label={ __( 'Set Cookies on', 'spectra-pro' ) }
								onDeselect={ () => setAttributes( { setCookiesOn: 'close-action' } ) }
								resetAllFilter={ () => ( {
									setCookiesOn: 'close-action',
								} ) }
								isShownByDefault
								panelId={clientId}
							>
 								<SelectControl
									label={ __( 'Set Cookies on', 'spectra-pro' ) }
									value={ setCookiesOn }
									help={ __(
										'Choose an action on which you want to set cookies to hide the popup for number of days.',
										'spectra-pro'
									) }
									options={ [
										{ value: 'close-action', label: __( 'Close Action', 'spectra-pro' ) },
										{ value: 'page-refresh', label: __( 'Page Refresh', 'spectra-pro' ) },
									] }
									onChange={ ( value ) => setAttributes( { setCookiesOn: value } ) }
								/>
							</ToolsPanelItem>
							<ToolsPanelItem
								hasValue={ () => !! hideForDays }
								label={ __( 'Hide for number of days', 'spectra-pro' ) }
								onDeselect={ () => setAttributes( { hideForDays: 2 } ) }
								resetAllFilter={ () => ( {
									hideForDays: 2,
								} ) }
								isShownByDefault
								panelId={clientId}
							>
								<RangeControl
									__nextHasNoMarginBottom
									__next40pxDefaultSize
									initialPosition={ 2 }
									label={ __( 'Hide for number of days', 'spectra-pro' ) }
									max={ 1000 }
									min={ 0 }
									value={ hideForDays }
									onChange={ ( value ) =>
										setAttributes( {
											hideForDays: value
										} )
									}
								/>
							</ToolsPanelItem>
                        </>
                    )}
                </>
            )}
		</>
	);
};

/**
 * Get Close Button Position Options (Pro)
 *
 * Returns an array of close button position options for modals,
 * disabling specific positions based on the modal's position and open behavior.
 *
 * @param {Object} attributes - Modal block attributes.
 * @return {Array<Object>} Array of close button position options with `value`, `label`, and `disabled` state.
 */
export const SpectraProCloseButtonChildOptions = ( attributes = {} ) => {
	const { openModalAs, modalPosition } = attributes;

	// Set of values to disable
	const disabledValues = new Set();

	// For off-canvas modals, disable based on openModalAs only (primary rule)
	if ( openModalAs === 'left-off-canvas' ) {
		disabledValues.add( 'popup-top-left' );
		disabledValues.add( 'window-top-left' );
	} else if ( openModalAs === 'right-off-canvas' ) {
		disabledValues.add( 'popup-top-right' );
		disabledValues.add( 'window-top-right' );
	} else if ( openModalAs === 'popup' ) {
		// For popup modals, disable based on modalPosition only when it's popup
		if ( modalPosition === 'top-left' ) {
			disabledValues.add( 'popup-top-left' );
			disabledValues.add( 'window-top-left' );
		} else if ( modalPosition === 'top-right' ) {
			disabledValues.add( 'popup-top-right' );
			disabledValues.add( 'window-top-right' );
		}
	}

	// Return directly usable options
	return [
		{
			value: 'popup-top-left',
			disabled: disabledValues.has( 'popup-top-left' ),
			label: __( 'Top Left', 'spectra-pro' ),
		},
		{
			value: 'popup-top-right',
			disabled: disabledValues.has( 'popup-top-right' ),
			label: __( 'Top Right', 'spectra-pro' ),
		},
		{
			value: 'window-top-left',
			disabled: disabledValues.has( 'window-top-left' ),
			label: __( 'Window - Top Left', 'spectra-pro' ),
		},
		{
			value: 'window-top-right',
			disabled: disabledValues.has( 'window-top-right' ),
			label: __( 'Window - Top Right', 'spectra-pro' ),
		},
	];
};
