<script setup lang="ts">
import type { ButtonType, ButtonVariant } from '#layers/types/components/button'

interface props {
  type?: ButtonType
  size?: string
  variant?: ButtonVariant
  target?: '_self' | '_blank'
  href?: string
  backgroundColor?: string
  textColor?: string
  disabled?: boolean
  gradient?: boolean
  useGameFont?: boolean
}

const props = withDefaults(defineProps<props>(), {
  type: 'action',
  size: 'size-extra-small md:size-medium',
  variant: 'filled',
  target: '_self',
  textColor: 'var(--alternative-02)',
  disabled: false,
  gradient: false,
  useGameFont: false,
})

const gameDataStore = useGameDataStore()
const { fontFamily } = storeToRefs(gameDataStore)

const componentTag = computed((): string => {
  switch (props.type) {
    case 'external':
    case 'link':
      return 'a'
    case 'download':
      return props.href ? 'a' : 'button'
    case 'internal':
      return props.href ? 'AtomsLocaleLink' : 'button'
    default:
      return 'button'
  }
})
const componentProps = computed(() => {
  if (props.type === 'external' || props.type === 'link') {
    return {
      href: props.href,
      target: props.target,
    }
  }

  if (props.type === 'internal') {
    if (props.href) {
      return {
        to: props.href,
      }
    }
    return {}
  }

  if (props.type === 'download') {
    if (props.href) {
      return {
        href: props.href,
        target: '_self',
        download: props.href?.split('/').pop() ?? 'download',
      }
    }
    return {}
  }

  return {}
})
const textColor = computed(() => {
  return props.textColor ? props.textColor : 'var(--text-secondary)'
})
const buttonStyle = computed(() => {
  const backgroundColor =
    props.variant === 'filled' ? 'var(--primary)' : 'white'
  const style: Record<string, string> = {
    backgroundColor: props.backgroundColor ?? backgroundColor,
    '--disabled-color': textColor.value,
  }

  return style
})
const textStyle = computed(() => {
  const style: Record<string, string> = {
    color: textColor.value,
  }

  if (props.useGameFont && fontFamily.value) {
    style.fontFamily = fontFamily.value
  }

  return style
})
</script>

<template>
  <component
    :is="componentTag"
    v-bind="{ ...componentProps }"
    :class="['btn-base', props.size, { disabled: props.disabled }]"
    :data-variant="props.variant"
    :style="buttonStyle"
    :disabled="props.disabled"
  >
    <i v-if="props.gradient" class="btn-gradient"></i>
    <span class="btn-content" :style="textStyle">
      <slot />
      <AtomsIconsLongArrowRightLine
        v-if="props.type === 'internal'"
        :color="props.textColor"
        class="icon icon-internal"
      />
      <AtomsIconsWebLinkLine
        v-if="props.type === 'external'"
        :color="props.textColor"
        class="icon icon-external"
      />
      <AtomsIconsDownloadLine
        v-if="props.type === 'download'"
        :color="props.textColor"
        class="icon icon-download"
      />
    </span>
  </component>
</template>

<style scoped>
.btn-base {
  @apply overflow-hidden relative inline-flex items-center justify-center font-medium cursor-pointer
    before:content-[''] before:absolute before:top-0 before:left-0 before:w-full before:h-full before:border before:border-white/10;
}
.btn-base[data-variant='filled'] {
  @apply after:content-[''] after:absolute after:top-0 after:left-0 after:w-full after:h-full after:bg-white after:transition-opacity after:duration-300 after:ease-in-out after:opacity-0
  hover:after:opacity-20;
}
.btn-base[data-variant='outlined'] {
  @apply before:border-[rgba(0,0,0,0.1)]
  hover:before:border-[#999];
}
.btn-base.disabled {
  @apply cursor-default pointer-events-none
  after:opacity-20 after:z-[2];
}
.btn-base.disabled::after {
  background-color: var(--disabled-color) !important;
}

.icon {
  @apply transition-transform duration-300 ease-spring;
}
.btn-base:hover .icon-internal {
  @apply translate-x-[3px];
}
.btn-base:hover .icon-external {
  @apply scale-[1.08];
}
.btn-base:hover .icon-download {
  @apply translate-y-[3px];
}

.btn-base.disabled .btn-content {
  @apply opacity-50;
}
.btn-base .btn-content {
  @apply relative flex items-center gap-1 z-[1];
}
.btn-base.size-extra-small .btn-content {
  @apply gap-0.5;
}

.btn-gradient {
  @apply absolute top-0 left-0 w-full h-full opacity-[0.7] mix-blend-soft-light;
  background: radial-gradient(
    68.19% 81.25% at 50.35% 100%,
    #fff 20%,
    rgba(255, 255, 255, 0) 100%
  );
}
</style>
