import React, {forwardRef} from 'react'
import {
  FormField as InstUIFormField,
  type FormFieldProps as InstUIFormFieldProps,
} from '@instructure/ui-form-field'
import {enhanceErrorMessages} from '../../util/enhanceErrorMessages'
import {enhanceLabel, hasErrorMessage} from '../../util/enhanceLabel'
import {bool} from 'prop-types'

export interface FormFieldSubcomponents {
  propTypes: typeof InstUIFormField.propTypes & {
    isRequired?: typeof bool
  }
}

export interface FormFieldProps extends InstUIFormFieldProps {
  isRequired?: boolean
}

const FormFieldComponent = forwardRef<InstUIFormField, FormFieldProps>(
  ({messages, isRequired, ...props}, ref) => {
    const messagesWithEnhancedErrors = enhanceErrorMessages(messages)

    const labelHasError = hasErrorMessage(messages)
    const enhancedLabel = enhanceLabel(props.label, isRequired, labelHasError)

    return (
      <InstUIFormField
        {...props}
        ref={ref}
        messages={messagesWithEnhancedErrors}
        label={enhancedLabel || ''}
      />
    )
  },
)

/**
 * This is a wrapper around the InstUI `FormField` component.
 *
 * Differences include:
 * - If the `label` prop is a string, it will be enhanced with an asterisk if `isRequired` is `true`
 * - If the `messages` prop contains an error message, it will include an icon
 */
export const FormField = Object.assign(FormFieldComponent, {
  // Note: `propTypes` are still required by functions such as `pickProps` and `omitProps`
  propTypes: {...InstUIFormField.propTypes, isRequired: bool},
}) as typeof FormFieldComponent & FormFieldSubcomponents

export {FormPropTypes} from '@instructure/ui-form-field'

FormField.displayName = 'FormField'
