import { computed, type ComputedRef } from 'vue'

import { useUiStore } from '@/stores/uiStore'
import type { TraceNode } from '@/types/trace'
import type { ChildItemWithHighlight } from '@/types/explorer'

/**
 * Composable for managing node highlight state in the explorer tree
 *
 * @param node - The current trace node
 * @param selectedNodeId - The ID of the currently selected node
 * @returns Computed properties for highlight state and children with highlight info
 */
export function useNodeHighlight(
  node: ComputedRef<TraceNode> | TraceNode,
  selectedNodeId: ComputedRef<string | undefined | null> | string | undefined | null,
) {
  const uiStore = useUiStore()
  const nodeValue = computed(() =>
    typeof node === 'object' && 'value' in node ? node.value : node,
  )
  const selectedId = computed(
    () =>
      (typeof selectedNodeId === 'object' && selectedNodeId !== null && 'value' in selectedNodeId
        ? selectedNodeId.value
        : selectedNodeId) || '',
  )

  /**
   * Recursively checks if a node or any of its descendants contains the target ID
   */
  const hasTarget = (n: TraceNode, targetId: string): boolean => {
    if (n.id === targetId) return true
    if (n.children && Array.isArray(n.children)) {
      return n.children.some((child) => hasTarget(child, targetId))
    }
    return false
  }

  /**
   * Finds the index of the next child step that leads to the target node
   * Returns null if the target is not in any child branch
   */
  const findNextStepToTarget = (currentNode: TraceNode, targetId: string): number | null => {
    const child = currentNode.children.find((c) => hasTarget(c, targetId))
    return child && child.id ? currentNode.children.indexOf(child) : null
  }

  /**
   * The index of the child that contains the selected node (or null if none)
   */
  const nextStepToTarget = computed(() => findNextStepToTarget(nodeValue.value, selectedId.value))

  /**
   * Whether this node is currently selected
   */
  const isSelected = computed(() => selectedId.value === nodeValue.value.id)

  /**
   * Whether this node or its connectors should be highlighted
   * (true if this node is selected OR if a descendant is selected)
   */
  const isHighlighted = computed(() => isSelected.value || nextStepToTarget.value !== null)

  /**
   * Children filtered by visible groups and mapped with their highlight state and position info.
   * Uses centralized filtering from uiStore which includes pass-through logic.
   */
  const childrenWithHighlight = computed((): ChildItemWithHighlight[] => {
    // filter using centralized shouldShowNode which handles pass-through nodes
    const visibleChildren = nodeValue.value.children.filter((child) =>
      uiStore.shouldShowNode(child as TraceNode),
    )

    return visibleChildren.map((child, index) => ({
      item: child,
      isLast: index === visibleChildren.length - 1,
      highlighted: index < (nextStepToTarget.value || 0),
    }))
  })

  return {
    nextStepToTarget,
    isSelected,
    isHighlighted,
    childrenWithHighlight,
  }
}
