<template>
  <div class="bookaro-actions-menu">
    <button
      type="button"
      class="bookaro-actions-menu__toggle"
      :aria-label="label"
      aria-haspopup="menu"
      :aria-expanded="open ? 'true' : 'false'"
      @click="toggle"
    >
      <ActionIcon name="ellipsis" />
    </button>

    <div
      v-if="open"
      class="bookaro-actions-menu__panel"
      role="menu"
    >
      <button
        v-for="item in visibleItems"
        :key="item.key || item.label"
        type="button"
        class="bookaro-actions-menu__item"
        :class="itemClass(item)"
        role="menuitem"
        :disabled="!!item.disabled"
        @click="handleItem(item)"
      >
        <ActionIcon v-if="item.icon" :name="item.icon" />
        <span>{{ item.label }}</span>
      </button>
    </div>
  </div>
</template>

<script>
import ActionIcon from '../ActionIcon.vue';

export default {
  name: 'ActionsMenu',
  components: { ActionIcon },
  props: {
    items: { type: Array, default: () => [] },
    label: { type: String, default: '' }
  },
  data() {
    return {
      open: false
    };
  },
  computed: {
    visibleItems() {
      return (this.items || []).filter(item => item && item.visible !== false);
    }
  },
  mounted() {
    document.addEventListener('click', this.onDocumentClick);
    document.addEventListener('keydown', this.onDocumentKeydown);
  },
  beforeUnmount() {
    document.removeEventListener('click', this.onDocumentClick);
    document.removeEventListener('keydown', this.onDocumentKeydown);
  },
  methods: {
    toggle() {
      this.open = !this.open;
    },
    close() {
      this.open = false;
    },
    onDocumentClick(event) {
      if (!this.open) {
        return;
      }
      const target = event?.target;
      if (!target || typeof target.closest !== 'function') {
        this.close();
        return;
      }
      if (target.closest('.bookaro-actions-menu')) {
        return;
      }
      this.close();
    },
    onDocumentKeydown(event) {
      if (!this.open) {
        return;
      }
      if (event.key === 'Escape') {
        this.close();
      }
    },
    itemClass(item) {
      const classes = [];
      if (item.variant === 'danger') {
        classes.push('bookaro-actions-menu__item--danger');
      }
      if (item.disabled) {
        classes.push('is-disabled');
      }
      return classes.join(' ');
    },
    handleItem(item) {
      if (!item || item.disabled) {
        return;
      }
      if (typeof item.onClick === 'function') {
        item.onClick();
      }
      this.close();
    }
  }
};
</script>
