/* eslint prefer-const: 0 */
import React, { useState, useMemo } from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';

const propTypes = {
  /**
   * The component used for the root node.
   * Either a string to use a DOM element or a component.
   */
  tag: PropTypes.elementType,
  className: PropTypes.string,
  defaultClassName: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]),
  isDanger: PropTypes.bool,
  isDisabled: PropTypes.bool,
  isPrimary: PropTypes.bool,
  isSuccess: PropTypes.bool,
  isWarning: PropTypes.bool,
  min: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
  max: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
  value: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
  onChange: PropTypes.func,
  formatLabel: PropTypes.func,
};

const defaultProps = {
  tag: 'input',
  className: '',
  defaultClassName: 'sui-a-form-range',
  isDanger: false,
  isDisabled: false,
  isPrimary: false,
  isSuccess: false,
  isWarning: false,
  min: 0,
  max: 100,
  value: 0,
  onChange: () => {},
  formatLabel: (value) => value,
};

const SLIDER_THUMB_WIDTH = 25;
const FULL_WIDTH_PERCENTAGE = 100;
const HALF_WIDTH_PERCENTAGE = 50;

export const FormRange = (props) => {
  let {
    tag: Tag,
    defaultClassName,
    className,
    isDanger,
    isDisabled,
    isPrimary,
    isSuccess,
    isWarning,
    min,
    max,
    value,
    onChange,
    formatLabel,
    ...attributes
  } = props;

  const defaultValue = value || min;

  const [currentValue, setCurrentValue] = useState(defaultValue);

  const classes = classnames(
    defaultClassName,
    className,
    {
      'as--danger': isDanger,
      'as--primary': isPrimary,
      'as--success': isSuccess,
      'as--warning': isWarning,
    },
  );

  const valueLeft = useMemo(
    () => (currentValue / max) * FULL_WIDTH_PERCENTAGE, [currentValue, max]);

  const handleChange = (event) => {
    const { value: newValue } = (event.target || {});

    setCurrentValue(newValue);

    onChange(newValue);
  };

  return (
    <div className={classes}>
      <div className="sui-a-form-range__label as--before">{formatLabel(min)}</div>

      <div className="sui-a-form-range__container">
        <Tag
          type="range"
          disabled={isDisabled}
          min={min}
          max={max}
          defaultValue={defaultValue}
          onChange={handleChange}
          {...attributes}
        />

        <div
          className="sui-a-form-range__wrapper"
          style={{
            transform: `translateX(calc(${valueLeft}% ${valueLeft > HALF_WIDTH_PERCENTAGE
              ? `- ${((valueLeft - HALF_WIDTH_PERCENTAGE) / FULL_WIDTH_PERCENTAGE) * SLIDER_THUMB_WIDTH}`
              : `+ ${((HALF_WIDTH_PERCENTAGE - valueLeft) / FULL_WIDTH_PERCENTAGE) * SLIDER_THUMB_WIDTH}`}px))`,
          }}
        >
          <div
            className="sui-a-form-range__value as--position-dynamic"

          >
            {formatLabel(currentValue)}
          </div>
        </div>
      </div>

      <div className="sui-a-form-range__label as--after">{formatLabel(max)}</div>
    </div>
  );
};

FormRange.propTypes = propTypes;
FormRange.defaultProps = defaultProps;
