<script setup lang="ts">
import { useColor } from '~/composables/colors'
import { FwLoader } from '~/components'
import { ref, computed, useSlots } from 'vue'
import type { ColorProps } from '~/types/common-props'

interface Props {
  variant?: 'solid' | 'outline' | 'ghost'
  width?: 'standard' | 'auto' | 'full'
  alignText?: 'left' | 'center' | 'right'

  isActive?: boolean
  isLoading?: boolean

  shadow?: boolean
  round?: boolean
  icon?: string

  onClick?: (...args: any[]) => void | Promise<void>
}

const props = defineProps<Props & ColorProps>()

const color = useColor(() => props.color)

const slots = useSlots()
const iconOnly = computed(() => !!props.icon && !slots.default)

const internalLoader = ref(false)
const isLoading = computed(() => props.isLoading || internalLoader.value)

const click = async (...args: any[]) => {
  internalLoader.value = true

  try {
    await props.onClick?.(...args)
  } finally {
    internalLoader.value = false
  }
}
</script>

<template>
  <button
    class="funkwhale is-colored button"
    :class="[
      color,
      'is-' + (variant ?? 'solid'),
      'is-' + (width ?? 'standard'),
      'is-aligned-' + (alignText ?? 'center'),
      {
        'is-active': isActive,
        'is-loading': isLoading,
        'icon-only': iconOnly,
        'has-icon': !!icon,
        'is-round': round,
        'is-shadow': shadow
      }
    ]"
    @click="click"
  >
    <i
      v-if="icon"
      :class="['bi', icon]"
    />

    <span>
      <slot />
    </span>

    <fw-loader
      v-if="isLoading"
      :container="false"
    />
  </button>
</template>

<style lang="scss">
@import './style.scss'
</style>
