<script setup lang="ts">
import { computed } from 'vue'
import { useAttrsWithDefaults } from '../../../composables/useAttrsWithDefaults'
import FdsIcon from '../../FdsIcon/FdsIcon.vue'
import type { FdsIconButtonProps } from './types'

const props = withDefaults(defineProps<FdsIconButtonProps>(), {
  size: 24,
  loading: false,
  type: 'button',
  dataTestid: undefined,
})

const { disabled, attrs } = useAttrsWithDefaults(props)

// Generate a readable label from icon name if aria-label is not provided
// Convert camelCase to readable text
const generateAriaLabel = (iconName: string): string =>
  iconName
    .replace(/([A-Z])/g, ' $1')
    .replace(/^./, (str) => str.toUpperCase())
    .trim()

const buttonAttrs = computed(() => {
  // Ensure aria-label exists - use provided one or generate from icon name
  const providedAriaLabel = typeof attrs['aria-label'] === 'string' ? attrs['aria-label'] : undefined
  const ariaLabel: string = providedAriaLabel || (props.loading ? 'Loading' : generateAriaLabel(props.icon))

  const result: Record<string, unknown> = {
    ...attrs,
    type: props.type,
    disabled: disabled.value,
    'aria-label': ariaLabel,
    'aria-disabled': disabled.value || props.loading ? true : undefined,
    'data-testid': props.dataTestid ?? undefined,
  }
  return result as any
})

// Remove padding of button (4px) from the size to get the icon size
const iconSize = computed(() => props.size - 4)

const emit = defineEmits<{
  (e: 'click', ev: MouseEvent): void
}>()

const buttonClasses = computed(() => [
  'inline-flex items-center justify-center rounded-md p-[2px] max-w-[48px] max-h-[48px] transition-colors duration-200 fill-blue-500 hover:bg-blue_t-100 active:bg-blue_t-200 focus-visible:outline-dashed focus-visible:outline-2 outline-blue-500',
  disabled.value ? 'opacity-20 cursor-not-allowed' : 'cursor-pointer',
])

const onClick = (ev: MouseEvent) => {
  if (disabled.value || props.loading) {
    ev.preventDefault()
    return
  }
  emit('click', ev)
}
</script>

<template>
  <button v-bind="buttonAttrs" :class="buttonClasses" @click="onClick">
    <FdsIcon v-if="!loading" :size="iconSize" :name="icon" aria-hidden="true" />
    <FdsIcon v-else :size="iconSize" name="spinner" class="animate-spin" aria-hidden="true" />
  </button>
</template>
