import { cn } from "@/lib/utils";
import { FormControl, FormDescription, FormField, FormItem, Input, InputProps } from "@/ui";

import { cva, type VariantProps } from "class-variance-authority";
import * as React from "react";
import { FieldPath, FieldValues, UseControllerProps, useFormContext } from "react-hook-form";
import { FormErrorMessage } from "./FormErrorMessage";
import { FormLabel, FormLabelProps } from "./FormLabel";
import { FormInputProps, FormInputWithIconProps } from "./FormProps";

const formTextFieldVariants = cva("", {
  variants: {
    variant: {
      default: "",
      ghost:
        "border-0 focus-visible:border focus-visible:border-input focus-visible:ring-0 focus-visible:ring-offset-0 ",
    },
  },
  defaultVariants: {
    variant: "default",
  },
});

export type FormTextFieldProps<
  TFieldValues extends FieldValues = FieldValues,
  TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>
> = {
  button?: (props?: React.PropsWithChildren) => React.ReactNode;
} & InputProps &
  FormInputProps &
  Partial<FormLabelProps> &
  FormInputWithIconProps &
  UseControllerProps<TFieldValues, TName> &
  VariantProps<typeof formTextFieldVariants>;

export const FormTextField = React.forwardRef<HTMLInputElement, FormTextFieldProps>(
  (props, ref) => {
    const {
      name,
      label,
      hint,
      description,
      placeholder,
      className,
      disabled,
      defaultValue,
      rules,
      required,
      type,
      variant,
    } = props;

    const { control } = useFormContext();

    return (
      <FormField
        control={control}
        name={name}
        disabled={disabled}
        rules={{
          required,
          ...rules,
        }}
        render={({ field, fieldState }) => {
          const isRequired = Boolean(rules?.required ?? required);

          return (
            <FormItem className={cn(className, "space-y-3")}>
              {label && <FormLabel label={label} hint={hint} required={isRequired} />}

              <FormControl className={"block"}>
                <Input
                  type={type}
                  placeholder={placeholder}
                  className={cn(
                    fieldState.error ? "border-destructive focus-visible:ring-destructive" : "",
                    formTextFieldVariants({ variant, className })
                  )}
                  {...field}
                />
              </FormControl>

              {description && <FormDescription>{description}</FormDescription>}
              <FormErrorMessage />
            </FormItem>
          );
        }}
      />
    );
  }
);
