<template>
  <div class="cpItemActions" :class="componentDynamicClasses">
    <cp-button-group v-if="hasActions" class="cpItemActions__buttonGroup">
      <cp-menu-item
        v-for="(action, index) in slicedActions"
        v-bind="action"
        :key="index"
        hide-label
        :leading-icon="action.icon"
      />
    </cp-button-group>
    <cp-contextual-menu
      ref="contextualMenu"
      :items="actions"
      @hide="handleDropdownState(false)"
      @show="handleDropdownState(true)"
    />
  </div>
</template>

<script setup lang="ts">
import type { MenuItem } from 'primevue/menuitem'
import { computed, ref } from 'vue'

import CpButtonGroup from '@/components/CpButtonGroup.vue'
import CpContextualMenu from '@/components/CpContextualMenu.vue'
import CpMenuItem from '@/components/CpMenuItem.vue'

export interface Props {
  actions: MenuItem[]
  iconPosition?: 'horizontal' | 'vertical'
  quickOptionsLimit?: number
}

const props = withDefaults(defineProps<Props>(), { quickOptionsLimit: 2, iconPosition: 'horizontal' })

const componentDynamicClasses = computed(() => ({ 'cpItemActions--isDropdownOpen': isDropdownOpen.value }))

const contextualMenu = ref<InstanceType<typeof CpContextualMenu>>()
const isDropdownOpen = ref(false)

const showContextualMenu = (event: MouseEvent) => contextualMenu.value?.show(event)

const defaultAction = computed(() => ({
  icon: `more-${props.iconPosition}`,
  command: (event: MouseEvent) => showContextualMenu(event),
}))

const hasActions = computed(() => !!props.actions.length)

const slicedActions = computed(() => {
  const actionsCopy = [...props.actions]

  if (actionsCopy.length <= props.quickOptionsLimit) {
    return [...actionsCopy, defaultAction.value]
  }

  const firstActions = actionsCopy.slice(0, props.quickOptionsLimit)
  return [...firstActions, defaultAction.value]
})

const handleDropdownState = (state: boolean) => (isDropdownOpen.value = state)
</script>

<style lang="scss">
.cpItemActions {
  position: absolute;
  top: 50%;
  right: 0;
  transform: translate3d(calc(var(--cp-dimensions-1) * 1.25), -50%, 0);
  transition:
    transform 150ms ease,
    opacity 150ms ease;

  &__buttonGroup {
    background-color: var(--cp-background-primary);
  }

  .cpMenuItem__button {
    padding: var(--cp-spacing-sm-md);
    border-radius: 0;
  }

  .cpMenuItem {
    padding: 0;

    &:first-child .cpMenuItem__button {
      border-bottom-left-radius: var(--cp-radius-md);
      border-top-left-radius: var(--cp-radius-md);
    }

    &:last-child .cpMenuItem__button {
      border-bottom-right-radius: var(--cp-radius-md);
      border-top-right-radius: var(--cp-radius-md);
    }
  }
}

[cp-item-actions-trigger] {
  position: relative;
}

@include mx.media-query-pointer-device-only {
  .cpItemActions {
    opacity: 0;
    pointer-events: none;
  }

  [cp-item-actions-trigger]:has(.cpItemActions--isDropdownOpen) .cpItemActions,
  [cp-item-actions-trigger]:is(:focus-within, :focus-visible, :hover) .cpItemActions {
    opacity: 1;
    pointer-events: auto;
  }
}
</style>
