<template>
  <div class="itf-dropdown__menu dropdown-menu" ref="dropdown" :aria-labelledby="modalId" :class="{'dropdown-menu-end': right, 'shadow': shadow}">
    <slot></slot>
  </div>
</template>
<script>
import { Vue, Component, Prop, Watch, PropSync } from 'vue-property-decorator';

let globalModalIndex = 0; // base modal z-index

export default @Component({
  name: 'itfDropdownMenu'
})
class itfDropdownMenu extends Vue {
  @PropSync('visible') value;
  @Prop({ type: String, default: 'down', validator: (value) => ['down', 'start', 'end', 'up'].includes(value) }) placement;
  @Prop({ type: String, default: 'click', validator: (value) => ['click', 'focus', 'hover', 'manual'].includes(value) }) trigger;
  @Prop({ type: String, default: 'Dropdown' }) label;
  @Prop({ type: Boolean }) right;
  @Prop({ type: Boolean }) toggle;
  @Prop({ type: Boolean }) shadow;
  @Prop({ type: Boolean }) disabled;
  @Prop({ type: Boolean }) text;
  @Prop({ type: Boolean }) appendToBody;
  @Prop({ type: Boolean }) appendToContext;
  @Prop({ type: String }) toggleId;
  @Prop({ validator: (value) => [true, false, 'inside', 'outside'].includes(value), default: true }) autoclose;
  @Prop({ type: Object, default: () => ({}) }) buttonOptions;
  @Prop({ type: Object, default: () => ({}) }) menuOptions;

  modalId = '';
  modalEl = null;

  async mounted() {
    this.modalId = `dropdownId${globalModalIndex++}`;
    const toggle = document.getElementById(this.toggleId);
    if (typeof window === 'undefined' || !toggle) {
      return;
    }
    const { default: Dropdown } = await import('bootstrap/js/src/dropdown.js');
    let context = document.body;
    this.modalEl = new Dropdown(toggle, {
      reference: 'parent',
      autoClose: this.autoclose
    });
    if (this.appendToContext && this.$el instanceof Node && this.$el.parentNode) {
      context = this.$el.closest('.itf-append-context') || document.body;
      this.$el.parentNode.removeChild(this.$el);
      context.appendChild(this.$el); // should append only to body
    } else if (this.appendToBody && this.$el instanceof Node && this.$el.parentNode) {
      this.$el.parentNode.removeChild(this.$el);
      context.appendChild(this.$el); // should append only to body
    }

    toggle.addEventListener('shown.bs.dropdown', () => {
      this.$emit('open');
    });
    toggle.addEventListener('hidden.bs.dropdown', () => {
      this.$emit('close');
    });
  }

  beforeDestroy() {
    try {
      if (this.modalEl) {
        this.modalEl.hide();
        this.modalEl.dispose();
      }
    } catch (err) {
      // ignore
    }
  }

  show() {
    console.info('p[en')
    if (this.modalEl) {
      this.modalEl.show();
    }
  }

  hide() {
    if (this.modalEl) {
      this.modalEl.hide();
    }
  }
}
</script>
