import { useEffect, useState, useContext } from '@wordpress/element';

import WidthIcon from 'blockbite-icons/dist/Width';
import HeightIcon from 'blockbite-icons/dist/Height';
import StopIcon from 'blockbite-icons/dist/Stop';

import MetricsControl from '@components/ui/MetricsControl';

import {
  optionsToDimensions,
  dimensionsToOptions,
} from '@components/DesignPanel/DynamicControls/DimensionHelpers';

import { ModifierPanelProps } from '@components/DesignPanel/types';
import { useActiveOptionValues } from '@components/DesignPanel/hooks/useActiveOptionvalue';
import { useStore } from 'zustand';
import { DesignContext } from '@components/DesignPanel/DesignStore';

const modifierIds = [
  'width',
  'minwidth',
  'maxwidth',
  'height',
  'minheight',
  'maxheight',
];

export const Dimension: React.FC<ModifierPanelProps> = ({ emitOptions }) => {
  const [values, setValues] = useState({
    width: { value: '', unit: 'arbitrary' },
    minwidth: { value: '', unit: 'arbitrary' },
    maxwidth: { value: '', unit: 'arbitrary' },
    height: { value: '', unit: 'arbitrary' },
    minheight: { value: '', unit: 'arbitrary' },
    maxheight: { value: '', unit: 'arbitrary' },
  });

  const store = useStore(useContext(DesignContext));

  const activeOptionValues = useActiveOptionValues(modifierIds, store);

  // set initial values
  useEffect(() => {
    const options = optionsToDimensions(activeOptionValues);
    setValues({ ...options });
  }, [activeOptionValues]);

  // update options
  useEffect(() => {
    const options = dimensionsToOptions(values);
    emitOptions(options);
  }, [values]);

  const handleUnitChange = (
    modifier:
      | 'width'
      | 'minwidth'
      | 'maxwidth'
      | 'height'
      | 'minheight'
      | 'maxheight',
    unit: string
  ) => {
    setValues({
      ...values,
      [modifier]: { value: values[modifier].value, unit },
    });
  };

  const widthModifiers = [
    {
      icon: <WidthIcon />,
      label: 'Width',
      value: 'width',
    },
    {
      icon: <StopIcon />,
      label: 'Min Width',
      value: 'minwidth',
    },
    {
      icon: <StopIcon />,
      label: 'Max Width',
      value: 'maxwidth',
    },
  ];

  const heightModifiers = [
    {
      icon: <HeightIcon />,
      label: 'Height',
      value: 'height',
    },
    {
      icon: <StopIcon />,
      label: 'Min Height',
      value: 'minheight',
    },
    {
      icon: <StopIcon />,
      label: 'Max Height',
      value: 'maxheight',
    },
  ];

  return (
    <div className="grid min-h-[120px] grid-cols-2 gap-x-4 gap-y-5">
      <div className="flex flex-col gap-2">
        {widthModifiers.map((modifier) => (
          <div className="flex flex-col gap-1" key={`width-${modifier.value}`}>
            <span>{modifier.label}</span>
            <MetricsControl
              key={modifier.value}
              defaultValue={values[modifier.value as keyof typeof values].value}
              defaultUnit={values.width.unit}
              onValueChange={(value) =>
                setValues({
                  ...values,
                  [modifier.value]: { value, unit: values.width.unit },
                })
              }
              onUnitChange={(unit) => handleUnitChange('width', unit)}
            />
          </div>
        ))}
      </div>
      <div className="flex flex-col gap-2">
        {heightModifiers.map((modifier) => (
          <div className="flex flex-col gap-1" key={`height-${modifier.value}`}>
            <span>{modifier.label}</span>
            <MetricsControl
              key={modifier.value}
              defaultValue={values[modifier.value as keyof typeof values].value}
              defaultUnit={values.height.unit}
              onValueChange={(value) =>
                setValues({
                  ...values,
                  [modifier.value]: { value, unit: values.height.unit },
                })
              }
              onUnitChange={(unit) => handleUnitChange('height', unit)}
            />
          </div>
        ))}
      </div>
    </div>
  );
};

export default Dimension;
