import * as React from "react";

import { cn } from "@/lib/utils";
import { FormControl, FormDescription, FormField, FormItem, Input, InputProps } from "@/ui";
import { Quantity } from "@shared/contexts";
import { cva, type VariantProps } from "class-variance-authority";
import { FieldPath, FieldValues, UseControllerProps, useFormContext } from "react-hook-form";
import { FormErrorMessage } from "./FormErrorMessage";
import { FormLabel, FormLabelProps } from "./FormLabel";
import { FormInputProps, FormInputWithIconProps } from "./FormProps";

const formQuantityFieldVariants = cva(
  "text-right [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none",
  {
    variants: {
      variant: {
        default: "",
        outline:
          "border-0 focus-visible:border focus-visible:border-input focus-visible:ring-0 focus-visible:ring-offset-0 ",
      },
    },
    defaultVariants: {
      variant: "default",
    },
  }
);

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

export const FormQuantityField = React.forwardRef<HTMLInputElement, FormQuantityFieldProps>(
  (props, ref) => {
    const {
      name,
      label,
      hint,
      description,
      placeholder,
      className,
      disabled,
      defaultValue,
      rules,
      precision,
      variant,
    } = props;

    const { control } = useFormContext();

    const transformToInput = (value: any) => {
      if (typeof value !== "object") {
        return value;
      }

      const quantityOrError = Quantity.create(value);
      if (quantityOrError.isFailure) {
        throw quantityOrError.error;
      }

      return (
        quantityOrError.object
          .toNumber()
          //.toPrecision(precision ?? value.precision)
          .toString()
      );
    };

    return (
      <FormField
        defaultValue={defaultValue}
        control={control}
        name={name}
        disabled={disabled}
        rules={rules}
        // eslint-disable-next-line @typescript-eslint/no-unused-vars
        render={({ field }) => {
          return (
            <FormItem ref={ref} className={cn(className, "space-y-3")}>
              {label && <FormLabel label={label} hint={hint} required={rules?.required ?? false} />}
              <FormControl>
                <Input
                  type='number'
                  name={field.name}
                  //ref={field.ref} <-- no activar que hace cosas raras
                  onBlur={field.onBlur}
                  disabled={field.disabled}
                  className={cn(formQuantityFieldVariants({ variant, className }))}
                  placeholder={placeholder}
                  value={transformToInput(field.value)}
                  onChange={(value) => {
                    // "value" ya viene con los "0" de la precisión
                    console.log(value);
                    field.onChange(value ?? "");
                  }}
                />
              </FormControl>
              {description && <FormDescription>{description}</FormDescription>}
              <FormErrorMessage />
            </FormItem>
          );
        }}
      />
    );
  }
);
