import type { ChangeEvent } from 'react';
import type { FormContextType, RJSFSchema, StrictRJSFSchema, WidgetProps } from '@rjsf/utils';
import { ariaDescribedByIds, rangeSpec } from '@rjsf/utils';
import { Input } from 'semantic-ui-react';

import { getSemanticProps } from '../util';

/** The `RangeWidget` component uses the `BaseInputTemplate` changing the type to `range` and wrapping the result
 * in a div, with the value along side it.
 *
 * @param props - The `WidgetProps` for this component
 */
export default function RangeWidget<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>(
  props: WidgetProps<T, S, F>,
) {
  const {
    id,
    value,
    required,
    readonly,
    disabled,
    onChange,
    onBlur,
    onFocus,
    options,
    schema,
    uiSchema,
    registry,
    rawErrors = [],
  } = props;
  const semanticProps = getSemanticProps<T, S, F>({
    formContext: registry.formContext,
    options,
    uiSchema,
    defaultSchemaProps: {
      fluid: true,
    },
  });

  // oxlint-disable-next-line no-shadow
  const handleChange = ({ target: { value } }: ChangeEvent<HTMLInputElement>) =>
    onChange?.(value === '' ? options.emptyValue : value);
  const handleBlur = () => onBlur?.(id, value);
  const handleFocus = () => onFocus?.(id, value);

  return (
    <>
      <Input
        id={id}
        key={id}
        name={id}
        type='range'
        required={required}
        disabled={disabled || readonly}
        {...rangeSpec<S>(schema)}
        {...semanticProps}
        value={value || ''}
        error={rawErrors.length > 0}
        onChange={handleChange}
        onBlur={handleBlur}
        onFocus={handleFocus}
        aria-describedby={ariaDescribedByIds(id)}
      />
      <span>{value}</span>
    </>
  );
}
