import { zodResolver } from "@hookform/resolvers/zod";
import { useEffect, useRef } from "react";
import { FieldValues, UseFormProps, UseFormReturn, useForm } from "react-hook-form";
import * as z4 from "zod/v4/core";

type UseHookFormProps<TFields extends FieldValues = FieldValues, TContext = any> = UseFormProps<
  TFields,
  TContext
> & {
  resolverSchema: z4.$ZodType<TFields, any>;
  initialValues: UseFormProps<TFields>["defaultValues"];
  onDirtyChange?: (isDirty: boolean) => void;
};

export function useHookForm<TFields extends FieldValues = FieldValues, TContext = any>({
  resolverSchema,
  initialValues,
  disabled,
  onDirtyChange,
  ...rest
}: UseHookFormProps<TFields, TContext>): UseFormReturn<TFields> {
  const form = useForm<TFields, TContext>({
    ...rest,
    resolver: zodResolver(resolverSchema),
    defaultValues: initialValues,
    disabled,
  });

  const {
    formState: { isDirty },
    reset,
  } = form;

  // Evita bucles de reset: guarda última instantánea aplicada
  const lastAppliedRef = useRef<unknown>(undefined);

  useEffect(() => {
    onDirtyChange?.(isDirty);
  }, [isDirty, onDirtyChange]);

  /*useEffect(() => {
    const applyReset = async () => {
      const values = typeof initialValues === "function" ? await initialValues() : initialValues;

      form.reset(values);
    };
    applyReset();
  }, [initialValues, form]);*/

  useEffect(() => {
    let mounted = true;
    const apply = async () => {
      const next = typeof initialValues === "function" ? await initialValues() : initialValues;
      // Evita reset redundante
      if (mounted && JSON.stringify(next) !== JSON.stringify(lastAppliedRef.current)) {
        reset(next as TFields);
        lastAppliedRef.current = next;
      }
    };
    void apply();
    return () => {
      mounted = false;
    };
  }, [initialValues, reset]);

  return form;
}
