<template>
  <div class="dropdown-wrapper">
    <button
      ref="dropdownBtnRef"
      class="dropdown-btn btn btn-xs btn-icon"
      @click.stop="toggleOptions"
    >
      <slot>
        <Icon icon="mdi:dots-horizontal" class="icon-sm" />
      </slot>
    </button>
    <Teleport to="body">
      <div 
        v-show="show" 
        ref="dropdownRef" 
        class="dropdown-menu"
        :style="dropdownStyle"
      >
        <div class="dropdown-options">
          <div v-for="group in groups" :key="group.key" class="groups">
            <div v-if="group.group" class="group-title">
              {{ group.group }}
            </div>
            <div
              class="dropdown-option"
              v-for="item in group.items"
              :key="item.label"
              :title="item.tooltip"
            >
              <button class="dropdown-item" @click.stop="action(item.onClick)">
                {{ item.label }}
              </button>
            </div>
          </div>
        </div>
      </div>
    </Teleport>
  </div>
</template>

<script setup>
import { nextTick, ref, computed, onMounted, onUnmounted } from "vue";
import { onClickOutside } from "@vueuse/core";
import { Icon } from '@iconify/vue';

const props = defineProps({
  options: {
    type: Array,
    required: true,
  },
  placement: {
    type: String,
    default: "bottom-end",
  },
});

const show = ref(false);
const dropdownBtnRef = ref(null);
const dropdownRef = ref(null);
const dropdownStyle = ref({});

onClickOutside(dropdownBtnRef, () => (show.value = false), { ignore: [dropdownRef] });

const groups = computed(() => {
  let _groups = props.options[0]?.group ? props.options : [{ group: "", items: props.options }];

  return _groups.map((group, i) => {
    return {
      key: i,
      group: group.group,
      items: group.items,
    };
  });
});

function updatePosition() {
  if (!dropdownBtnRef.value || !show.value) return;
  
  const rect = dropdownBtnRef.value.getBoundingClientRect();
  dropdownStyle.value = {
    position: 'fixed',
    top: `${rect.bottom + 4}px`,
    left: props.placement === 'bottom-end' ? 'auto' : `${rect.left}px`,
    right: props.placement === 'bottom-end' ? `${window.innerWidth - rect.right}px` : 'auto',
    zIndex: 1000,
  };
}

function toggleOptions() {
  show.value = !show.value;
  nextTick(() => updatePosition());
}

function action(clickEvent) {
  clickEvent && clickEvent();
  show.value = false;
}
</script>

<style lang="scss" scoped>
.dropdown-wrapper {
  position: relative;
}

.groups {
  padding: 5px;

  .group-title {
    display: flex;
    align-items: center;
    padding: 4px 8px;
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    color: #9ca3af;
  }
}

.dropdown-btn {
  padding: 2px;
  border: none;
  background: transparent;
  cursor: pointer;
  
  &:hover {
    background-color: #f3f4f6;
    border-radius: 4px;
  }
}

.dropdown-menu {
  min-width: 150px;
}

.dropdown-options {
  background-color: #fff;
  border-radius: 8px;
  box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
  padding: 4px;
  border: 1px solid #e5e7eb;
}

.dropdown-option {
  .dropdown-item {
    width: 100%;
    text-align: left;
    padding: 8px 12px;
    border: none;
    background: transparent;
    cursor: pointer;
    font-size: 13px;
    border-radius: 4px;
    color: #374151;
    
    &:hover {
      background-color: #f3f4f6;
    }
  }
}

.icon-sm {
  width: 14px;
  height: 14px;
}
</style>
