<template>
  <Popover v-slot="{ open, close }" :class="ui.wrapper" @mouseleave="onMouseLeave">
    <PopoverButton
      ref="trigger"
      as="div"
      :disabled="disabled"
      class="inline-flex w-full"
      role="button"
      @mouseover="onMouseOver"
    >
      <slot :open="open" :close="close">
        <button :disabled="disabled">
          Open
        </button>
      </slot>
    </PopoverButton>

    <div v-if="open" ref="container" :class="[ui.container, ui.width]" @mouseover="onMouseOver">
      <transition appear v-bind="ui.transition">
        <PopoverPanel :class="[ui.base, ui.background, ui.ring, ui.rounded, ui.shadow]" static>
          <slot name="panel" :open="open" :close="close" />
        </PopoverPanel>
      </transition>
    </div>
  </Popover>
</template>

<script>
import { computed, ref, onMounted, defineComponent } from "vue";
import { defu } from "defu";
import { Popover, PopoverButton, PopoverPanel } from "@headlessui/vue";
import { usePopper } from "../../composables/usePopper";
import { useAppConfig } from "#imports";
import appConfig from "#build/app.config";
export default defineComponent({
  components: {
    Popover,
    PopoverButton,
    PopoverPanel
  },
  props: {
    mode: {
      type: String,
      default: "click",
      validator: (value) => {
        return ["click", "hover"].includes(value);
      }
    },
    disabled: {
      type: Boolean,
      default: false
    },
    openDelay: {
      type: Number,
      default: 50
    },
    closeDelay: {
      type: Number,
      default: 0
    },
    popper: {
      type: Object,
      default: () => ({})
    },
    ui: {
      type: Object,
      default: () => appConfig.ui.popover
    }
  },
  setup(props) {
    const appConfig2 = useAppConfig();
    const ui = computed(() => defu({}, props.ui, appConfig2.ui.popover));
    const popper = computed(() => defu({}, props.popper, ui.value.popper));
    const [trigger, container] = usePopper(popper.value);
    const popoverApi = ref(null);
    let openTimeout = null;
    let closeTimeout = null;
    onMounted(() => {
      setTimeout(() => {
        const popoverProvides = trigger.value?.$.provides;
        if (!popoverProvides) {
          return;
        }
        const popoverProvidesSymbols = Object.getOwnPropertySymbols(popoverProvides);
        popoverApi.value = popoverProvidesSymbols.length && popoverProvides[popoverProvidesSymbols[0]];
      }, 200);
    });
    function onMouseOver() {
      if (props.mode !== "hover" || !popoverApi.value) {
        return;
      }
      if (closeTimeout) {
        clearTimeout(closeTimeout);
        closeTimeout = null;
      }
      if (popoverApi.value.popoverState === 0) {
        return;
      }
      openTimeout = openTimeout || setTimeout(() => {
        popoverApi.value.togglePopover && popoverApi.value.togglePopover();
        openTimeout = null;
      }, props.openDelay);
    }
    function onMouseLeave() {
      if (props.mode !== "hover" || !popoverApi.value) {
        return;
      }
      if (openTimeout) {
        clearTimeout(openTimeout);
        openTimeout = null;
      }
      if (popoverApi.value.popoverState === 1) {
        return;
      }
      closeTimeout = closeTimeout || setTimeout(() => {
        popoverApi.value.closePopover && popoverApi.value.closePopover();
        closeTimeout = null;
      }, props.closeDelay);
    }
    return {
      // eslint-disable-next-line vue/no-dupe-keys
      ui,
      trigger,
      container,
      onMouseOver,
      onMouseLeave
    };
  }
});
</script>
