<script setup lang="ts">
import VPIconFa from '@theme/VPIconFa.vue'
import VPIconfont from '@theme/VPIconfont.vue'
import VPIconify from '@theme/VPIconify.vue'
import VPIconImage from '@theme/VPIconImage.vue'
import { computed } from 'vue'
import { isLinkHttp } from 'vuepress/shared'

const { provider, name, size, color, extra } = defineProps<{
  provider?: 'iconify' | 'iconfont' | 'fontawesome'
  name: string | { svg: string }
  size?: string | number
  color?: string
  extra?: string
}>()

declare const __MD_POWER_ICON_PROVIDER__: 'iconify' | 'iconfont' | 'fontawesome'
declare const __MD_POWER_ICON_PREFIX__: string

const type = computed(() => {
  // name -> https://example.com/icon.svg
  // name -> /icon.svg
  if (typeof name === 'string' && (isLinkHttp(name) || name[0] === '/')) {
    return 'link'
  }

  // name -> { svg: '<svg></svg>' }
  if (typeof name === 'object' && !!name.svg) {
    return 'svg'
  }

  const _provider = provider || __MD_POWER_ICON_PROVIDER__
  if (_provider === 'iconfont' || _provider === 'fontawesome') {
    return _provider
  }

  return 'iconify'
})

function parseSize(size: string | number): string {
  if (String(Number(size)) === String(size))
    return `${size}px`
  return String(size)
}

const rect = computed(() => {
  if (!size)
    return undefined

  const [width, height] = String(size)
    .replaceAll('px', '[UNIT]')
    .split('x')
    .map(s => parseSize(s.replaceAll('[UNIT]', 'px').trim()))

  return { width, height: height || width }
})
const binding = computed(() => ({
  name: name as string,
  color,
  size: rect.value,
  prefix: __MD_POWER_ICON_PREFIX__ as any,
}))
</script>

<template>
  <VPIconImage
    v-if="type === 'link' || type === 'svg'"
    :type="type" :name="name" :color="color" :size="rect"
  />
  <VPIconfont
    v-else-if="type === 'iconfont'"
    v-bind="binding"
  />
  <VPIconFa
    v-else-if="type === 'fontawesome'"
    :extra="extra"
    v-bind="{ ...binding, ...$attrs }"
  />
  <VPIconify
    v-else-if="type === 'iconify'"
    :extra="extra"
    v-bind="binding"
  />
</template>
