<script setup>
import { computed } from 'vue'
import { Link } from '@inertiajs/vue3'
import { ArrowPathIcon } from '@heroicons/vue/20/solid'

const props = defineProps({
  variant: {
    type: String,
    default: 'primary',
    validator: (value) => ['primary', 'danger', 'ghost'].includes(value),
  },
  size: {
    type: String,
    default: 'md',
    validator: (value) => ['sm', 'md', 'lg'].includes(value),
  },
  href: {
    type: String,
    default: undefined,
  },
  external: {
    type: Boolean,
    default: false,
  },
  disabled: {
    type: Boolean,
    default: false,
  },
  loading: {
    type: Boolean,
    default: false,
  },
})

const emit = defineEmits(['click'])

const isDisabled = computed(() => props.disabled || props.loading)

const component = computed(() => {
  if (props.href && props.external) return 'a'
  if (props.href) return Link
  return 'button'
})

const buttonClasses = computed(() => {
  const classes = [
    'inline-flex items-center justify-center gap-2',
    'font-semibold rounded-lg',
    'transition-all duration-200',
    'focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-surface',
  ]

  // Size classes
  if (props.size === 'sm') {
    classes.push('px-4 py-2 text-sm')
  } else if (props.size === 'md') {
    classes.push('px-6 py-3 text-base')
  } else if (props.size === 'lg') {
    classes.push('px-8 py-3.5 text-lg')
  }

  // Variant classes
  if (isDisabled.value) {
    classes.push('opacity-50 cursor-not-allowed')
    if (props.variant === 'primary') {
      classes.push('bg-primary text-gray-900')
    } else if (props.variant === 'danger') {
      classes.push('bg-red-500 text-white')
    } else if (props.variant === 'ghost') {
      classes.push('bg-transparent text-gray-400')
    }
  } else {
    classes.push('cursor-pointer')
    if (props.variant === 'primary') {
      classes.push(
        'bg-primary text-gray-900',
        'hover:bg-secondary hover:text-white',
        'focus:ring-primary'
      )
    } else if (props.variant === 'danger') {
      classes.push(
        'bg-red-500 text-white',
        'hover:bg-red-600',
        'focus:ring-red-500'
      )
    } else if (props.variant === 'ghost') {
      classes.push(
        'bg-transparent text-gray-400',
        'hover:text-white hover:bg-white/10',
        'focus:ring-gray-400'
      )
    }
  }

  return classes.join(' ')
})

const handleClick = (event) => {
  if (!isDisabled.value) {
    emit('click', event)
  }
}
</script>

<template>
  <component
    :is="component"
    :href="href"
    :class="buttonClasses"
    :disabled="isDisabled"
    :type="href ? undefined : 'button'"
    v-bind="$attrs"
    @click="handleClick"
  >
    <ArrowPathIcon v-if="loading" class="h-5 w-5 animate-spin" />
    <slot />
  </component>
</template>
