import { useState, type ComponentProps, type ReactNode } from 'react'
import {
  get,
  useFormContext,
  type FieldError,
  type FieldValues,
  type Path,
  type RegisterOptions,
} from 'react-hook-form'

import { EyeIcon } from '~/components/icons/eye'

import { Button } from './button'

type TInputProperties<T extends FieldValues> = Omit<
  ComponentProps<'input'>,
  'size'
> & {
  id: string
  label?: ReactNode
  name: Path<T>
  rules?: RegisterOptions
}

export const Input = <TFormValues extends Record<string, unknown>>(
  properties: TInputProperties<TFormValues>,
) => {
  const { id, label, name, rules, type = 'text', ...rest } = properties
  const [inputType, setInputType] = useState(type)

  const {
    register,
    formState: { errors },
  } = useFormContext()

  const error: FieldError = get(errors, name)

  return (
    <div className="relative">
      <label
        htmlFor={id}
        className="mb-1 block text-gray-700"
      >
        {label} {error && <span className="text-red-500">{error.message}</span>}
      </label>
      <input
        id={id}
        type={inputType}
        className="w-full rounded-md border border-[#DFDFDF] p-2"
        {...register(name, rules)}
        {...rest}
      />
      {type === 'password' && (
        <Button
          type="button"
          variant="icon"
          size="fit"
          className="absolute top-9 right-3 text-gray-500"
          onClick={() =>
            setInputType(inputType === 'password' ? 'text' : 'password')
          }
        >
          {inputType === 'password' ? (
            <EyeIcon
              width={15}
              height={15}
            />
          ) : (
            <EyeIcon
              width={15}
              height={15}
            />
          )}
        </Button>
      )}
    </div>
  )
}
