import {
  useDisclosure,
  UseDisclosureProps,
  UseDisclosureReturn,
  useToast,
} from "@chakra-ui/react";
import { useForm, UseFormProps, UseFormReturn } from "react-hook-form";
import { useMutation, UseMutationResult } from "@tanstack/react-query";

import { FormKeyConfig } from "./form-key-config";
import { TData } from "../types";

export interface UseEditRecordModalProps<T extends TData> {
  /**
   * The title of the Create Record modal to display on the button and the header
   */
  title: string;
  /**
   * The mutation to run when the form is submitted
   * @param data The data to submit to the mutation function
   */
  mutationFn: (data: T) => Promise<T>;
  /**
   * The form key config populate the modal
   */
  formKeys: FormKeyConfig<T>[];
  /**
   * The default values to fill the form
   */
  defaultValues?: UseFormProps<T>["defaultValues"];
}

export interface UseEditRecordModalReturn<T extends TData> {
  /**
   * The title of the Create Record modal to display on the button and the header
   */
  title: string;
  /**
   * The mutation response
   */
  mutationResponse: UseMutationResult<T, unknown, T, unknown>;
  /**
   * The form to use for the Create Record modal
   */
  form: UseFormReturn<T>;
  /**
   * The function to run the submission of the form
   */
  onFormSubmit: (data: T) => Promise<void>;
  /**
   * The function to run when the form has errors
   */
  onFormError: (errors: any) => void;
  /**
   * The modal disclosure props
   */
  disclosure: UseDisclosureReturn;
  /**
   * The form key config populate the modal
   */
  formKeys: FormKeyConfig<T>[];
}

export const useEditRecordModalWithCustomMutationHook = <
  T extends TData,
  R extends {}
>({
  title,
  formKeys,
  defaultValues,
  onFormSubmit: _onFormSubmit = async () => {},
  useMutationHook,
  disclosureProps,
}: Omit<UseEditRecordModalProps<T>, "mutationFn"> & {
  useMutationHook: ({
    onSuccess = () => {},
    onError = () => {},
  }: {
    onSuccess?: () => void;
    onError?: () => void;
  }) => R;
  onFormSubmit?: (mutation: R, formFields: T) => Promise<void>;
  disclosureProps?: UseDisclosureProps;
}) => {
  const disclosure = useDisclosure(disclosureProps);

  const form = useForm<T>({ defaultValues });

  const onSuccess = () => {
    console.log("success");
  };

  const onError = () => {
    console.log("error");
  };

  const mutation = useMutationHook({ onSuccess, onError });

  const onFormSubmit = async (data: T) => {
    await _onFormSubmit(mutation, data);
    // await mutationResponse.mutateAsync(data);
    disclosure.onClose();
  };

  const onFormError = (errors: any) => {
    // eslint-disable-next-line no-console -- error logging
    console.error(errors);
  };

  return {
    title,
    formKeys,
    mutationResponse: mutation,
    form,
    onFormSubmit,
    onFormError,
    disclosure,
  };
};

/**
 * Generic abstraction of the useMutation required to run the CreateRecordModal
 * A function can be passed into the mutationFn to run the record creation process on save
 * @returns
 */
export const useEditRecordModal = <T extends TData>({
  title,
  formKeys,
  mutationFn,
  defaultValues,
}: UseEditRecordModalProps<T>): UseEditRecordModalReturn<T> => {
  return useEditRecordModalWithCustomMutationHook({
    title,
    formKeys,
    defaultValues,
    useMutationHook: ({ onSuccess, onError }) =>
      useMutation({
        mutationFn,
        onSuccess,
        onError,
      }),
    onFormSubmit: async (mutation, data) => {
      await mutation.mutateAsync(data);
    },
  });
};
