import { useFormContext, useFormControl } from 'domains/forms/hooks'
import { RefObject, TextareaHTMLAttributes } from 'preact'
import { useRef, useLayoutEffect } from 'preact/hooks'
import FormControlWrapper from './wrapper'

type InputProps = TextareaHTMLAttributes<HTMLTextAreaElement> & {
  name: 'textMessageEntry'
  labelText: string
  labelClass: string
  contentHint?: string | null
  focus?: boolean
  submitButtonRef: RefObject<HTMLButtonElement>
}

function Textarea({
  id,
  name,
  labelText,
  labelClass,
  contentHint = null,
  focus,
  submitButtonRef,
  'aria-invalid': ariaInvalid,
  'aria-describedby': ariaDescribedBy,
  ...props
}: InputProps) {
  const textareaRef = useRef<HTMLTextAreaElement | null>(null)
  const { isSubmitted } = useFormContext()
  const [field, { error }] = useFormControl(name)
  const hasError = isSubmitted && error

  const describedByIds = [
    ariaDescribedBy && ariaDescribedBy,
    contentHint && `${id}-content-hint`,
    hasError && `${id}-error`,
  ]
    .filter(Boolean)
    .join(' ')

  useLayoutEffect(() => {
    if (textareaRef.current && focus) {
      textareaRef.current.focus()
    }
  }, [focus])

  const handleKeyDown = (e: KeyboardEvent) => {
    if (e.key === 'Enter' && !e.shiftKey) {
      // Prevent default newline in textarea
      e.preventDefault()

      // Trigger the submit button
      if (submitButtonRef.current) {
        submitButtonRef.current.click()
      }
    }
  }

  return (
    <FormControlWrapper
      id={id}
      contentHint={contentHint}
      validity={!hasError}
      errorText={error}
      labelText={labelText}
      labelClass={labelClass}
    >
      <textarea
        {...field}
        {...props}
        ref={textareaRef}
        id={id}
        aria-invalid={ariaInvalid || hasError ? 'true' : 'false'}
        aria-describedby={describedByIds || undefined}
        name={name}
        onKeyDown={handleKeyDown}
      />
    </FormControlWrapper>
  )
}

export default Textarea
