/**
 * External dependencies.
 */
import { InspectorControls, BlockControls } from '@wordpress/block-editor';
import {
	__experimentalToolsPanel as ToolsPanel,
	__experimentalToolsPanelItem as ToolsPanelItem,
	__experimentalToggleGroupControl as ToggleGroupControl,
	__experimentalToggleGroupControlOption as ToggleGroupControlOption,
	TextControl,
	ToggleControl,
	RangeControl,
	Toolbar,
	ToolbarButton,
} from '@wordpress/components';
import { useEffect, useState } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { resetEvergreenCookies } from './helpers';

/**
 * Timer type settings panel component.
 *
 * @since x.x.x
 *
 * @param {*}      defaultValue Default value to return if props are not provided.
 * @param {Object} props        Component properties.
 * @return {Element} Timer settings panel elements.
 */
export const TimerSettings = ( defaultValue, props ) => {
	if ( ! props ) {
		return defaultValue;
	}

	const {
		attributes: { timerType, uniqueId },
		setAttributes,
		clientId,
	} = props;

	return (
		<>
			{ /*
			 * Timer Type Control Panel Item
			 * Allows selection between date-based and evergreen timer types
			 * - Default value: 'date'
			 * - Shows reset option when value differs from default
			 * - Automatically generates unique ID when switching to evergreen
			 * @see https://developer.wordpress.org/block-editor/reference-guides/components/tools-panel/
			 */ }
			<ToolsPanelItem
				hasValue={ () => timerType !== 'date' }
				label={ __( 'Timer Type', 'spectra-pro' ) }
				onDeselect={ () => setAttributes( { timerType: 'date' } ) }
				isShownByDefault
				panelId={ clientId }
			>
				{ /* Timer Type Control */ }
				<ToggleGroupControl
					__next40pxDefaultSize
					__nextHasNoMarginBottom
					isBlock
					label={ __( 'Timer Type', 'spectra-pro' ) }
					value={ timerType || 'date' }
					onChange={ ( value ) => {
						setAttributes( { timerType: value } );

						if ( 'evergreen' === value && ! uniqueId ) {
							setAttributes( {
								uniqueId: clientId + '_' + Date.now(),
							} );
						}
					} }
					help={ __( 'Choose the type of countdown timer to display.', 'spectra-pro' ) }
				>
					<ToggleGroupControlOption label={ __( 'Date', 'spectra-pro' ) } value="date" />
					<ToggleGroupControlOption label={ __( 'Evergreen', 'spectra-pro' ) } value="evergreen" />
				</ToggleGroupControl>
			</ToolsPanelItem>
			{ timerType === 'evergreen' && <EvergreenSettings { ...props } /> }
		</>
	);
};

/**
 * Evergreen timer settings panel component.
 *
 * @since x.x.x
 *
 * @param {Object} props Component properties.
 * @return {Element} Evergreen timer settings panel elements.
 */
export const EvergreenSettings = ( props ) => {
	const {
		attributes: { evergreenDays, evergreenHours, evergreenMinutes, resetAfterDays, uniqueId },
		setAttributes,
		clientId,
	} = props;

	const [ localDays, setLocalDays ] = useState( evergreenDays );
	const [ localHours, setLocalHours ] = useState( evergreenHours );
	const [ localMinutes, setLocalMinutes ] = useState( evergreenMinutes );
	const [ localResetDays, setLocalResetDays ] = useState( resetAfterDays );

	useEffect( () => {
		setLocalDays( evergreenDays );
	}, [ evergreenDays ] );

	useEffect( () => {
		setLocalHours( evergreenHours );
	}, [ evergreenHours ] );

	useEffect( () => {
		setLocalMinutes( evergreenMinutes );
	}, [ evergreenMinutes ] );

	useEffect( () => {
		setLocalResetDays( resetAfterDays );
	}, [ resetAfterDays ] );

	return (
		<>
			{ /*
			 * Evergreen Timer Duration Settings Panel
			 * Contains controls for configuring the evergreen timer duration:
			 * - Days (0-365)
			 * - Hours (0-23)
			 * - Minutes (0-59)
			 * - Reset period (0-365 days)
			 * Resets cookies when duration values change
			 */ }
			<ToolsPanelItem
				hasValue={ () => evergreenDays !== 0 }
				label={ __( 'Days', 'spectra-pro' ) }
				onDeselect={ () => setAttributes( { evergreenDays: 0 } ) }
				isShownByDefault
				panelId={ clientId }
			>
				<RangeControl
					label={ __( 'Days', 'spectra-pro' ) }
					value={ Number( localDays ) || 0 }
					onChange={ ( value ) => {
						const newValue = Number( value );
						setLocalDays( newValue );
						setAttributes( { evergreenDays: newValue } );
						resetEvergreenCookies( uniqueId );
					} }
					min={ 0 }
					max={ 365 }
					step={ 1 }
				/>
			</ToolsPanelItem>

			{ /*
			 * Evergreen Hours Control Panel Item
			 * Configures the number of hours for the evergreen timer duration
			 * - Range: 0-23 hours
			 * - Default value: 0
			 * - Resets cookies when value changes
			 */ }
			<ToolsPanelItem
				hasValue={ () => evergreenHours !== 0 }
				label={ __( 'Hours', 'spectra-pro' ) }
				onDeselect={ () => setAttributes( { evergreenHours: 0 } ) }
				isShownByDefault
				panelId={ clientId }
			>
				<RangeControl
					label={ __( 'Hours', 'spectra-pro' ) }
					value={ Number( localHours ) || 0 }
					onChange={ ( value ) => {
						const newValue = Number( value );
						setLocalHours( newValue );
						setAttributes( { evergreenHours: newValue } );
						resetEvergreenCookies( uniqueId );
					} }
					min={ 0 }
					max={ 23 }
					step={ 1 }
				/>
			</ToolsPanelItem>

			{ /*
			 * Evergreen Minutes Control Panel Item
			 * Configures the number of minutes for the evergreen timer duration
			 * - Range: 0-59 minutes
			 * - Default value: 0
			 * - Resets cookies when value changes
			 */ }
			<ToolsPanelItem
				hasValue={ () => evergreenMinutes !== 0 }
				label={ __( 'Minutes', 'spectra-pro' ) }
				onDeselect={ () => setAttributes( { evergreenMinutes: 0 } ) }
				isShownByDefault
				panelId={ clientId }
			>
				<RangeControl
					label={ __( 'Minutes', 'spectra-pro' ) }
					value={ Number( localMinutes ) || 0 }
					onChange={ ( value ) => {
						const newValue = Number( value );
						setLocalMinutes( newValue );
						setAttributes( { evergreenMinutes: newValue } );
						resetEvergreenCookies( uniqueId );
					} }
					min={ 0 }
					max={ 59 }
					step={ 1 }
				/>
			</ToolsPanelItem>

			{ /*
			 * Timer Reset Period Control Panel Item
			 * Configures the number of days until the timer automatically resets
			 * - Range: 0-365 days
			 * - Default value: 0 (immediate reset)
			 * - 0 = reset immediately after expiration
			 */ }
			<ToolsPanelItem
				hasValue={ () => resetAfterDays !== 0 }
				label={ __( 'Reset After (Days)', 'spectra-pro' ) }
				onDeselect={ () => setAttributes( { resetAfterDays: 0 } ) }
				isShownByDefault
				panelId={ clientId }
			>
				<RangeControl
					label={ __( 'Reset After (Days)', 'spectra-pro' ) }
					value={ Number( localResetDays ) || 0 }
					onChange={ ( value ) => {
						const newValue = Number( value );
						setLocalResetDays( newValue );
						setAttributes( { resetAfterDays: newValue } );
					} }
					min={ 0 }
					max={ 365 }
					step={ 1 }
					help={ __(
						'Number of days to wait until the evergreen is reset for visitors. If set to 0, the timer restarts immediately after expiring.',
						'spectra-pro'
					) }
				/>
			</ToolsPanelItem>
		</>
	);
};

/**
 * Timer expiry settings panel component.
 *
 * @since x.x.x
 *
 * @param {*}      defaultValue Default value to return if props are not provided.
 * @param {Object} props        Component properties.
 * @return {Element} Expiry settings panel elements.
 */
export const ExpirySettings = ( defaultValue, props ) => {
	if ( ! props ) {
		return defaultValue;
	}

	const {
		attributes: { timerEndAction, redirectURL, reloadRequired, autoReload },
		setAttributes,
		clientId,
	} = props;

	return (
		<>
			{ /* Toolbar for Expired and Live mode. */ }
			<ToolbarSettings { ...props } />
			<InspectorControls group="settings">
				{ /*
				 * Expiry Settings Tools Panel
				 * Contains all timer expiration behavior controls including:
				 * - End action selection
				 * - Redirect URL configuration
				 * - Content replacement settings
				 * Resets all expiry settings to defaults when "Reset All" is clicked
				 * Default values:
				 * - timerEndAction: 'zero'
				 * - redirectURL: ''
				 * - reloadRequired: true
				 * - autoReload: false
				 */ }
				<ToolsPanel
					label={ __( 'Expiry Settings', 'spectra-pro' ) }
					resetAll={ () => {
						setAttributes( {
							timerEndAction: 'zero',
							redirectURL: '',
							reloadRequired: true,
							autoReload: false,
						} );
					} }
					panelId={ clientId }
				>
					{ /*
					 * Timer End Action Control Panel Item
					 * Configures what happens when the countdown timer expires
					 * Options:
					 * - 'zero': Keep timer at 00:00:00
					 * - 'hide': Hide the timer completely
					 * - 'redirect': Redirect to specified URL
					 * - 'replace': Replace with alternative content
					 * Default value: 'zero'
					 */ }
					<ToolsPanelItem
						hasValue={ () => timerEndAction !== 'zero' }
						label={ __( 'Timer End Action', 'spectra-pro' ) }
						onDeselect={ () => setAttributes( { timerEndAction: 'zero' } ) }
						isShownByDefault
						panelId={ clientId }
					>
						<ToggleGroupControl
							__next40pxDefaultSize
							__nextHasNoMarginBottom
							isBlock
							label={ __( 'Timer End Action', 'spectra-pro' ) }
							value={ timerEndAction || 'zero' }
							onChange={ ( value ) => {
								if ( 'replace' !== value ) {
									setAttributes( { editorInnerBlocksPreview: false } );
								}

								setAttributes( { timerEndAction: value } );
							} }
							help={ __(
								'For a better editing experience, expiry options work only on frontend.',
								'spectra-pro'
							) }
						>
							<ToggleGroupControlOption label={ __( 'Keep', 'spectra-pro' ) } value="zero" />
							<ToggleGroupControlOption label={ __( 'Hide', 'spectra-pro' ) } value="hide" />
							<ToggleGroupControlOption label={ __( 'Redirect', 'spectra-pro' ) } value="redirect" />
							<ToggleGroupControlOption label={ __( 'Replace', 'spectra-pro' ) } value="replace" />
						</ToggleGroupControl>
					</ToolsPanelItem>
					{ timerEndAction === 'redirect' && (
						/*
						 * Redirect URL Control Panel Item
						 * Configures the destination URL for redirect action
						 * - Only shown when timerEndAction is 'redirect'
						 * - Validates URL format
						 * - Default value: empty string
						 */
						<ToolsPanelItem
							hasValue={ () => redirectURL !== '' }
							label={ __( 'Redirect URL', 'spectra-pro' ) }
							onDeselect={ () => setAttributes( { redirectURL: '' } ) }
							isShownByDefault
							panelId={ clientId }
						>
							<TextControl
								label={ __( 'Redirect URL', 'spectra-pro' ) }
								value={ redirectURL }
								onChange={ ( value ) => setAttributes( { redirectURL: value } ) }
								placeholder={ __( 'https://example.com', 'spectra-pro' ) }
							/>
						</ToolsPanelItem>
					) }
					{ timerEndAction === 'replace' && (
						<>
							{ /*
							 * Reload Required Control Panel Item
							 * Configures whether page reload is needed to show replaced content
							 * - Only shown when timerEndAction is 'replace'
							 * - Default value: true
							 * - true: Content only appears after reload (recommended)
							 * - false: Content is hidden but present in DOM
							 */ }
							<ToolsPanelItem
								hasValue={ () => reloadRequired !== true }
								label={ __( 'Reload Required', 'spectra-pro' ) }
								onDeselect={ () => setAttributes( { reloadRequired: true } ) }
								isShownByDefault
								panelId={ clientId }
							>
								<ToggleControl
									label={ __( 'Reload Required', 'spectra-pro' ) }
									checked={ reloadRequired }
									onChange={ ( value ) =>
										setAttributes( {
											reloadRequired: value,
										} )
									}
									help={
										reloadRequired
											? __(
													'Recommended: Expired content is only rendered after reload when countdown expires.',
													'spectra-pro'
											  )
											: __(
													'Expired content is rendered but visibly hidden until countdown expires.',
													'spectra-pro'
											  )
									}
								/>
							</ToolsPanelItem>

							{ reloadRequired && (
								/*
								 * Auto Reload Control Panel Item
								 * Configures automatic page reload when timer expires
								 * - Only shown when reloadRequired is true
								 * - Default value: false
								 */
								<ToolsPanelItem
									hasValue={ () => autoReload !== false }
									label={ __( 'Automatically Reload', 'spectra-pro' ) }
									onDeselect={ () => setAttributes( { autoReload: false } ) }
									isShownByDefault
									panelId={ clientId }
								>
									<ToggleControl
										label={ __( 'Automatically Reload', 'spectra-pro' ) }
										checked={ autoReload }
										onChange={ ( value ) =>
											setAttributes( {
												autoReload: value,
											} )
										}
										help={ __( 'Automatically reload the page when timer ends.', 'spectra-pro' ) }
									/>
								</ToolsPanelItem>
							) }
						</>
					) }
				</ToolsPanel>
			</InspectorControls>
		</>
	);
};

/**
 * Toolbar controls for previewing timer states.
 *
 * @since x.x.x
 *
 * @param {Object} props Component properties.
 * @return {Element|null} Toolbar controls or null if not applicable.
 */
const ToolbarSettings = ( props ) => {
	const {
		attributes: { timerEndAction, editorInnerBlocksPreview },
		setAttributes,
	} = props;

	if ( 'replace' !== timerEndAction ) {
		return null;
	}

	return (
		<>
			<BlockControls>
				<Toolbar>
					<ToolbarButton
						text={ __( 'Live', 'spectra-pro' ) }
						label={ __( 'Live', 'spectra-pro' ) }
						isActive={ ! editorInnerBlocksPreview }
						onClick={ () => setAttributes( { editorInnerBlocksPreview: false } ) }
					/>
					<ToolbarButton
						text={ __( 'Expired', 'spectra-pro' ) }
						label={ __( 'Expired', 'spectra-pro' ) }
						isActive={ editorInnerBlocksPreview }
						onClick={ () => setAttributes( { editorInnerBlocksPreview: true } ) }
					/>
				</Toolbar>
			</BlockControls>
		</>
	);
};
