/**
 * Copyright (c) 2023-present Pi Dash Software, Inc. and contributors
 * SPDX-License-Identifier: AGPL-3.0-only
 * See the LICENSE file for details.
 */

import { useCallback, useEffect, useState } from "react";

//TODO: remove temp flag isActive later and use showAlert as the source of truth
const useReloadConfirmations = (isActive = true, message?: string, defaultShowAlert = false, onLeave?: () => void) => {
  const [showAlert, setShowAlert] = useState(defaultShowAlert);

  const alertMessage = message ?? "Are you sure you want to leave? Changes you made may not be saved.";

  const handleBeforeUnload = useCallback(
    (event: BeforeUnloadEvent) => {
      if (!isActive || !showAlert) return;
      event.preventDefault();
      event.returnValue = "";
    },
    [isActive, showAlert]
  );

  const handleAnchorClick = useCallback(
    (event: MouseEvent) => {
      if (!isActive || !showAlert) return;
      // Skip if event target is not available or defaultPrevented
      if (!event.target || event.defaultPrevented) return;
      // Skip control/command/option/alt+click
      if (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return;
      // check if the event target is an anchor or a child of an anchor tag
      const eventTarget = event.target as HTMLElement;
      if (!eventTarget.closest("a")) return; // This is intentionally not type safe
      // check if anchor target is _blank
      const anchorElement = eventTarget.closest("a") as HTMLAnchorElement;
      const isAnchorTargetBlank = anchorElement.getAttribute("target") === "_blank";
      if (isAnchorTargetBlank) return;
      // show confirm dialog
      const isLeaving = confirm(alertMessage);
      if (isLeaving) {
        onLeave && onLeave();
      } else {
        event.preventDefault();
        event.stopPropagation();
      }
    },
    [isActive, showAlert]
  );

  useEffect(() => {
    // handle browser refresh
    window.addEventListener("beforeunload", handleBeforeUnload, true);
    // handle anchor tag click
    window.addEventListener("click", handleAnchorClick, true);
    // TODO: handle back / forward button click

    return () => {
      // cleanup
      window.removeEventListener("beforeunload", handleBeforeUnload, true);
      window.removeEventListener("click", handleAnchorClick, true);
    };
  }, [handleAnchorClick, handleBeforeUnload]);

  return { setShowAlert };
};

export default useReloadConfirmations;
