import React, { ChangeEventHandler, LegacyRef } from 'react';
import classNames from 'classnames';
import { InjectedFieldProps } from '../Field/InjectedFieldProps';
import { FormDefaults } from '../FormDefaults';
import Group, { GroupProps } from '../Group';

export interface InputGroupProps<TValue>
  extends InjectedFieldProps<TValue>,
    Omit<
      React.HTMLProps<HTMLInputElement>,
      | keyof InjectedFieldProps<any>
      | 'children'
      | 'className'
      | 'label'
      | 'value'
    >,
    Omit<GroupProps, keyof InjectedFieldProps<any> | 'children'> {
  onChange: ChangeEventHandler<HTMLInputElement>;
  value: string | number | null | undefined;
  icon?: React.ReactNode;
}

function InputGroup<TValue>(
  {
    input,
    meta,
    label,
    helpText,
    className,
    required,
    disabled,
    onChange,
    value,
    icon,
    ...rest
  }: InputGroupProps<TValue>,
  ref: LegacyRef<HTMLInputElement>
) {
  return (
    <Group
      input={input}
      meta={meta}
      required={required}
      disabled={disabled}
      label={label}
      helpText={helpText}
      className={classNames(
        className,
        FormDefaults.cssClassPrefix + 'input-group'
      )}>
      {icon}
      <input
        {...input}
        {...rest}
        aria-invalid={!!meta.error}
        aria-errormessage={!!meta.error ? `${input.name}-error` : undefined}
        value={value ?? ''}
        onChange={onChange}
        ref={ref}
        className={classNames(
          className,
          FormDefaults.cssClassPrefix + 'input-group'
        )}
      />
    </Group>
  );
}

/** Generic controlled `<input/>` wrapped by a `<Group/>` */
const InputGroupWithRef = React.forwardRef(InputGroup) as typeof InputGroup;

export default InputGroupWithRef;
