<script setup lang="ts">
import VButton from './VButton.vue';
import type IVButtonGroup from './IVButton.type.ts';
import { computed, ref, onMounted } from 'vue';

const props = withDefaults(defineProps<IVButtonGroup>(), {
    buttons: () => [],
    inlineLayoutWhen: 'never',
    size: 'md',
    align: undefined,
    iconRight: false,
})

// Reference to <ul> element containing buttons
const buttonsEl = ref<HTMLUListElement | null>(null)

// Determines whether the layout should be in line
const inlineAlways = computed(() => ['always', '', true].includes(props.inlineLayoutWhen))
const inlineSm = computed(() => ['sm', 'small'].includes(props.inlineLayoutWhen as string))
const inlineMd = computed(() => ['md', 'medium'].includes(props.inlineLayoutWhen as string))
const inlineLg = computed(() => ['lg', 'large'].includes(props.inlineLayoutWhen as string))

// Horizontal alignment of button group
const center = computed(() => props.align === 'center')
const right = computed(() => props.align === 'right')

// Uniform width for all buttons
const equisizedWidth = ref('auto')
const groupStyle = computed(() => `--equisized-width: ${equisizedWidth.value};`)

// Function for calculating maximum button width and applying it to all buttons
const computeEquisizedWidth = async () => {
  let maxWidth = 0
  await new Promise((resolve) => setTimeout(resolve, 100))
  buttonsEl.value?.querySelectorAll('.p-button').forEach((btn: Element) => {
    const button = btn as HTMLButtonElement
    const width = button.offsetWidth
    const buttonStyle = window.getComputedStyle(button)
    const marginLeft = +buttonStyle.marginLeft.replace('px', '')
    const marginRight = +buttonStyle.marginRight.replace('px', '')
    button.style.width = 'var(--equisized-width)'
    const newWidth = width + marginLeft + marginRight
    if (newWidth > maxWidth) {
      maxWidth = newWidth
    }
  })
  equisizedWidth.value = `${maxWidth}px`
}

// Calculation of uniform installation width if necessary
onMounted(async () => {
  if (!buttonsEl.value || !props.equisized) {
    return
  }
  await computeEquisizedWidth()
})
</script>

<template>
  <ul
    ref="buttonsEl"
    role="list"
    :style="groupStyle"
    class="btns-group"
    :class="{
      'btns-group--equisized': equisized,
      'btns-group--inline': inlineAlways || inlineSm || inlineMd || inlineLg,
      'btns-group--center': center,
      'btns-group--right': right,
      'btns-group--inline-reverse': reverse,
    }"
  >
    <li v-for="({onClick, title, ...button}, i) in buttons" :key="i" role="listitem">
      <VButton
        v-bind="button"
        @click="onClick"
        :size="props.size"
        :icon-right="props.iconRight"
        :title="title"
      />
    </li>
    <slot/>
  </ul>
</template>

<style lang="css" scoped>
.btns-group{
  display: flex;
  flex-wrap: wrap;
  flex-direction: column;
  gap: 0.5rem;
  list-style: none;
  padding: 0px;
  margin: 0px;
}

.btns-group--equisized{width: var(--equisized-width, auto);}
.btns-group--inline{flex-direction: row;}
.btns-group--center{justify-content: center;}
.btns-group--right{justify-content: flex-end;}
.btns-group--inline-reverse{flex-direction: row-reverse;}

</style>
