'use client'

import React, { type ReactElement, useMemo, useState, type ChangeEvent } from 'react'
import Label from '@/Components/Inputs/Label'
import Description from '@/Components/Inputs/Description'
import { type ITextInputProps } from '@/Types'
import { makeClassName } from '@/utils'
import { Input as ShadInput } from '@/Components/ui/input'

export default function Input({
  id,
  testId = 'input',
  value,
  onChange,
  onSubmit,
  submitOnEnter = true,
  error,
  size = 'med',
  defaultClassName = 'block border border-slate-300 focus:outline-blue-400 w-full disabled:opacity-50 disabled:bg-slate-50',
  className,
  wrapperClassName,
  defaultWrapperClassName = 'block',
  disabled = false,
  placeholder,
  label,
  description,
  before,
  after,
  cleaner,
  autofocus = false,
  onBlur,
  onFocus,
  type = 'text',
  validator
}: ITextInputProps): ReactElement {
  const [v, setV] = useState<string | number | undefined>(value)
  const updateValue = (newValue?: string | number): void => {
    setV(newValue)
    value = newValue
  }
  useMemo(() => {
    updateValue(value)
  }, [value])
  const onInputChange = (e: ChangeEvent<HTMLInputElement>): void => {
    let newV = e.target.value
    if (typeof cleaner === 'function') {
      newV = cleaner(newV)
    }
    updateValue(newV)
    if (typeof onChange === 'function') {
      onChange(newV)
    }
  }

  const sizeToUse = size !== undefined ? size : 'md'

  return (
    <>
      <label className={
        makeClassName({
          defaultClassName: defaultWrapperClassName,
          className: wrapperClassName
        })
      }>
        {
          typeof label === 'string'
            ? <Label disabled={disabled} label={label} />
            : label !== undefined ? label : ''
        }
        {
          typeof description === 'string'
            ? <Description description={description} disabled={disabled} />
            : description !== undefined ? description : ''
        }
        {before !== undefined ? before : ''}
        <ShadInput
          id={id}
          autoFocus={autofocus}
          className={makeClassName({
            defaultClassName,
            size: sizeToUse,
            className,
            extras: [
              disabled ? 'cursor-not-allowed' : undefined,
              sizeToUse === 'xs' ? 'h-8  text-xs' : '',
              sizeToUse === 'sm' ? 'h-10  text-sm' : '',
              sizeToUse === 'md' || sizeToUse === 'med' ? 'h-12  text-md' : '',
              sizeToUse === 'lg' ? 'h-14  text-lg' : '',
              sizeToUse === 'xl' ? 'h-16  text-xl' : '',
            ],
            errorClassName: 'border-2 border-rose-600',
            error
          })}
          placeholder={placeholder}
          onChange={onInputChange}
          onBlur={onBlur}
          onFocus={onFocus}
          data-testid={testId}
          disabled={disabled}
          onKeyUp={(e) => {
            if (typeof onSubmit === 'function' && e.key === 'Enter') {
              onSubmit(v)
            }
          }}
          value={v !== undefined ? v : ''}
          type={type}
          {...validator}
        />
        {after !== undefined ? after : ''}
      </label>
    </>
  )
}
