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

defineOptions({
  inheritAttrs: false,
})

const props = withDefaults(defineProps<FdsButtonMinorProps>(), {
  loading: false,
  block: false,
  state: undefined,
  icon: undefined,
  iconPos: 'left',
  iconSize: 24,
  textSelection: false,
  as: 'button',
  type: 'button',
  invert: false,
  dataTestid: undefined,
})

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

const { disabled, href, target, rel, attrs } = useAttrsWithDefaults(props)

const rootClasses = computed(() => [
  props.block ? 'flex w-full' : 'inline-flex shrink-0 self-start',
  'transition-opacity duration-200',
])

const externalClass = computed(() => attrs.class)

const elBase =
  'box-border appearance-none inline-flex items-center justify-center w-fit min-h-0 shadow-none p-0.5 text-base select-none m-0 rounded-md text-left align-middle no-underline transition-[box-shadow,border-color,background-color] duration-200 font-main font-bold text-base leading-5 tracking-normal focus-visible:outline-dashed focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-blue-500'

const variantClasses = computed(() =>
  props.invert
    ? 'border-0 font-normal text-white bg-transparent focus-visible:outline-dashed focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white hover:bg-blue-800 active:bg-blue-900'
    : 'border-0 font-normal text-blue-600 bg-transparent focus-visible:outline-dashed focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-blue-500 hover:bg-blue_t-100 active:bg-blue_t-200',
)

const blockElClasses = computed(() => props.block && 'w-full justify-center')

const iconOrderClasses = computed(() =>
  props.icon && props.iconPos === 'right' ? 'order-2 ml-2 mr-0' : props.icon && 'mr-2',
)

const buttonClasses = computed(() => [
  elBase,
  variantClasses.value,
  blockElClasses.value,
  props.textSelection && 'select-text',
  disabled.value ? 'opacity-20 cursor-not-allowed' : 'cursor-pointer',
])

const iconFillClass = computed(() => (props.invert ? 'fill-white' : 'fill-blue-500'))

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

const componentTag = computed(() => {
  if (disabled.value || props.loading) return 'button'
  return props.as
})

const linkAttrs = computed(() => {
  if (componentTag.value === 'a') return { href: href.value, target: target.value, rel: rel.value }
  if (componentTag.value === 'router-link') return { to: href.value }
  return {}
})

const componentAttrs = computed(() => {
  const { class: _class, ...restAttrs } = attrs
  return {
    ...linkAttrs.value,
    ...restAttrs,
  }
})
</script>

<template>
  <div :class="[rootClasses, externalClass]" :aria-disabled="disabled ? 'true' : undefined">
    <component
      :is="componentTag"
      v-bind="componentAttrs"
      :type="componentTag === 'button' ? props.type : undefined"
      :disabled="componentTag === 'button' ? disabled : undefined"
      :data-testid="dataTestid"
      :class="buttonClasses"
      @click="onClick"
    >
      <template v-if="loading">
        <FdsSpinner class="mr-2" size="24px" color="inherit" />
      </template>
      <template v-else-if="icon">
        <span :class="iconOrderClasses" aria-hidden="true">
          <FdsIcon :class="iconFillClass" :name="icon" :size="iconSize" />
        </span>
      </template>
      <span>
        {{ text }}
      </span>
    </component>
  </div>
</template>
