<script setup lang="ts">
import { computed } from 'vue'
import { type RouterLinkProps, RouterLink } from 'vue-router'
import { type ColorProps, type DefaultProps, type VariantProps, propsToColor } from '~/composables/colors';

const { to, icon, thickWhenActive, round, ...colorProps } = defineProps<{
    width?: 'standard' | 'auto' | 'full'
    alignText?: 'left' | 'center' | 'right'
    alignSelf?: 'start' | 'center' | 'end'
    thickWhenActive?: true

    icon?: string;
    round?: true;
  } & RouterLinkProps & (ColorProps | DefaultProps) & VariantProps>()

const isExternalLink = computed(() => {
  return typeof to === 'string' && to.startsWith('http')
})

const [fontWeight, activeFontWeight] = thickWhenActive ? [600, 900] : [400, 400]

const isIconOnly = computed(() => !!icon)
const isSimple = propsToColor(colorProps).class === ''
</script>

<template>
  <a v-if="isExternalLink"
    v-bind="propsToColor({ ...colorProps, interactive: true })"
    :class="[
      $style.link,
      'is-' + width,
      'is-text-aligned-' + (alignText ?? 'center'),
      'is-self-aligned-' + (alignSelf ?? 'center'),
      round && $style['is-round'],
      isIconOnly && $style['is-icon-only'],
      isSimple && $style['force-underline'],
      isSimple && $style['no-spacing'],
    ]"
    :href="to.toString()"
    target="_blank"
  >
    <i v-if="icon" :class="['bi', icon]" />
    <span>
      <slot />
    </span>
  </a>
  <RouterLink v-else
    :to="to"
    v-bind="propsToColor({ ...colorProps, interactive: true })"
    :class="[
      $style.link,
      'is-' + width,
      'is-text-aligned-' + (alignText ?? 'center'),
      'is-self-aligned-' + (alignSelf ?? 'center'),
      round && $style['is-round'],
      isIconOnly && $style['is-icon-only'],
      isSimple && $style['no-spacing'],
      isSimple && $style['force-underline']
    ]"
  >
    <i v-if="icon" :class="['bi', icon]" />
    <span>
      <slot />
    </span>
  </RouterLink>
</template>

<style module lang="scss">
  .link {
    white-space: nowrap;

    font-family: $font-main;
    font-weight: v-bind(fontWeight);

    &:global(.router-link-exact-active) {
      font-weight: v-bind(activeFontWeight);
    }

    font-size: 0.875em;

    line-height: 1em;

    transform: translateX(var(--fw-translate-x)) translateY(var(--fw-translate-y)) scale(var(--fw-scale));
    transition:background-color .2s, border-color .3s;

    // Icon

    i:global(.bi) {
      font-size: 1.2rem;
      &.large {
        font-size:2rem;
      }
    }

    i:global(.bi) + span:not(:empty) {
      margin-left: 1ch;
    }

    &:not(.force-underline) {
      text-decoration: none;
      background-color: transparent;
      border-color: transparent;
    }

    /* Shape */

    border-radius: var(--fw-border-radius);
    margin: 0 0.5ch;

    padding: 0.642857142857em 0.714em 0.714em 0.714em;
    &.is-icon-only {
      padding: 0.675em 0.714em 0.678em 0.714em;
    }
    &.no-spacing{
      padding: 0;
      margin: 0;
      font-size: 1em;
    }

    &.is-round {
      border-radius: 100vh;
    }

    /* Alignment */

    display: inline-flex;
    align-items: center;
    justify-content: flex-start;

    &.is-text-aligned-center {
      justify-content: center
    }

    &.is-text-aligned-left {
      justify-content: flex-start
    }

    &.is-text-aligned-right {
      justify-content: flex-end;
    }

    &.is-self-aligned-start {
      align-self: flex-start;
    }

    &.is-self-aligned-center {
      align-self: center;
    }

    &.is-self-aligned-end {
      align-self: flex-end;
    }

    /* Width */

    &.is-full {
      align-self: stretch;
    }
  }
</style>
