<script setup lang="ts">
import { computed } from 'vue'

import CurvedConnector from './CurvedConnector.vue'
import NodeColorIndicator from './NodeColorIndicator.vue'
import ExplorerNodeContent from './ExplorerNodeContent.vue'
import VerticalConnector from './VerticalConnector.vue'
import { useNavigation } from '@/composables/useNavigation'
import { useNodeHighlight } from '@/composables/useNodeHighlight'
import type { ConnectorVariant } from '@/types/explorer'
import type { TraceNode } from '@/types/trace'
import type { TraceNodeHoverPayload } from '@/types/traceTooltip'
import { useUiStore } from '@/stores/uiStore'
import { getGroupColor, getGroupIcon, classifyNodeGroup } from '@/utils/nodeGroups'

const props = defineProps<{
  item: TraceNode
  isLastChild: boolean
  hereditaryOffset: ConnectorVariant[]
}>()

const emit = defineEmits<{
  (e: 'hover-node', payload: TraceNodeHoverPayload): void
  (e: 'leave-node'): void
}>()

const uiStore = useUiStore()
const { goToNode } = useNavigation()

// use central store for collapse state
const isCollapsed = computed(() => uiStore.collapsedNodeIds.has(props.item.id || ''))

// logic for highlighting the path to the selected node
const { isSelected, isHighlighted, childrenWithHighlight } = useNodeHighlight(
  computed(() => props.item),
  computed(() => uiStore.selectedNodeId),
)

function toggleCollapse() {
  if (props.item.id) {
    uiStore.toggleNodeCollapse(props.item.id)
  }
}
</script>

<template>
  <div
    class="flex px-2 hover:bg-primary/10 transition-colors duration-200 cursor-pointer group"
    :class="{ 'bg-primary/20': isSelected }"
    @click.stop="goToNode(item.id || '')"
    @mousemove="emit('hover-node', { item, clientX: $event.clientX, clientY: $event.clientY })"
    @mouseleave="emit('leave-node')"
  >
    <!-- Offset blocks (hereditary connectors from ancestors) -->
    <div
      v-for="(variant, index) in hereditaryOffset"
      :key="`offset-${index}`"
      class="flex-none relative w-[24px] flex justify-center"
    >
      <!-- Vertical line from ancestor -->
      <VerticalConnector :variant="variant" />

      <!-- Curved corner connector (only on last offset) -->
      <CurvedConnector v-if="index === hereditaryOffset.length - 1" :highlighted="isHighlighted" />
    </div>

    <!-- Node color indicator with optional vertical extension -->
    <NodeColorIndicator
      :color="getGroupColor(item)"
      :icon="getGroupIcon(classifyNodeGroup(item))"
      :has-children="item.children.length > 0"
      :is-collapsed="isCollapsed"
      :highlighted="isHighlighted && uiStore.selectedNodeId != item.id"
      class="transition-opacity duration-200"
    />

    <!-- Node content (name, duration, tokens, collapse button) -->
    <ExplorerNodeContent
      :node="item"
      :is-collapsed="isCollapsed"
      @toggle-collapse="toggleCollapse"
      class="transition-opacity duration-200"
    />
  </div>

  <!-- Recursive children rendering -->
  <div
    v-for="child in childrenWithHighlight"
    :key="child.item.id"
    :class="isCollapsed ? 'hidden' : 'block'"
  >
    <ExplorerItem
      :item="child.item"
      :is-last-child="child.isLast"
      :hereditary-offset="
        hereditaryOffset.concat([
          child.highlighted ? 'highlighted' : child.isLast ? 'empty' : 'filled',
        ])
      "
      @hover-node="emit('hover-node', $event)"
      @leave-node="emit('leave-node')"
    />
  </div>
</template>
