import { useRef, useEffect } from '@wordpress/element';
import { CuiSlider } from '@cliqthemes/cliq-slider-control';
// @wordpress/scripts' webpack config only merges CSS into the enqueued
// "style-index.css" bundle when its source file is literally named
// style.(s)css (see the `style` cacheGroup test in its webpack.config.js) —
// this vendor CSS lands in the SEPARATE "index.css" chunk instead, regardless
// of whether it's imported from here or from a consumer's own style.scss (a
// plain .css import isn't inlined by Sass either way). Each consumer must
// additionally enqueue its own build's index.css alongside style-index.css.
import '@cliqthemes/cliq-slider-control/style.css';

/**
 * Shared slider control — wraps @cliqthemes/cliq-slider-control around a plain
 * <input>, replacing the native <input type="range"> used for the `range`
 * search-form field and the Distance widget's slider mode. Same lifecycle
 * shape as GlideSelect (frontend/src/widgets.js): a mount-once init effect
 * creates the instance on the ref'd input, separate effects push bounds/value
 * changes into the live instance rather than recreating it, destroy() on
 * unmount. Unlike GlideSelect's vendored `window.Glide` global, this is a real
 * ESM import (no polling-for-global needed).
 *
 * The library mounts ONTO the existing <input> (its value stays in sync), so
 * server-rendered markup (a plain native range input) degrades gracefully
 * before this enhances it — no SSR markup changes are needed anywhere this is
 * used.
 */
const SliderControl = ( { min = 0, max = 100, step = 1, value, onChange, className, hookClass, disabled = false } ) => {
	const inputRef = useRef( null );
	const sliderRef = useRef( null );
	const onChangeRef = useRef( onChange );
	onChangeRef.current = onChange;

	useEffect( () => {
		if ( ! inputRef.current ) return undefined;
		// CuiSlider hides the original <input> and builds a new sibling DOM tree
		// (its `dom.root`) — className is CuiSlider's OWN constructor option for
		// tagging that visible root, the only way a per-field generated CSS rule
		// (see the consumer's Slider-settings style panel) can ever reach it.
		const instance = new CuiSlider( inputRef.current, {
			min,
			max,
			step,
			value: value ?? min,
			enabled: ! disabled,
			className: hookClass || undefined,
		} );
		instance.on( 'change', ( { newValue } ) => onChangeRef.current?.( newValue ) );
		sliderRef.current = instance;
		return () => {
			instance.destroy();
			sliderRef.current = null;
		};
		// eslint-disable-next-line react-hooks/exhaustive-deps -- mount once; bounds/value sync via the effects below
	}, [] );

	useEffect( () => {
		if ( ! sliderRef.current ) return;
		sliderRef.current.setOption( 'min', min );
		sliderRef.current.setOption( 'max', max );
		sliderRef.current.setOption( 'step', step );
	}, [ min, max, step ] );

	useEffect( () => {
		if ( ! sliderRef.current || value === undefined || value === null ) return;
		if ( sliderRef.current.getValue() !== value ) sliderRef.current.setValue( value );
	}, [ value ] );

	useEffect( () => {
		if ( ! sliderRef.current ) return;
		if ( disabled ) sliderRef.current.disable();
		else sliderRef.current.enable();
	}, [ disabled ] );

	return <input ref={ inputRef } type="text" className={ className } defaultValue={ value ?? min } readOnly />;
};

export default SliderControl;
