import { Writable } from "svelte/store";
export type TEventName = "submit" | "blur" | "input";

export type TElement = (
  | HTMLInputElement
  | HTMLTextAreaElement
  | HTMLButtonElement
  | HTMLSelectElement
) & { checked?: boolean };

export type TConfig<TValues, TSchema> = {
  form: HTMLFormElement | undefined;
  dirty: Map<keyof TValues, boolean>;
  elements: Set<TElement>;
  strategy: TEventName;
  fields: Map<keyof TValues, keyof TValues>;
  errors: Writable<Partial<Record<keyof TValues, string>>>;
  values: Writable<Partial<TValues>>;
  defaultValues: Partial<TValues>;
  isSubmitting: Writable<boolean>;
  schema: TSchema | undefined;
};

export type TContext<TValues, TFieldName extends keyof TValues, TConfig> = {
  config: TConfig;
  name: TFieldName;
  value?: TValues[TFieldName];
  isDirty?: boolean;
  setError: (name: keyof TValues, message: string) => void;
};

export type TValidator<TValues, TFieldName extends keyof TValues, TConfig> =
  | ((ctx: TContext<TValues, TFieldName, TConfig>) => string)
  | ((ctx: TContext<TValues, TFieldName, TConfig>) => Promise<string>);
