<template>
  <Teleport to="body">
    <Transition name="modal-fade" @after-enter="onOpened" @after-leave="onClosed">
      <div v-if="modelValue" class="modal-backdrop open" @click="handleBackdropClick">
        <div class="modal-container" :class="['modal-container-' + size, { 'open': modelValue }]" role="dialog"
          aria-modal="true" :aria-labelledby="titleId" :aria-describedby="bodyId" @click.stop>
          <div v-if="$slots.header || title || !hideCloseButton" class="modal-header">
            <slot name="header">
              <h3 v-if="title" :id="titleId" class="modal-title">{{ title }}</h3>
              <button v-if="!hideCloseButton" type="button" class="close-button" @click="closeModal"
                aria-label="Close modal">
                <VIcon name="close" />
              </button>
            </slot>
          </div>

          <div class="modal-body" :id="bodyId">
            <slot></slot>
          </div>

          <div v-if="$slots.footer" class="modal-footer">
            <slot name="footer"></slot>
          </div>
        </div>
      </div>
    </Transition>
  </Teleport>
</template>

<script lang="ts" setup>
import { computed, watch, onMounted, onBeforeUnmount, ref } from 'vue';
import VIcon from './VIcon.vue'; // Assuming VIcon is available

const props = defineProps({
  modelValue: {
    type: Boolean,
    required: true,
  },
  title: {
    type: String,
    default: null,
  },
  hideCloseButton: {
    type: Boolean,
    default: false,
  },
  persistent: {
    type: Boolean,
    default: false,
  },
  size: {
    type: String, // 'sm', 'md', 'lg'
    default: 'md',
    validator: (value: string) => ['sm', 'md', 'lg'].includes(value),
  },
  idBase: {
    type: String,
    default: null,
  },
});

const emit = defineEmits(['update:modelValue', 'close', 'opened', 'closed']);

const uniqueComponentId = ref(`modal-${Math.random().toString(36).substring(2, 9)}`);

const titleId = computed(() => props.idBase ? `${props.idBase}-title` : `${uniqueComponentId.value}-title`);
const bodyId = computed(() => props.idBase ? `${props.idBase}-description` : `${uniqueComponentId.value}-description`);

const closeModal = () => {
  emit('update:modelValue', false);
  emit('close');
};

const handleBackdropClick = () => {
  if (!props.persistent) {
    closeModal();
  }
};

const handleEscKey = (event: KeyboardEvent) => {
  if (event.key === 'Escape' && props.modelValue) {
    closeModal();
  }
};

watch(() => props.modelValue, (isOpen) => {
  if (isOpen) {
    document.body.classList.add('modal-open');
    document.addEventListener('keydown', handleEscKey);
  } else {
    document.body.classList.remove('modal-open');
    document.removeEventListener('keydown', handleEscKey);
  }
});

// Cleanup listener if component is unmounted while modal is open
onBeforeUnmount(() => {
  if (props.modelValue) {
    document.body.classList.remove('modal-open');
    document.removeEventListener('keydown', handleEscKey);
  }
});

const onOpened = () => {
  emit('opened');
};

const onClosed = () => {
  emit('closed');
};

</script>

<style lang="scss">
// Global style for body when modal is open - this is the only style needed
// All other modal styles are in valerie-ui.scss
body.modal-open {
  overflow: hidden;
}
</style>
