<template>
  <div
    class="group relative box-content flex cursor-pointer flex-col items-center justify-center rounded-lg bg-component-node-background px-2 py-3 transition-colors duration-150 select-none hover:bg-secondary-background-hover"
    :data-node-name="node.label"
    draggable="true"
    @click="handleClick"
    @dragstart="handleDragStart"
    @dragend="handleDragEnd"
    @mouseenter="handleMouseEnter"
    @mouseleave="handleMouseLeave"
  >
    <i :class="cn(nodeIcon, 'size-6 text-muted-foreground')" />

    <TextTickerMultiLine
      class="text-foreground mt-2 h-7 w-full shrink-0 text-xs/normal font-normal"
    >
      {{ node.label }}
    </TextTickerMultiLine>
  </div>

  <Teleport v-if="showPreview" to="body">
    <div
      :ref="(el) => (previewRef = el as HTMLElement)"
      :style="nodePreviewStyle"
    >
      <NodePreviewCard
        :node-def="node.data!"
        :show-inputs-and-outputs="false"
      />
    </div>
  </Teleport>
</template>

<script setup lang="ts">
import { kebabCase } from 'es-toolkit/string'
import type { Ref } from 'vue'
import { computed, inject } from 'vue'

import TextTickerMultiLine from '@/components/common/TextTickerMultiLine.vue'
import NodePreviewCard from '@/components/node/NodePreviewCard.vue'
import { useNodePreviewAndDrag } from '@/composables/node/useNodePreviewAndDrag'
import { resolveBlueprintIcon } from '@/constants/essentialsDisplayNames'
import { ESSENTIALS_ICON_OVERRIDES } from '@/constants/essentialsNodes'
import type { ComfyNodeDefImpl } from '@/stores/nodeDefStore'
import type { RenderedTreeExplorerNode } from '@/types/treeExplorerTypes'
import { cn } from '@comfyorg/tailwind-utils'

const { node } = defineProps<{
  node: RenderedTreeExplorerNode<ComfyNodeDefImpl>
}>()

const panelRef = inject<Ref<HTMLElement | null>>(
  'essentialsPanelRef',
  undefined!
)

const emit = defineEmits<{
  click: [node: RenderedTreeExplorerNode<ComfyNodeDefImpl>]
}>()

const nodeDef = computed(() => node.data)

const {
  previewRef,
  showPreview,
  nodePreviewStyle,
  handleMouseEnter,
  handleMouseLeave,
  handleDragStart,
  handleDragEnd
} = useNodePreviewAndDrag(nodeDef, panelRef)

const nodeIcon = computed(() => {
  const nodeName = node.data?.name
  if (nodeName && nodeName in ESSENTIALS_ICON_OVERRIDES)
    return ESSENTIALS_ICON_OVERRIDES[nodeName]
  if (nodeName) {
    const blueprintIcon = resolveBlueprintIcon(nodeName)
    if (blueprintIcon) return blueprintIcon
  }
  const iconName = nodeName ? kebabCase(nodeName) : 'node'
  return `icon-[comfy--${iconName}]`
})

function handleClick() {
  if (!node.data) return
  emit('click', node)
}
</script>
