import type { SubscribableForm } from "@/components/form-common/types";
import { Button, type ButtonProps } from "@/components/ui/button";
import { Loader2Icon } from "lucide-react";
import { type ReactNode, useEffect, useState } from "react";

export interface FormSubmitProps
  extends Omit<ButtonProps, "type" | "children"> {
  formApi: SubscribableForm<{ isSubmitting: boolean; canSubmit: boolean }>;
  children:
    | ReactNode
    | ((state: {
        isSubmitting: boolean;
        canSubmit: boolean;
        disabled: boolean;
      }) => ReactNode);
}

export function FormSubmit({
  children,
  disabled,
  formApi,
  ...props
}: FormSubmitProps) {
  const [{ isSubmitting, canSubmit }, setState] = useState<{
    isSubmitting: boolean;
    canSubmit: boolean;
  }>({ isSubmitting: false, canSubmit: true });

  useEffect(() => {
    return formApi.store.subscribe(({ currentVal }) => {
      setState({
        isSubmitting: currentVal.isSubmitting,
        canSubmit: currentVal.canSubmit,
      });
    });
  }, [formApi]);

  return (
    <Button
      type="submit"
      disabled={disabled || !canSubmit || isSubmitting}
      {...props}
    >
      {typeof children === "function"
        ? children({ isSubmitting, canSubmit, disabled: disabled ?? false })
        : children}
      {isSubmitting && <Loader2Icon className="animate-spin repeat-infinite" />}
    </Button>
  );
}
