/**
 * WordPress dependencies
 */
import { Button, Icon, RangeControl, __experimentalHStack as HStack, __experimentalUnitControl as UnitControl, __experimentalUseCustomUnits as useCustomUnits, __experimentalParseQuantityAndUnitFromRawValue as parseQuantityAndUnitFromRawValue, CustomSelectControl } from '@wordpress/components';
import { useSelect } from '@wordpress/data';
import { useState, useMemo } from '@wordpress/element';
import { usePrevious } from '@wordpress/compose';
import { __, _x, sprintf } from '@wordpress/i18n';
import { settings } from '@wordpress/icons';

/**
 * Internal dependencies
 */
import { useSettings } from '../../use-settings';
import { store as blockEditorStore } from '../../../store';
import { RANGE_CONTROL_MAX_SIZE, ALL_SIDES, LABELS, getSliderValueFromPreset, getCustomValueFromPreset, getPresetValueFromCustomValue, isValueSpacingPreset } from '../utils';
import { jsx as _jsx } from "react/jsx-runtime";
import { Fragment as _Fragment } from "react/jsx-runtime";
import { jsxs as _jsxs } from "react/jsx-runtime";
const CUSTOM_VALUE_SETTINGS = {
  px: {
    max: 300,
    steps: 1
  },
  '%': {
    max: 100,
    steps: 1
  },
  vw: {
    max: 100,
    steps: 1
  },
  vh: {
    max: 100,
    steps: 1
  },
  em: {
    max: 10,
    steps: 0.1
  },
  rm: {
    max: 10,
    steps: 0.1
  },
  svw: {
    max: 100,
    steps: 1
  },
  lvw: {
    max: 100,
    steps: 1
  },
  dvw: {
    max: 100,
    steps: 1
  },
  svh: {
    max: 100,
    steps: 1
  },
  lvh: {
    max: 100,
    steps: 1
  },
  dvh: {
    max: 100,
    steps: 1
  },
  vi: {
    max: 100,
    steps: 1
  },
  svi: {
    max: 100,
    steps: 1
  },
  lvi: {
    max: 100,
    steps: 1
  },
  dvi: {
    max: 100,
    steps: 1
  },
  vb: {
    max: 100,
    steps: 1
  },
  svb: {
    max: 100,
    steps: 1
  },
  lvb: {
    max: 100,
    steps: 1
  },
  dvb: {
    max: 100,
    steps: 1
  },
  vmin: {
    max: 100,
    steps: 1
  },
  svmin: {
    max: 100,
    steps: 1
  },
  lvmin: {
    max: 100,
    steps: 1
  },
  dvmin: {
    max: 100,
    steps: 1
  },
  vmax: {
    max: 100,
    steps: 1
  },
  svmax: {
    max: 100,
    steps: 1
  },
  lvmax: {
    max: 100,
    steps: 1
  },
  dvmax: {
    max: 100,
    steps: 1
  }
};
export default function SpacingInputControl({
  icon,
  isMixed = false,
  minimumCustomValue,
  onChange,
  onMouseOut,
  onMouseOver,
  showSideInLabel = true,
  side,
  spacingSizes,
  type,
  value
}) {
  var _CUSTOM_VALUE_SETTING, _CUSTOM_VALUE_SETTING2;
  // Treat value as a preset value if the passed in value matches the value of one of the spacingSizes.
  value = getPresetValueFromCustomValue(value, spacingSizes);
  let selectListSizes = spacingSizes;
  const showRangeControl = spacingSizes.length <= RANGE_CONTROL_MAX_SIZE;
  const disableCustomSpacingSizes = useSelect(select => {
    const editorSettings = select(blockEditorStore).getSettings();
    return editorSettings?.disableCustomSpacingSizes;
  });
  const [showCustomValueControl, setShowCustomValueControl] = useState(!disableCustomSpacingSizes && value !== undefined && !isValueSpacingPreset(value));
  const [minValue, setMinValue] = useState(minimumCustomValue);
  const previousValue = usePrevious(value);
  if (!!value && previousValue !== value && !isValueSpacingPreset(value) && showCustomValueControl !== true) {
    setShowCustomValueControl(true);
  }
  const [availableUnits] = useSettings('spacing.units');
  const units = useCustomUnits({
    availableUnits: availableUnits || ['px', 'em', 'rem']
  });
  let currentValue = null;
  const showCustomValueInSelectList = !showRangeControl && !showCustomValueControl && value !== undefined && (!isValueSpacingPreset(value) || isValueSpacingPreset(value) && isMixed);
  if (showCustomValueInSelectList) {
    selectListSizes = [...spacingSizes, {
      name: !isMixed ?
      // translators: %s: A custom measurement, e.g. a number followed by a unit like 12px.
      sprintf(__('Custom (%s)'), value) : __('Mixed'),
      slug: 'custom',
      size: value
    }];
    currentValue = selectListSizes.length - 1;
  } else if (!isMixed) {
    currentValue = !showCustomValueControl ? getSliderValueFromPreset(value, spacingSizes) : getCustomValueFromPreset(value, spacingSizes);
  }
  const selectedUnit = useMemo(() => parseQuantityAndUnitFromRawValue(currentValue), [currentValue])[1] || units[0]?.value;
  const setInitialValue = () => {
    if (value === undefined) {
      onChange('0');
    }
  };
  const customTooltipContent = newValue => value === undefined ? undefined : spacingSizes[newValue]?.name;
  const customRangeValue = parseFloat(currentValue, 10);
  const getNewCustomValue = newSize => {
    const isNumeric = !isNaN(parseFloat(newSize));
    const nextValue = isNumeric ? newSize : undefined;
    return nextValue;
  };
  const getNewPresetValue = (newSize, controlType) => {
    const size = parseInt(newSize, 10);
    if (controlType === 'selectList') {
      if (size === 0) {
        return undefined;
      }
      if (size === 1) {
        return '0';
      }
    } else if (size === 0) {
      return '0';
    }
    return `var:preset|spacing|${spacingSizes[newSize]?.slug}`;
  };
  const handleCustomValueSliderChange = next => {
    onChange([next, selectedUnit].join(''));
  };
  const allPlaceholder = isMixed ? __('Mixed') : null;
  const options = selectListSizes.map((size, index) => ({
    key: index,
    name: size.name
  }));
  const marks = spacingSizes.slice(1, spacingSizes.length - 1).map((_newValue, index) => ({
    value: index + 1,
    label: undefined
  }));
  const sideLabel = ALL_SIDES.includes(side) && showSideInLabel ? LABELS[side] : '';
  const typeLabel = showSideInLabel ? type?.toLowerCase() : type;
  const ariaLabel = sprintf(
  // translators: 1: The side of the block being modified (top, bottom, left etc.). 2. Type of spacing being modified (padding, margin, etc).
  _x('%1$s %2$s', 'spacing'), sideLabel, typeLabel).trim();
  return /*#__PURE__*/_jsxs(HStack, {
    className: "spacing-sizes-control__wrapper",
    children: [icon && /*#__PURE__*/_jsx(Icon, {
      className: "spacing-sizes-control__icon",
      icon: icon,
      size: 24
    }), showCustomValueControl && /*#__PURE__*/_jsxs(_Fragment, {
      children: [/*#__PURE__*/_jsx(UnitControl, {
        onMouseOver: onMouseOver,
        onMouseOut: onMouseOut,
        onFocus: onMouseOver,
        onBlur: onMouseOut,
        onChange: newSize => onChange(getNewCustomValue(newSize)),
        value: currentValue,
        units: units,
        min: minValue,
        placeholder: allPlaceholder,
        disableUnits: isMixed,
        label: ariaLabel,
        hideLabelFromVision: true,
        className: "spacing-sizes-control__custom-value-input",
        size: "__unstable-large",
        onDragStart: () => {
          if (value?.charAt(0) === '-') {
            setMinValue(0);
          }
        },
        onDrag: () => {
          if (value?.charAt(0) === '-') {
            setMinValue(0);
          }
        },
        onDragEnd: () => {
          setMinValue(minimumCustomValue);
        }
      }), /*#__PURE__*/_jsx(RangeControl, {
        __next40pxDefaultSize: true,
        onMouseOver: onMouseOver,
        onMouseOut: onMouseOut,
        onFocus: onMouseOver,
        onBlur: onMouseOut,
        value: customRangeValue,
        min: 0,
        max: (_CUSTOM_VALUE_SETTING = CUSTOM_VALUE_SETTINGS[selectedUnit]?.max) !== null && _CUSTOM_VALUE_SETTING !== void 0 ? _CUSTOM_VALUE_SETTING : 10,
        step: (_CUSTOM_VALUE_SETTING2 = CUSTOM_VALUE_SETTINGS[selectedUnit]?.steps) !== null && _CUSTOM_VALUE_SETTING2 !== void 0 ? _CUSTOM_VALUE_SETTING2 : 0.1,
        withInputField: false,
        onChange: handleCustomValueSliderChange,
        className: "spacing-sizes-control__custom-value-range",
        __nextHasNoMarginBottom: true,
        label: ariaLabel,
        hideLabelFromVision: true
      })]
    }), showRangeControl && !showCustomValueControl && /*#__PURE__*/_jsx(RangeControl, {
      __next40pxDefaultSize: true,
      onMouseOver: onMouseOver,
      onMouseOut: onMouseOut,
      className: "spacing-sizes-control__range-control",
      value: currentValue,
      onChange: newSize => onChange(getNewPresetValue(newSize)),
      onMouseDown: event => {
        // If mouse down is near start of range set initial value to 0, which
        // prevents the user have to drag right then left to get 0 setting.
        if (event?.nativeEvent?.offsetX < 35) {
          setInitialValue();
        }
      },
      withInputField: false,
      "aria-valuenow": currentValue,
      "aria-valuetext": spacingSizes[currentValue]?.name,
      renderTooltipContent: customTooltipContent,
      min: 0,
      max: spacingSizes.length - 1,
      marks: marks,
      label: ariaLabel,
      hideLabelFromVision: true,
      __nextHasNoMarginBottom: true,
      onFocus: onMouseOver,
      onBlur: onMouseOut
    }), !showRangeControl && !showCustomValueControl && /*#__PURE__*/_jsx(CustomSelectControl, {
      className: "spacing-sizes-control__custom-select-control",
      value:
      // passing empty string as a fallback to continue using the
      // component in controlled mode
      options.find(option => option.key === currentValue) || '',
      onChange: selection => {
        onChange(getNewPresetValue(selection.selectedItem.key, 'selectList'));
      },
      options: options,
      label: ariaLabel,
      hideLabelFromVision: true,
      size: "__unstable-large",
      onMouseOver: onMouseOver,
      onMouseOut: onMouseOut,
      onFocus: onMouseOver,
      onBlur: onMouseOut
    }), !disableCustomSpacingSizes && /*#__PURE__*/_jsx(Button, {
      label: showCustomValueControl ? __('Use size preset') : __('Set custom size'),
      icon: settings,
      onClick: () => {
        setShowCustomValueControl(!showCustomValueControl);
      },
      isPressed: showCustomValueControl,
      size: "small",
      className: "spacing-sizes-control__custom-toggle",
      iconSize: 24
    })]
  });
}
//# sourceMappingURL=spacing-input-control.js.map