import React, { useRef } from 'react'
import { useField, FieldRenderProps, UseFieldConfig } from 'react-final-form'
import '../tailwind.css'
import { classNames } from '../utils/css'
import { Labelled } from '../Labelled/Labelled'

type Type = 'text' | 'email' | 'number' | 'password' | 'search' | 'tel'

type InputMode =
  | 'none'
  | 'text'
  | 'email'
  | 'decimal'
  | 'numeric'
  | 'tel'
  | 'search'

export interface TextFieldProps {
  /* Hint text to display */
  placeholder?: string
  /* Initial value for the input */
  value?: string
  /* Additional hint text to display */
  helpText?: string
  /* Label for the input */
  label?: string
  /* Disable the input */
  disabled?: boolean
  /* Choose the keyboard that should be used on mobile devices */
  inputMode?: InputMode
  /* Determine type of input */
  type?: Type
  /* Name of the input */
  name: string
  // Display larger input
  large?: boolean
  /* Suffix component */
  suffix?: React.ReactNode
  /* Validation function */
  validate?: UseFieldConfig<string>['validate']
}

const styles = {
  base: 'block w-full mt-1 rounded-lg border placeholder-primary-placeholder bg-primary-background',
  default: 'text-primary-text',
  defaultBorder: 'border-primary-border focus-within:ring-primary focus-within:border-primary-hover',
  error: 'text-negative-text border-negative-border focus-within:ring-negative focus-within:border-negative-hover',
  disabled: 'text-disabled-text',
  smallPadding: 'py-2 px-3',
  largePadding: 'py-3 px-4',
  smallFont: 'text-sm',
  largeFont: 'text-base'
}

export const TextField = ({
  placeholder,
  value,
  helpText,
  label,
  disabled,
  inputMode,
  type,
  name,
  suffix,
  validate,
  large
}: TextFieldProps) => {
  const {
    input,
    meta: { error, touched, submitError }
  }: FieldRenderProps<string> = useField(name, {
    initialValue: value,
    validate: validate
  })
  const errorText = touched && (error || submitError) ? error : null

  const className = classNames(
    styles.base,
    !errorText && styles.default,
    errorText && styles.error,
    disabled && styles.disabled,
    !large && styles.smallPadding,
    large && styles.largePadding,
    !large && styles.smallFont,
    large && styles.largeFont,
    !errorText && styles.defaultBorder
  )

  const inputNode = useRef<HTMLInputElement>(null)

  const handleClick = () => {
    inputNode.current?.focus()
  }


  return (
    <div onClick={handleClick}>
      <Labelled
        label={label ? label : ''}
        helpText={helpText}
        error={errorText}
        disabled={disabled}
      >
        <div className='relative'>
          <input
            ref={inputNode}
            type={type ? type : 'text'}
            className={className}
            placeholder={placeholder}
            inputMode={inputMode}
            disabled={disabled}
            {...input}
          ></input>
          {suffix && <div className='absolute inset-y-0 right-0 pr-3 flex items-center'>{suffix}</div>}
        </div>
      </Labelled>
    </div>
  )
}
