<script>
import theme from "#build/b24ui/modal";
</script>

<script setup>
import { computed, toRef } from "vue";
import { DialogRoot, DialogTrigger, DialogPortal, DialogOverlay, DialogContent, DialogTitle, DialogDescription, DialogClose, VisuallyHidden, useForwardPropsEmits } from "reka-ui";
import { reactivePick, createReusableTemplate } from "@vueuse/core";
import { useAppConfig } from "#imports";
import { useLocale } from "../composables/useLocale";
import { usePortal } from "../composables/usePortal";
import { tv } from "../utils/tv";
import icons from "../dictionary/icons";
import B24Button from "./Button.vue";
const props = defineProps({
  title: { type: String, required: false },
  description: { type: String, required: false },
  content: { type: Object, required: false },
  overlay: { type: Boolean, required: false, default: true },
  scrollable: { type: Boolean, required: false },
  overlayBlur: { type: null, required: false, default: "auto" },
  transition: { type: Boolean, required: false, default: true },
  fullscreen: { type: Boolean, required: false },
  portal: { type: [Boolean, String], required: false, skipCheck: true, default: true },
  close: { type: [Boolean, Object], required: false, default: true },
  closeIcon: { type: [Function, Object], required: false },
  dismissible: { type: Boolean, required: false, default: true },
  scrollbarThin: { type: Boolean, required: false, default: true },
  class: { type: null, required: false },
  b24ui: { type: null, required: false },
  open: { type: Boolean, required: false },
  defaultOpen: { type: Boolean, required: false },
  modal: { type: Boolean, required: false, default: true }
});
const emits = defineEmits(["after:leave", "after:enter", "close:prevent", "update:open"]);
const slots = defineSlots();
const { t } = useLocale();
const appConfig = useAppConfig();
const rootProps = useForwardPropsEmits(reactivePick(props, "open", "defaultOpen", "modal"), emits);
const portalProps = usePortal(toRef(() => props.portal));
const contentProps = toRef(() => props.content);
const contentEvents = computed(() => {
  if (!props.dismissible) {
    const events = ["pointerDownOutside", "interactOutside", "escapeKeyDown"];
    return events.reduce((acc, curr) => {
      acc[curr] = (e) => {
        e.preventDefault();
        emits("close:prevent");
      };
      return acc;
    }, {});
  }
  if (props.scrollable) {
    return {
      // FIXME: This is a workaround to prevent the modal from closing when clicking on the scrollbar https://reka-ui.com/docs/components/dialog#scrollable-overlay but it's not working on Mac OS.
      pointerDownOutside: (e) => {
        const originalEvent = e.detail.originalEvent;
        const target = originalEvent.target;
        if (originalEvent.offsetX > target.clientWidth || originalEvent.offsetY > target.clientHeight) {
          e.preventDefault();
        }
      }
    };
  }
  return {};
});
const [DefineContentTemplate, ReuseContentTemplate] = createReusableTemplate();
const b24ui = computed(() => tv({ extend: tv(theme), ...appConfig.b24ui?.modal || {} })({
  transition: props.transition,
  fullscreen: props.fullscreen,
  overlayBlur: props.overlayBlur,
  overlay: props.overlay,
  scrollable: props.scrollable
}));
</script>

<template>
  <DialogRoot v-slot="{ open, close }" v-bind="rootProps">
    <DefineContentTemplate>
      <DialogContent
        data-slot="content"
        :class="b24ui.content({ class: [!slots.default && props.class, props.b24ui?.content] })"
        v-bind="contentProps"
        @after-enter="emits('after:enter')"
        @after-leave="emits('after:leave')"
        v-on="contentEvents"
      >
        <VisuallyHidden v-if="!!slots.content && (title || !!slots.title || (description || !!slots.description))">
          <DialogTitle v-if="title || !!slots.title">
            <slot name="title">
              {{ title }}
            </slot>
          </DialogTitle>

          <DialogDescription v-if="description || !!slots.description">
            <slot name="description">
              {{ description }}
            </slot>
          </DialogDescription>
        </VisuallyHidden>

        <slot name="content" :close="close">
          <div
            v-if="!!slots.header || (title || !!slots.title) || (description || !!slots.description) || (props.close || !!slots.close) || !!slots.body"
            data-slot="contentWrapper"
            :class="b24ui.contentWrapper({ class: props.b24ui?.contentWrapper })"
          >
            <div v-if="!!slots.header || (title || !!slots.title) || (description || !!slots.description) || (props.close || !!slots.close)" data-slot="header" :class="b24ui.header({ class: props.b24ui?.header })">
              <slot name="header" :close="close">
                <div data-slot="wrapper" :class="b24ui.wrapper({ class: props.b24ui?.wrapper })">
                  <DialogTitle v-if="title || !!slots.title" data-slot="title" :class="b24ui.title({ class: props.b24ui?.title })">
                    <slot name="title">
                      {{ title }}
                    </slot>
                  </DialogTitle>

                  <DialogDescription v-if="description || !!slots.description" data-slot="description" :class="b24ui.description({ class: props.b24ui?.description })">
                    <slot name="description">
                      {{ description }}
                    </slot>
                  </DialogDescription>
                </div>

                <slot name="actions" />

                <DialogClose v-if="props.close || !!slots.close" as-child>
                  <slot name="close" :b24ui="b24ui">
                    <B24Button
                      v-if="props.close"
                      :icon="closeIcon || icons.close"
                      size="md"
                      color="air-tertiary-no-accent"
                      :aria-label="t('modal.close')"
                      v-bind="typeof props.close === 'object' ? props.close : {}"
                      data-slot="close"
                      :class="b24ui.close({ class: props.b24ui?.close })"
                    />
                  </slot>
                </DialogClose>
              </slot>
            </div>

            <div v-if="!!slots.body" data-slot="body" :class="b24ui.body({ class: props.b24ui?.body, scrollbarThin: Boolean(props.scrollbarThin) })">
              <slot name="body" :close="close" />
            </div>
          </div>

          <div v-if="!!slots.footer" data-slot="footer" :class="b24ui.footer({ class: props.b24ui?.footer })">
            <slot name="footer" :close="close" />
          </div>
        </slot>
      </DialogContent>
    </DefineContentTemplate>

    <DialogTrigger v-if="!!slots.default" as-child :class="props.class">
      <slot :open="open" />
    </DialogTrigger>

    <DialogPortal v-bind="portalProps">
      <template v-if="scrollable">
        <DialogOverlay data-slot="overlay" :class="b24ui.overlay({ class: props.b24ui?.overlay })">
          <ReuseContentTemplate />
        </DialogOverlay>
      </template>

      <template v-else>
        <DialogOverlay v-if="overlay" data-slot="overlay" :class="b24ui.overlay({ class: props.b24ui?.overlay })" />

        <ReuseContentTemplate />
      </template>
    </DialogPortal>
  </DialogRoot>
</template>
