import { fadeInOut } from "@/utils/variants";
import { cn } from "clsx-tailwind-merge";
import { AnimatePresence, motion } from "framer-motion";
import { InputHTMLAttributes } from "react";
import { FieldError, FieldErrors, FieldValues, Path, RegisterOptions, UseFormRegister } from "react-hook-form";

type InputProps<T extends FieldValues> = {
  label: string;
  name: Path<T>;
  register: UseFormRegister<T>;
  errors: FieldErrors<T>;
  registerOptions?: RegisterOptions<T, Path<T>> | undefined;
  attr?: InputHTMLAttributes<HTMLInputElement>;
  disabled?: boolean;
  className?: string;
  children?: React.ReactNode;
};

const Input = <T extends FieldValues>({
  label,
  name,
  register,
  errors,
  registerOptions,
  attr,
  disabled,
  className,
  children,
}: InputProps<T>) => {
  return (
    <div className={`${cn("text-[0.875rem]/none text-light-blue text-left relative mb-10", className)}`}>
      <label htmlFor={name} className="block font-bold mb-1.5">
        {label}
      </label>
      {!children ? (
        <input
          {...attr}
          className={`${cn(
            "px-4 border border-alto focus:outline-none focus:border-light-blue focus:ring-1 focus:ring-light-blue rounded-[0.25rem] py-2 w-full text-base text-shark aria-invalid:border-red-600 focus:aria-invalid:ring-red-600 aria-invalid:text-red-600",
            { "opacity-50 pointer-events-none": disabled }
          )}`}
          {...register(name, registerOptions)}
          aria-invalid={!!errors[name]}
          disabled={disabled}
        />
      ) : (
        children
      )}
      <AnimatePresence>
        {errors[name] && (
          <motion.p {...fadeInOut()} className="text-red-600 mt-1 absolute text-[clamp(0.625rem,3vw,0.7813rem)]">
            {(errors[name] as FieldError)?.message}
          </motion.p>
        )}
      </AnimatePresence>
    </div>
  );
};

export default Input;
