<script setup lang="ts">
/**
 * Props-driven link composition. Renders a text link using the Button
 * primitive with variant="link". Supports the same href / emit / confirm
 * behaviour as ButtonAction.
 *
 *   <LinkAction label="Open docs" href="https://example.com" target="_blank" />
 *   <LinkAction label="Refresh" emit="refresh" @action="onAction" />
 */
import { computed } from "vue"
import * as LucideIcons from "@lucide/vue"
import type { FunctionalComponent } from "vue"

type LucideIcon = FunctionalComponent

import { Button } from "@/components/ui/button"

export interface LinkActionProps {
  label?: string
  /** Lucide icon name rendered before the label. */
  icon?: string
  /** Navigation target. */
  href?: string
  target?: "_self" | "_blank" | "_parent" | "_top"
  /** Custom event name emitted via `action` when clicked. */
  emit?: string
  disabled?: boolean
  /** HTML id attribute. */
  id?: string
  /** HTML name (used as `data-element-name`). */
  name?: string
}

const props = withDefaults(defineProps<LinkActionProps>(), {
  target: "_self",
})

const emit = defineEmits<{
  (e: "click", event: MouseEvent): void
  (e: "action", payload: { name: string }): void
}>()

const iconLibrary = LucideIcons as unknown as Record<string, LucideIcon>
function resolveIcon(name: string | undefined): LucideIcon | undefined {
  if (!name) {
    return undefined
  }
  const pascal = name
    .split(/[-_\s]/)
    .filter(Boolean)
    .map((s) => s.charAt(0).toUpperCase() + s.slice(1))
    .join("")
  return iconLibrary[pascal] ?? iconLibrary[name]
}
const icon = computed(() => resolveIcon(props.icon))

const renderAs = computed<"a" | "button">(() =>
  props.href ? "a" : "button",
)

function onClick(event: MouseEvent): void {
  emit("click", event)
  if (props.href) {
    return
  }
  event.preventDefault()
  if (props.emit) {
    emit("action", { name: props.emit })
  }
}
</script>

<template>
  <Button
    :id="id"
    :as="renderAs"
    variant="link"
    size="sm"
    :disabled="disabled"
    :href="renderAs === 'a' ? href : undefined"
    :target="renderAs === 'a' ? target : undefined"
    :data-action-name="emit ?? label"
    :data-element-name="name ?? undefined"
    @click="onClick"
  >
    <component :is="icon" v-if="icon" class="h-4 w-4" />
    <span v-if="label">{{ label }}</span>
  </Button>
</template>
