<script setup>
import { Icon } from "@iconify/vue";
import { reactiveOmit } from "@vueuse/core";
import { onBeforeUnmount, shallowRef, watchEffect } from "vue";
import {
  DialogClose,
  DialogContent,
  DialogOverlay,
  DialogPortal,
  useForwardPropsEmits
} from "reka-ui";
import { cn } from "../../../utils/cn";
defineOptions({
  inheritAttrs: false
});
const props = defineProps({
  forceMount: { type: Boolean, required: false },
  disableOutsidePointerEvents: { type: Boolean, required: false },
  asChild: { type: Boolean, required: false },
  as: { type: null, required: false },
  class: { type: [Boolean, null, String, Object, Array], required: false, skipCheck: true },
  showCloseButton: { type: Boolean, required: false, default: true },
  contentWidth: { type: String, required: false }
});
const emit = defineEmits(["escapeKeyDown", "pointerDownOutside", "focusOutside", "interactOutside", "openAutoFocus", "closeAutoFocus", "after-close"]);
const delegatedProps = reactiveOmit(props, "class", "showCloseButton", "contentWidth");
const forwarded = useForwardPropsEmits(delegatedProps, emit);
const overlayElement = shallowRef(null);
let closeFallbackTimer;
let hasEmittedAfterClose = false;
function isClosedContentTarget(target) {
  return target instanceof HTMLElement && target.dataset.state === "closed";
}
function clearCloseFallbackTimer() {
  if (closeFallbackTimer === void 0) {
    return;
  }
  window.clearTimeout(closeFallbackTimer);
  closeFallbackTimer = void 0;
}
function emitAfterClose() {
  if (hasEmittedAfterClose) {
    return;
  }
  hasEmittedAfterClose = true;
  clearCloseFallbackTimer();
  emit("after-close");
}
function parseDurationMs(value) {
  const normalizedValue = value.trim();
  if (normalizedValue.endsWith("ms")) {
    const duration = Number.parseFloat(normalizedValue.slice(0, -2));
    return Number.isFinite(duration) ? duration : 0;
  }
  if (normalizedValue.endsWith("s")) {
    const duration = Number.parseFloat(normalizedValue.slice(0, -1));
    return Number.isFinite(duration) ? duration * 1e3 : 0;
  }
  return 0;
}
function getLongestMotionMs(element) {
  const style = window.getComputedStyle(element);
  const animationDurations = style.animationDuration.split(",");
  const animationDelays = style.animationDelay.split(",");
  const transitionDurations = style.transitionDuration.split(",");
  const transitionDelays = style.transitionDelay.split(",");
  let longestMotionMs = 0;
  for (const [index, durationValue] of animationDurations.entries()) {
    const durationMs = parseDurationMs(durationValue);
    const delayMs = parseDurationMs(animationDelays[index] ?? animationDelays[0] ?? "0s");
    longestMotionMs = Math.max(longestMotionMs, durationMs + delayMs);
  }
  for (const [index, durationValue] of transitionDurations.entries()) {
    const durationMs = parseDurationMs(durationValue);
    const delayMs = parseDurationMs(transitionDelays[index] ?? transitionDelays[0] ?? "0s");
    longestMotionMs = Math.max(longestMotionMs, durationMs + delayMs);
  }
  return longestMotionMs;
}
function syncCloseFallback() {
  const element = overlayElement.value;
  clearCloseFallbackTimer();
  if (!element) {
    return;
  }
  if (element.dataset.state !== "closed") {
    hasEmittedAfterClose = false;
    return;
  }
  const motionMs = getLongestMotionMs(element);
  closeFallbackTimer = window.setTimeout(() => {
    emitAfterClose();
  }, motionMs > 0 ? motionMs : 0);
}
function handleOverlayCloseMotionEnd(event) {
  if (hasEmittedAfterClose || event.target !== event.currentTarget || !isClosedContentTarget(event.currentTarget)) {
    return;
  }
  emitAfterClose();
}
function setOverlayElement(target) {
  if (target instanceof HTMLElement) {
    overlayElement.value = target;
    syncCloseFallback();
    return;
  }
  if (target && "$el" in target && target.$el instanceof HTMLElement) {
    overlayElement.value = target.$el;
    syncCloseFallback();
    return;
  }
  overlayElement.value = null;
  clearCloseFallbackTimer();
}
watchEffect((onCleanup) => {
  const element = overlayElement.value;
  if (!element) {
    return;
  }
  const observer = new MutationObserver(() => {
    syncCloseFallback();
  });
  observer.observe(element, {
    attributes: true,
    attributeFilter: ["data-state"]
  });
  syncCloseFallback();
  onCleanup(() => {
    observer.disconnect();
  });
});
onBeforeUnmount(() => {
  clearCloseFallbackTimer();
});
</script>

<template>
  <DialogPortal>
    <DialogOverlay
      :ref="setOverlayElement"
      class="fixed inset-0 z-50 flex justify-center overflow-y-auto overscroll-none bg-zinc-900/60 pt-[15vh] pb-8 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0"
      @animationend="handleOverlayCloseMotionEnd"
      @transitionend="handleOverlayCloseMotionEnd"
    >
      <DialogContent
        :class="
  cn(
    'relative z-50 grid w-full max-w-lg self-start gap-4 border border-zinc-200 bg-white p-6 shadow-lg duration-200 sm:rounded-lg',
    props.class
  )
"
        :style="props.contentWidth ? { maxWidth: props.contentWidth } : void 0"
        v-bind="{ ...$attrs, ...forwarded }"
        @pointer-down-outside="(event) => {
  const originalEvent = event.detail.originalEvent;
  const target = originalEvent.target;
  if (originalEvent.offsetX > target.clientWidth || originalEvent.offsetY > target.clientHeight) {
    event.preventDefault();
  }
}"
      >
        <slot />

        <DialogClose
          v-if="showCloseButton"
          class="absolute top-4 right-4 p-0.5 transition-colors rounded-md hover:bg-zinc-100"
        >
          <Icon icon="fluent:dismiss-20-filled" />
          <span class="sr-only">Close</span>
        </DialogClose>
      </DialogContent>
    </DialogOverlay>
  </DialogPortal>
</template>
