import { t } from "i18next";
import { useCallback, useEffect } from "react";
import { useBlocker } from "react-router-dom";
import { useWarnAboutChange } from "./useWarnAboutChange";

export type UnsavedChangesNotifierProps = {
  title?: string;
  subtitle?: string;
  confirmText?: string;
  cancelText?: string;
  onConfirm?: () => void;
  onCancel?: () => void;
  type?: "success" | "error" | "warning" | "info";
};

export const useUnsavedChangesNotifier = ({
  isDirty = false,
  title = t("hooks.use_unsaved_changes_notifier.title"),
  subtitle = t("hooks.use_unsaved_changes_notifier.subtitle"),
  confirmText = t("hooks.use_unsaved_changes_notifier.confirm_text"),
  cancelText = t("hooks.use_unsaved_changes_notifier.cancel_text"),
  onConfirm,
  onCancel,
  type = "warning",
}: UnsavedChangesNotifierProps & { isDirty?: boolean }) => {
  const blocker = useBlocker(isDirty);
  const { show } = useWarnAboutChange();

  const confirm = useCallback(() => {
    if (!isDirty) return Promise.resolve(true);

    return new Promise<boolean>((resolve) => {
      show({
        title,
        subtitle,
        confirmText,
        cancelText,
        type,
        onConfirm: () => {
          resolve(true);
          onConfirm?.();
        },
        onCancel: () => {
          resolve(false);
          onCancel?.();
        },
      });
    });
  }, [cancelText, confirmText, isDirty, onCancel, onConfirm, show, subtitle, title, type]);

  useEffect(() => {
    if (blocker.state === "blocked") {
      confirm().then((result) => {
        if (result) blocker.proceed();
        else blocker.reset();
      });
    }
  }, [blocker, confirm]);

  useEffect(() => {
    if (isDirty) {
      window.onbeforeunload = () => subtitle;
    }

    return () => {
      window.onbeforeunload = null;
    };
  }, [isDirty, subtitle]);

  return {
    confirm,
  };
};
