<template>
    <Teleport to="body">
        <Transition
            enter-active-class="transition duration-150 ease-out"
            enter-from-class="opacity-0"
            enter-to-class="opacity-100"
            leave-active-class="transition duration-100 ease-in"
            leave-from-class="opacity-100"
            leave-to-class="opacity-0"
        >
            <div
                v-if="modelValue"
                class="fixed inset-0 z-40 flex items-center justify-center bg-black/50 px-4"
                role="dialog"
                aria-modal="true"
                @mousedown.self="closeOnBackdrop"
            >
                <div
                    class="w-full rounded-md bg-white shadow-2xl"
                    :class="maxWidth"
                    @mousedown.stop
                >
                    <div class="flex items-center justify-between border-b border-slate-200 px-6 py-4">
                        <h2 class="text-xl font-bold uppercase text-primary-500">{{ title }}</h2>
                        <button
                            type="button"
                            class="text-slate-500 hover:text-primary-500 flex items-center"
                            aria-label="Fermer"
                            @click="close"
                        >
                            <Icon name="mdi:close" size="24" />
                        </button>
                    </div>

                    <div class="px-6 py-5">
                        <slot />
                    </div>

                    <div
                        v-if="$slots.footer"
                        class="border-t border-slate-200 px-6 py-4"
                    >
                        <slot name="footer" :close="close" />
                    </div>
                </div>
            </div>
        </Transition>
    </Teleport>
</template>

<script setup lang="ts">
import { onMounted, onBeforeUnmount, watch } from 'vue'

const props = withDefaults(defineProps<{
    modelValue: boolean
    title?: string
    closeOnBackdropClick?: boolean
    maxWidth?: string
}>(), {
    title: '',
    closeOnBackdropClick: true,
    maxWidth: 'max-w-lg'
})

const emit = defineEmits<{
    (e: 'update:modelValue', value: boolean): void
}>()

const close = () => emit('update:modelValue', false)

const closeOnBackdrop = () => {
    if (props.closeOnBackdropClick) close()
}

const onKeydown = (event: KeyboardEvent) => {
    if (event.key === 'Escape' && props.modelValue) close()
}

watch(() => props.modelValue, (open) => {
    if (typeof document === 'undefined') return
    document.body.style.overflow = open ? 'hidden' : ''
})

onMounted(() => {
    if (typeof document !== 'undefined') {
        document.addEventListener('keydown', onKeydown)
    }
})

onBeforeUnmount(() => {
    if (typeof document !== 'undefined') {
        document.removeEventListener('keydown', onKeydown)
        document.body.style.overflow = ''
    }
})
</script>
