// Import necessary WordPress modules.
const { __ } = wp.i18n;
const { SelectControl, RangeControl } = wp.components;

// Import custom helpers and components.
import { getRangeLimitsByUnitForWidth } from '../block/helpers';
import DeviceSwitcher from './DeviceSwitcher';
import { useDevice } from './DeviceContext';

// Define allowed units for custom width control.
const allowedUnits = [ 'px', '%', 'vw', 'em', 'rem' ];

/**
 * WidthControl Component.
 *
 * This component allows the user to configure width settings for a section/block.
 * It supports three width types: full, inline, and custom, with device-specific control.
 *
 * Props:
 * @param {string} label - The display label for the width setting.
 * @param {string} widthType - The current selected width type ('full', 'inline', 'custom').
 * @param {Function} setWidthType - Setter function to update the width type.
 * @param {Object} sectionWidth - Object holding width values per device.
 * @param {Function} setSectionWidth - Setter to update device-specific width values.
 * @param {string} sectionWidthUnit - The unit used for width values.
 * @param {Function} setSectionWidthUnit - Setter function for width unit.
 */
const WidthControl = ({
  label = __( 'Width', 'journey-timeline-block' ),
  widthType,
  setWidthType,
  sectionWidth = {},
  setSectionWidth,
  sectionWidthUnit = 'px',
  setSectionWidthUnit
}) => {

  const { activeDevice } = useDevice();

  /**
   * Handle changes to width type dropdown.
   */
  const handleWidthTypeChange = ( value ) => {
    setWidthType( value );

    // If full width selected, apply 100% width.
    if ( 'full' === value ) {
      setSectionWidth({ desktop: 100, tablet: 100, mobile: 100 });
      setSectionWidthUnit( '%' );
    } else if ( 'inline' === value ) { // If inline width selected, use 'auto' sizing.
      setSectionWidth({ desktop: 'auto', tablet: 'auto', mobile: 'auto' });
    }
  };

  /**
   * Handle changes to unit type.
   * Only desktop unit is editable for consistency.
   */
  const handleUnitChange = ( unit ) => {
    if ( 'desktop' === activeDevice ) {
      setSectionWidthUnit( unit );
    }
  };

  /**
   * Handle width value change for the active device.
   */
  const handleWidthValueChange = ( value ) => {
    setSectionWidth({
      ...sectionWidth,
      [activeDevice]: value
    });
  };

  // Format unit options for dropdown.
  const unitOptions = allowedUnits.map( ( unit ) => ({
    label: unit,
    value: unit
  }) );

  // Define width type options.
  const widthOptions = [
    { label: 'Default', value: '' },
    { label: 'Full Width (100%)', value: 'full' },
    { label: 'Inline (auto)', value: 'inline' },
    { label: 'Custom Width', value: 'custom' }
  ];

  // Get the selected width type label for rendering.
  const selectedWidthLabel = widthOptions.find( opt => opt.value === widthType )?.label;

  // Get allowed range limits for current unit.
  const { min, max } = getRangeLimitsByUnitForWidth( sectionWidthUnit );

  return (
    <>
      {/* Main width type dropdown. */}
      <div className="ojb-label-wrap">
        <label className="components-base-control__label">{label}</label>
        <SelectControl
          value={widthType}
          options={widthOptions}
          onChange={handleWidthTypeChange}
        />
      </div>

      {/* If custom width selected, show range and unit controls. */}
      {'custom' === widthType && (
        <div className="ojb-custom-width-settings">
          {/* Unit selector and responsive device switcher. */}
          <div className="ojb-label-wrap">
            <label className="components-base-control__label">{selectedWidthLabel}</label>
            <SelectControl
              className="sel_unit"
              value={sectionWidthUnit}
              options={unitOptions}
              onChange={handleUnitChange}
              disabled={'desktop' !== activeDevice} // Restrict unit change to desktop.
            />
            <div className="ojb-responsive-tabs">
              <DeviceSwitcher/>
            </div>
          </div>

          {/* Range input for setting width value per device. */}
          <div className="ojb-input-wrap">
            <RangeControl
              value={parseFloat( sectionWidth?.[activeDevice]) || 0}
              onChange={handleWidthValueChange}
              min={min}
              max={max}
              step={'em' === sectionWidthUnit || 'rem' === sectionWidthUnit ? 0.1 : 1}
            />
          </div>
        </div>
      )}
    </>
  );
};

export default WidthControl;
