<script setup lang="ts">
import { XIcon } from '@lucide/vue'
import type { HTMLAttributes } from 'vue'
import { inject, ref, watch } from 'vue'
import { useScrollLock } from '@vueuse/core'
import { cn } from '@/lib/utils'
import { useFocusTrap } from '@/lib/use-focus-trap'
import { useDismissableLayer } from '@/lib/use-dismissable-layer'
import { DialogContextKey } from './context'
import DialogClose from './DialogClose.vue'

defineOptions({ inheritAttrs: false })

const props = defineProps<{ class?: HTMLAttributes['class'] }>()

const context = inject(DialogContextKey)!
const contentRef = ref<HTMLElement | null>(null)

useFocusTrap(contentRef, context.open)
useDismissableLayer(contentRef, context.open, {
  onDismiss: () => { context.open.value = false },
  onPointerDownOutside: (event) => {
    const target = event.target as HTMLElement
    if (event.offsetX > target.clientWidth || event.offsetY > target.clientHeight) {
      event.preventDefault()
    }
  },
})

const isLocked = useScrollLock(document.body)
watch(context.open, (value) => { isLocked.value = value }, { immediate: true })
</script>

<template>
  <Teleport to="body">
    <Transition
      enter-active-class="animate-in fade-in-0 animation-duration-100"
      leave-active-class="animate-out fade-out-0 animation-duration-100"
    >
      <div
        v-if="context.open.value"
        class="fixed inset-0 z-50 grid place-items-center overflow-y-auto bg-black/80"
      >
        <div
          ref="contentRef"
          data-slot="dialog-content"
          role="dialog"
          aria-modal="true"
          :aria-labelledby="context.titleId"
          :aria-describedby="context.descriptionId"
          tabindex="-1"
          v-bind="$attrs"
          :class="cn(
            'relative z-50 grid w-full max-w-lg my-8 gap-4 border border-border bg-background p-6 shadow-lg sm:rounded-lg md:w-full',
            props.class,
          )"
        >
          <slot />

          <DialogClose class="absolute top-4 right-4 p-0.5 transition-colors rounded-md hover:bg-secondary">
            <XIcon class="w-4 h-4" />
            <span class="sr-only">Close</span>
          </DialogClose>
        </div>
      </div>
    </Transition>
  </Teleport>
</template>
