import { SubmitErrorHandler } from "react-hook-form";
import { ValidationResult } from "../validation";
import { FormGroup } from "./form-groups";

export interface FormHandlers<T> {
  handleBlur: (
    fieldName: keyof T,
    groupIndex: number
  ) => Promise<ValidationResult>;

  handleSubmit: (
    onValid: (data: { groups: FormGroup<T>[] }) => Promise<void>,
    onInvalid?: SubmitErrorHandler<{ groups: FormGroup<T>[] }>
  ) => (e: React.FormEvent) => Promise<void>;

  handleChange: (
    fieldName: keyof T,
    groupIndex: number,
    callback?: (value: T[keyof T]) => void
  ) => { onChange: (e: any) => Promise<void> };

  handleFocus: (
    fieldName: keyof T,
    groupIndex: number,
    callback?: () => void
  ) => { onFocus: () => void };

  resetField: (fieldName: keyof T, groupIndex: number) => void;

  setFieldValue: (
    fieldName: keyof T,
    groupIndex: number,
    value: T[keyof T],
    options?: {
      shouldValidate?: boolean;
      shouldDirty?: boolean;
      shouldTouch?: boolean;
    }
  ) => void;

  touchField: (fieldName: keyof T, groupIndex: number) => void;

  /**
   * Resets the form to its initial state or to the provided default values.
   *
   * @param defaultValues - Optional new default values to reset the form to
   * @param options - Reset options
   * @param options.keepDirty - If true, the dirty state will be preserved (default: false)
   * @param options.keepErrors - If true, errors will be preserved (default: false)
   * @param options.keepValues - If true, values will be preserved (default: false)
   * @param options.keepIsSubmitted - If true, isSubmitted state will be preserved (default: false)
   * @param options.keepTouched - If true, touched state will be preserved (default: false)
   *
   * @example
   * // Reset form to initial values
   * resetForm();
   *
   * @example
   * // Reset form with new default values
   * resetForm({
   *   groups: [
   *     {
   *       id: "new-id-1",
   *       data: { name: "New Name", email: "new@example.com" }
   *     }
   *   ]
   * });
   *
   * @example
   * // Reset form but keep dirty state
   * resetForm(undefined, { keepDirty: true });
   */
  resetForm: (
    defaultValues?: { groups: FormGroup<T>[] },
    options?: {
      keepDirty?: boolean;
      keepErrors?: boolean;
      keepValues?: boolean;
      keepIsSubmitted?: boolean;
      keepTouched?: boolean;
    }
  ) => void;
}
