<template>
  <Teleport v-if="modelValue" to="#wrapper">
    <div @click="onClick" class="popup">
      <slot />
    </div>
  </Teleport>
</template>

<script lang="ts" setup>
import { onKeyDown } from '@vueuse/core'

const props = defineProps({
  modelValue: {
    type: Boolean,
    required: true,
  },
})

const emit = defineEmits<{
  'update:modelValue': [boolean]
  'close': []
}>()

const popupsVisible = usePopupsVisible()
const stop: (() => void)[] = []

let id = 0

watch(
  () => props.modelValue,
  (isVisible) => {
    if (isVisible) {
      id = ++popupsVisible.value
      stop.push(
        onKeyDown('Escape', () => {
          if (id === popupsVisible.value) {
            emit('close')
            emit('update:modelValue', false)
          }
        }),
      )
    } else {
      if (id) {
        popupsVisible.value--
        id = 0
      }
      stop.forEach((fn) => fn())
      stop.splice(0, stop.length)
    }
  },
  { immediate: true },
)

onUnmounted(() => {
  if (id) {
    popupsVisible.value--
    stop.forEach((fn) => fn())
  }
})

function onClick(event: MouseEvent) {
  if (event.target === event.currentTarget) {
    event.stopPropagation()
    emit('close')
    emit('update:modelValue', false)
  }
}
</script>

<style scoped>
.popup {
  position: absolute;
  z-index: 20;
  top: 0;
  left: 0;
  display: flex;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.64);
  overflow-y: auto;
}

.popup > * {
  margin: auto;
}
</style>
