import { useEffect, useState } from '@wordpress/element';
import { TextControl } from '@components/ui/TextControl';
import { DropdownPicker } from '@components/ui/DropdownPicker';
import { Popover } from '@components/ui/Popover';
import ButtonToggleGroup from '@components/ui/ButtonToggle';
import RangeControl from '@components/ui/RangeSlider';

import GridIcon from 'blockbite-icons/dist/Grid';
import PercentageIcon from 'blockbite-icons/dist/Percentage';
import TailwindUnitIcon from 'blockbite-icons/dist/Tailwind';
import SliderIcon from 'blockbite-icons/dist/Slider';
import has from 'lodash/has';

type MetricsControlProps = {
  defaultUnit: string;
  defaultValue: string;
  units?: string[] | 'native' | 'percent' | 'grid' | 'arbitrary' | 'all';
  inputClassName?: string;
  onValueChange: (value: string) => void;
  onUnitChange: (unit: string) => void;
};

const MetricsControl: React.FC<MetricsControlProps> = ({
  defaultUnit,
  defaultValue,
  onValueChange,
  onUnitChange,
  inputClassName = 'w-[75px]',
}) => {
  const [isVisible, setIsVisible] = useState(false);
  const [currentOptions, setCurrentOptions] = useState<string[]>([]);

  // Use local state for defaultUnit and defaultValue
  const [unit, setUnit] = useState(defaultUnit);
  const [value, setValue] = useState(defaultValue);

  // Set initial state from props
  useEffect(() => {
    setUnit(defaultUnit);
    setValue(defaultValue);
  }, [defaultUnit, defaultValue]);

  const showOptions = (unit: string) => {
    if (unit !== 'arbitrary' && has(blockbite.codex.units.spacing, unit)) {
      const options =
        blockbite.codex.units.spacing[
          unit as keyof typeof blockbite.codex.units.spacing
        ];
      setCurrentOptions(
        Array.isArray(options) ? options : Object.keys(options)
      );
    } else {
      setCurrentOptions([]);
    }
    setIsVisible(true);
  };

  const unitOptions = [
    {
      icon: <TailwindUnitIcon />,
      label: 'Tailwind CSS Units',
      value: 'native',
    },
    { icon: <PercentageIcon />, label: 'Percentage Units', value: 'percent' },
    { icon: <GridIcon />, label: 'Grid Units', value: 'grid' },
    { icon: <SliderIcon />, label: 'Pixel Units', value: 'arbitrary' },
  ];

  return (
    <div className="relative flex flex-col items-baseline">
      <TextControl
        inputClassName={inputClassName}
        defaultValue={unit === 'grid' ? value.replace('b_', '') : value}
        onClick={() => unit !== 'arbitrary' && showOptions(unit)}
        onChange={(newValue) => {
          setValue(newValue);
          onValueChange(newValue);
        }}
        readOnly={unit !== 'arbitrary'}
      >
        <Popover
          visible={isVisible}
          position="bottom left"
          className="w-[300px] bg-white shadow-sm"
          onVisibleChange={setIsVisible}
        >
          {unit === 'arbitrary' ? (
            <RangeControl
              defaultValue={value}
              label="Pixel Value"
              min={0}
              max={100}
              gridMode={true}
              showTooltip={false}
              onValueChange={(newValue: string) => {
                setValue(newValue);
                onValueChange(newValue);
              }}
            />
          ) : (
            <ButtonToggleGroup
              className="mt-4"
              options={currentOptions.map((option) => ({
                value: option,
                label: unit === 'grid' ? option.replace('b_', '') : option,
                onClick: () => {
                  setValue(option);
                  onValueChange(option);
                },
              }))}
              size="small"
              defaultPressed={value}
              onPressedChange={onValueChange}
            />
          )}
        </Popover>

        <DropdownPicker
          className="h-[32px]"
          defaultValue={unit}
          options={unitOptions}
          onPressedChange={(selectedUnit) => {
            setUnit(selectedUnit);
            onUnitChange(selectedUnit);
            showOptions(selectedUnit);
          }}
        />
      </TextControl>
    </div>
  );
};

export default MetricsControl;
