/**
 * Shared shadow control — toggle on/off, preview swatch, popup with sliders + color.
 */
import {
	ColorIndicator,
	Dropdown,
	RangeControl,
	ToggleControl,
	__experimentalDropdownContentWrapper as DropdownContentWrapper,
} from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import {
	DEFAULT_CUSTOM_SHADOW,
	DEFAULT_SHADOW_COLOR,
	composeCustomShadow,
	inferShadowPreset,
	parseCustomShadow,
} from '../styleFieldDefaults';
import ThemeColorPalette from './ThemeColorPalette';
/**
 * @param {object}   props
 * @param {string}   [props.label]
 * @param {string}   props.preset        none|natural|deep|sharp|soft|custom
 * @param {string}   props.color
 * @param {string}   props.css           Composed / custom box-shadow CSS
 * @param {Function} props.onChange      ({ preset, color, css }) => void
 * @param {Array}    [props.colorPalettes]
 * @param {string}   [props.className]
 */
export default function ShadowFields( {
	label = __( 'Shadow', 'joc-blockora-morph' ),
	preset: presetProp,
	color: colorProp,
	css: cssProp,
	onChange,
	colorPalettes = [],
	className = '',
} ) {
	const css = cssProp || 'none';
	const knownPresets = new Set( [
		'none',
		'natural',
		'deep',
		'sharp',
		'soft',
		'custom',
	] );
	const preset = knownPresets.has( presetProp )
		? presetProp
		: inferShadowPreset( css ) || 'none';
	const enabled = preset !== 'none' && css !== 'none' && Boolean( css );
	const color = colorProp || DEFAULT_SHADOW_COLOR;
	const offsets =
		enabled && css && css !== 'none'
			? parseCustomShadow( css )
			: { ...DEFAULT_CUSTOM_SHADOW };

	const emit = ( nextPreset, nextColor, nextCustom ) => {
		const p = nextPreset || 'none';
		const c = nextColor || DEFAULT_SHADOW_COLOR;
		if ( p === 'none' ) {
			onChange( {
				preset: 'none',
				color: c,
				css: 'none',
			} );
			return;
		}
		const parts =
			typeof nextCustom === 'object' && nextCustom !== null
				? nextCustom
				: parseCustomShadow(
						typeof nextCustom === 'string' ? nextCustom : css
				  );
		const composed = composeCustomShadow( parts, c );
		onChange( {
			preset: 'custom',
			color: c,
			css: composed || 'none',
		} );
	};

	const previewShadow = enabled
		? composeCustomShadow( offsets, color )
		: 'none';

	return (
		<div className={ `bm-shadow-fields ${ className }`.trim() }>
			<div className="bm-shadow-fields__head">
				<span className="bm-shadow-fields__label">{ label }</span>
				<ToggleControl
					className="bm-shadow-fields__toggle"
					checked={ enabled }
					onChange={ ( next ) => {
						if ( next ) {
							const seed =
								css && css !== 'none'
									? parseCustomShadow( css )
									: { ...DEFAULT_CUSTOM_SHADOW };
							emit(
								'custom',
								color || DEFAULT_SHADOW_COLOR,
								seed
							);
							return;
						}
						emit( 'none', color, null );
					} }
					label={
						enabled
							? __( 'On', 'joc-blockora-morph' )
							: __( 'Off', 'joc-blockora-morph' )
					}
					__nextHasNoMarginBottom
				/>
			</div>

			{ enabled ? (
				<Dropdown
					className="bm-shadow-fields__box-dropdown"
					popoverProps={ {
						placement: 'bottom-start',
						offset: 8,
					} }
					renderToggle={ ( { isOpen, onToggle } ) => (
						<button
							type="button"
							className={
								'bm-shadow-fields__box' +
								( isOpen ? ' is-open' : '' )
							}
							onClick={ onToggle }
							aria-expanded={ isOpen }
							aria-label={ __(
								'Edit shadow',
								'joc-blockora-morph'
							) }
						>
							<span
								className="bm-shadow-fields__box-surface"
								style={ { boxShadow: previewShadow } }
								aria-hidden="true"
							/>
						</button>
					) }
					renderContent={ () => (
						<DropdownContentWrapper paddingSize="medium">
							<div className="bm-shadow-fields__popover">
								<p className="bm-shadow-fields__popover-title">
									{ __( 'Shadow', 'joc-blockora-morph' ) }
								</p>
								<RangeControl
									label={ __(
										'Horizontal',
										'joc-blockora-morph'
									) }
									value={ offsets.x }
									onChange={ ( next ) =>
										emit( 'custom', color, {
											...offsets,
											x: next ?? 0,
										} )
									}
									min={ -40 }
									max={ 40 }
									__next40pxDefaultSize
									__nextHasNoMarginBottom
								/>
								<RangeControl
									label={ __(
										'Vertical',
										'joc-blockora-morph'
									) }
									value={ offsets.y }
									onChange={ ( next ) =>
										emit( 'custom', color, {
											...offsets,
											y: next ?? 0,
										} )
									}
									min={ -40 }
									max={ 40 }
									__next40pxDefaultSize
									__nextHasNoMarginBottom
								/>
								<RangeControl
									label={ __( 'Blur', 'joc-blockora-morph' ) }
									value={ offsets.blur }
									onChange={ ( next ) =>
										emit( 'custom', color, {
											...offsets,
											blur: next ?? 0,
										} )
									}
									min={ 0 }
									max={ 80 }
									__next40pxDefaultSize
									__nextHasNoMarginBottom
								/>
								<RangeControl
									label={ __( 'Spread', 'joc-blockora-morph' ) }
									value={ offsets.spread }
									onChange={ ( next ) =>
										emit( 'custom', color, {
											...offsets,
											spread: next ?? 0,
										} )
									}
									min={ -40 }
									max={ 40 }
									__next40pxDefaultSize
									__nextHasNoMarginBottom
								/>
								<div className="bm-shadow-fields__color">
									<span className="bm-shadow-fields__color-label">
										{ __( 'Color', 'joc-blockora-morph' ) }
									</span>
									<div className="bm-shadow-fields__color-row">
										<ColorIndicator
											colorValue={ color || undefined }
										/>
										<span className="bm-shadow-fields__color-value">
											{ color ||
												DEFAULT_SHADOW_COLOR }
										</span>
									</div>
									<ThemeColorPalette
										palettes={ colorPalettes }
										value={ color || '' }
										onChange={ ( next ) =>
											emit(
												'custom',
												next == null ||
													String( next ).trim() ===
														''
													? DEFAULT_SHADOW_COLOR
													: next,
												offsets
											)
										}
										clearable
										enableAlpha
									/>
								</div>
							</div>
						</DropdownContentWrapper>
					) }
				/>
			) : null }
		</div>
	);
}
