import cx from 'clsx';
import { isEqual, isMap, isNil } from 'lodash-es';
import { useCallback, useRef, useState } from 'react';
import type { Option } from '../models';
import styles from './HSegmentedControl.module.css';

type HSegmentedControlProps = {
  name?: string;
  defaultValue?: Option['value'];
  options?: Option[];
  value?: Option['value'];
  onChange?: (value: Option['value']) => void;
  extendClassName?: HTMLDivElement['className'];
};

export function HSegmentedControl({
  name,
  defaultValue,
  options = [],
  value,
  onChange,
  extendClassName,
}: HSegmentedControlProps) {
  const [selected, setSelected] = useState(
    value ??
      defaultValue ??
      (isMap(options[0]) ? options[0].get('value') : options[0].value) ??
      null,
  );
  const [sliderPosition, setSliderPosition] = useState(0);
  const [sliderWidth, setSliderWidth] = useState(0);
  const sliderRef = useRef<HTMLDivElement>(null);
  const optionsRef = useRef<HTMLDivElement[]>([]);

  const handleSelectAction = useCallback((option: Option['value'], index: number) => {
    setSelected(option);
    onChange?.(option);
    if (optionsRef.current && optionsRef.current.length > index) {
      const optionElement = optionsRef.current[index];
      setSliderPosition(optionElement.offsetLeft);
      setSliderWidth(optionElement.offsetWidth);
    }
  }, []);

  return (
    <div className={cx(styles.segmented_control, extendClassName)}>
      <div className={styles.options}>
        {options.map((option, index) => {
          const label = isMap(option) ? option.get('label') : option.label;
          const value = isMap(option) ? option.get('value') : option.value;
          return (
            <div
              key={`${index}_${value}`}
              className={cx(styles.option, isEqual(selected, value) && styles.selected)}
              ref={(el) => (optionsRef.current[index] = el!)}
              onClick={() => handleSelectAction(value, index)}>
              {label}
            </div>
          );
        })}
        {!isNil(selected) && (
          <div
            className={styles.slider}
            ref={sliderRef}
            style={{ left: `${sliderPosition}px`, width: `${sliderWidth}px` }}
          />
        )}
      </div>
      {!isNil(name) && <input type="hidden" name={name} value={selected} />}
    </div>
  );
}
