<script setup lang="ts">
import type { PropType } from 'vue'
import UiIcon from './Icon.vue'
import { nuxtLinkProps, uiLinkProps } from '#shadcn-pro/utils/link'
import type { ButtonVariants } from '#shadcn-pro/components/ui/button'

const props = defineProps({
  ...nuxtLinkProps,
  ...uiLinkProps,
  variant: {
    type: String as PropType<ButtonVariants['variant']>,
  },
  size: {
    type: String as PropType<ButtonVariants['size']>,
  },
  label: {
    type: String,
  },
  type: {
    type: String,
    default: 'button',
  },
  block: {
    type: Boolean,
    default: false,
  },
  loading: {
    type: Boolean,
    default: false,
  },
  disabled: {
    type: Boolean,
    default: false,
  },
  icon: {
    type: String,
    default: null,
  },
  loadingIcon: {
    type: String,
    default: () => 'i-ph:spinner animate-spin',
  },
  leadingIcon: {
    type: String,
    default: null,
  },
  trailingIcon: {
    type: String,
    default: null,
  },
  trailing: {
    type: Boolean,
    default: false,
  },
  leading: {
    type: Boolean,
    default: false,
  },
})

const isLeading = computed(() => {
  return (
    (props.icon && props.leading)
    || (props.icon && !props.trailing)
    || (props.loading && !props.trailing)
    || props.leadingIcon
  )
})

const isTrailing = computed(() => {
  return (
    (props.icon && props.trailing)
    || (props.loading && props.trailing)
    || props.trailingIcon
  )
})
const linkProps = computed(() => getUiLinkProps(props))

const leadingIconName = computed(() => {
  if (props.loading) {
    return props.loadingIcon
  }

  return props.leadingIcon || props.icon
})

const trailingIconName = computed(() => {
  if (props.loading && !isLeading.value) {
    return props.loadingIcon
  }

  return props.trailingIcon || props.icon
})
</script>

<template>
  <Button
    as-child
    v-bind="{ variant, size }"
    :class="!disabled && 'cursor-pointer'"
  >
    <UiLink
      :as="type"
      :disabled="disabled || loading"
      v-bind="{ ...linkProps }"
    >
      <template #default="{ isActive }">
        <slot v-bind="{ isActive }" name="leading" :disabled="disabled" :loading="loading">
          <UiIcon
            v-if="isLeading && leadingIconName"
            :name="leadingIconName"
            :class="[leadingIconName, label || $slots.default ? 'mr-2' : '']"
            aria-hidden="true"
          />
        </slot>

        <slot v-bind="{ isActive }">
          <span v-if="label">
            {{ label }}
          </span>
        </slot>

        <slot v-bind="{ isActive }" name="trailing" :disabled="disabled" :loading="loading">
          <UiIcon
            v-if="isTrailing && trailingIconName"
            :class="[label || $slots.default ? 'ml-2' : '']"
            :name="trailingIconName"
            aria-hidden="true"
          />
        </slot>
      </template>
    </UiLink>
  </Button>
</template>
