<template>
  <button
    :id="buttonId"
    :class="mergedButtonClass"
    :disabled="disabled"
    type="button"
    v-bind="attrs"
    @click="onClick"
  >
    <IconifyIcon
      v-if="iconName && iconPosition === 'left'"
      :icon="iconName"
      :width="iconSize"
      :height="iconSize"
      data-test="icon-left"
    />

    <span><slot>{{ label }}</slot></span>

    <IconifyIcon
      v-if="iconName && iconPosition === 'right'"
      :icon="iconName"
      :width="iconSize"
      :height="iconSize"
      data-test="icon-right"
    />
  </button>
</template>

<script setup lang="ts">
import { computed, useAttrs, useId } from 'vue'
import { Icon as IconifyIcon } from '@iconify/vue'
import { twMerge } from 'tailwind-merge'

defineOptions({ name: 'MalioButton', inheritAttrs: false })

const props = withDefaults(
  defineProps<{
    id?: string
    label?: string
    disabled?: boolean
    buttonClass?: string
    variant?: 'primary' | 'secondary' | 'tertiary' | 'danger'
    iconName?: string
    iconPosition?: 'left' | 'right'
    iconSize?: string | number
  }>(),
  {
    id: '',
    label: '',
    disabled: false,
    buttonClass: '',
    variant: 'primary',
    iconName: '',
    iconPosition: 'right',
    iconSize: 16,
  },
)

const attrs = useAttrs()
const generatedId = useId()

const buttonId = computed(() => props.id || `malio-button-${generatedId}`)

const variantClasses = computed(() => {
  if (props.disabled) {
    if (props.variant === 'tertiary') {
      return 'border border-m-disabled text-m-disabled bg-transparent cursor-not-allowed'
    }
    return 'bg-m-disabled text-white cursor-not-allowed'
  }

  switch (props.variant) {
    case 'secondary':
      return 'bg-m-btn-secondary hover:bg-m-btn-secondary-hover active:bg-m-btn-secondary-active text-white cursor-pointer'
    case 'tertiary':
      return 'border border-m-btn-primary bg-transparent text-m-btn-primary hover:border-m-btn-primary-hover hover:text-m-btn-primary-hover active:border-m-btn-primary-active active:text-m-btn-primary-active cursor-pointer'
    case 'danger':
      return 'bg-m-btn-danger hover:bg-m-btn-danger-hover active:bg-m-btn-danger-active text-white cursor-pointer'
    default:
      return 'bg-m-btn-primary hover:bg-m-btn-primary-hover active:bg-m-btn-primary-active text-white cursor-pointer'
  }
})

const mergedButtonClass = computed(() =>
  twMerge(
    'inline-flex w-[240px] h-[40px] items-center justify-center gap-1 p-[10px] rounded-md text-base font-bold leading-[150%] transition-colors duration-150 focus:outline-none focus-visible:ring-2 focus-visible:ring-m-primary/50',
    variantClasses.value,
    props.buttonClass,
  ),
)

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

function onClick(e: MouseEvent) {
  if (!props.disabled) {
    emit('click', e)
  }
}
</script>
