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

<script setup>
import { computed, toRef } from "vue";
import { DialogRoot, DialogTrigger, DialogPortal, DialogOverlay, DialogContent, DialogTitle, DialogDescription, DialogClose, VisuallyHidden } from "reka-ui";
import { reactivePick } from "@vueuse/core";
import { useAppConfig } from "#imports";
import { useComponentProps } from "../composables/useComponentProps";
import { useForwardProps } from "../composables/useForwardProps";
import { useBlurOnOpen } from "../composables/useBlurOnOpen";
import { FieldGroupReset } from "../composables/useFieldGroup";
import { useLocale } from "../composables/useLocale";
import { usePortal } from "../composables/usePortal";
import { pointerDownOutside } from "../utils/overlay";
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 },
  overlayBlur: { type: null, required: false, default: "off" },
  transition: { type: Boolean, required: false, default: true },
  side: { type: null, required: false, default: "bottom" },
  inset: { 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 },
  class: { type: null, required: false },
  b24ui: { type: Object, required: false },
  open: { type: Boolean, required: false },
  defaultOpen: { type: Boolean, required: false },
  modal: { type: Boolean, required: false, default: true },
  unmountOnHide: { type: Boolean, required: false }
});
const emits = defineEmits(["leave", "after:leave", "enter", "after:enter", "close:prevent", "update:open"]);
const slots = defineSlots();
const props = useComponentProps("slideover", _props);
const { t } = useLocale();
const appConfig = useAppConfig();
const rootProps = useForwardProps(reactivePick(props, "open", "defaultOpen", "modal", "unmountOnHide"), useBlurOnOpen(() => props.open, emits));
const portalProps = usePortal(toRef(() => props.portal));
const contentProps = toRef(() => props.content);
const contentEvents = computed(() => {
  if (!props.dismissible) {
    const events = ["interactOutside", "escapeKeyDown"];
    return events.reduce((acc, curr) => {
      acc[curr] = (e) => {
        e.preventDefault();
        emits("close:prevent");
      };
      return acc;
    }, {});
  }
  return {
    pointerDownOutside
  };
});
const b24ui = computed(() => tv({ extend: theme, ...appConfig.b24ui?.slideover || {} })({
  transition: props.transition,
  side: props.side,
  inset: props.inset,
  overlayBlur: props.overlayBlur,
  useFooter: !!slots.footer
}));
const isBtnCloseExternal = computed(() => !props.inset && ["left", "right", "bottom"].includes(props?.side) && (props.close || !!slots.close));
</script>

<template>
  <DialogRoot v-slot="{ open, close }" v-bind="rootProps">
    <DialogTrigger v-if="!!slots.default" as-child :class="props.class">
      <slot :open="open" />
    </DialogTrigger>

    <DialogPortal v-bind="portalProps" :force-mount="portalProps.disabled && props.unmountOnHide === false || void 0">
      <FieldGroupReset>
        <DialogOverlay v-if="props.overlay" data-slot="overlay" :class="b24ui.overlay({ class: props.b24ui?.overlay })" />

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

            <DialogDescription v-if="!props.description && !slots.description" />
            <DialogDescription v-else-if="!!slots.content">
              <slot name="description">
                {{ props.description }}
              </slot>
            </DialogDescription>
          </VisuallyHidden>

          <template v-if="isBtnCloseExternal && (props.close || !!slots.close)">
            <DialogClose as-child>
              <slot name="close" :b24ui="b24ui">
                <B24Button
                  v-if="props.close"
                  :icon="props.closeIcon || icons.close"
                  class="group"
                  color="air-primary"
                  :aria-label="t('slideover.close')"
                  size="lg"
                  :b24ui="{
  baseLine: 'ps-1 pe-1',
  label: 'hidden sm:flex'
}"
                  v-bind="typeof props.close === 'object' ? props.close : {}"
                  data-slot="close"
                  :class="b24ui.close({ class: props.b24ui?.close })"
                />
              </slot>
            </DialogClose>
          </template>

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

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

                <slot name="actions" />

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

            <template v-if="!!slots['body']">
              <div data-slot="body" :class="b24ui.body({ class: props.b24ui?.body })">
                <slot name="body" :close="close" />
              </div>
            </template>

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