<script lang="ts" setup>
import { isEqual } from 'ohash'
import { nuxtLinkProps, uiLinkProps } from '~/utils/link'

const props = defineProps({ ...nuxtLinkProps, ...uiLinkProps })

function resolveLinkClass(
  route: any,
  $route: any,
  { isActive, isExactActive }: { isActive: boolean, isExactActive: boolean },
) {
  if (props.exactQuery && !isEqual(route.query, $route.query))
    return props.inactiveClass

  if (props.exactHash && route.hash !== $route.hash)
    return props.inactiveClass

  if (props.exact && isExactActive)
    return props.activeClass

  if (!props.exact && isActive)
    return props.activeClass

  return props.inactiveClass
}
</script>

<template>
  <component
    :is="as"
    v-if="!to"
    :type="type"
    :disabled="disabled"
    v-bind="$attrs"
    :class="active ? activeClass : inactiveClass"
  >
    <slot v-bind="{ isActive: active }" />
  </component>
  <NuxtLink
    v-else
    v-slot="{
      route,
      href,
      target,
      rel,
      navigate,
      isActive,
      isExactActive,
      isExternal,
    }"
    v-bind="$props"
    custom
  >
    <a
      v-bind="$attrs"
      :href="!disabled ? href : undefined"
      :aria-disabled="disabled ? 'true' : undefined"
      :role="disabled ? 'link' : undefined"
      :rel="rel"
      :target="target"
      :class="
        active !== undefined
          ? active
            ? activeClass
            : inactiveClass
          : resolveLinkClass(route, $route, { isActive, isExactActive })
      "
      @click="(e:any) => !isExternal && !disabled && navigate(e)"
    >
      <slot
        v-bind="{
          isActive:
            active !== undefined ? active : exact ? isExactActive : isActive,
        }"
      />
    </a>
  </NuxtLink>
</template>
