import { computed } from 'vue'
import { useDark } from '@vueuse/core'
import { useUiStore } from '@/stores/uiStore'
import { getGroupColor, getGroupIcon, classifyNodeGroup } from '@/utils/nodeGroups'
import type { TimelineItem } from '@/types/timeline'
import type { TraceNode } from '@/types/trace'

/**
 * Composable for managing timeline data derivation
 */
export function useTimelineData() {
  const uiStore = useUiStore()
  const isDark = useDark()

  /**
   * Recursively flattens a pre-filtered hierarchical TraceNode into an array of TimelineItems.
   * Children are already filtered to only include visible nodes.
   */
  function flattenTrace(node: TraceNode, depth: number = 0): TimelineItem[] {
    const items: TimelineItem[] = []

    // attempt to parse dates
    const start = node.begin
      ? new Date(node.begin)
      : node.timestamp
        ? new Date(node.timestamp)
        : undefined

    // if no end time, assume instantaneous event
    const end = node.end ? new Date(node.end) : start

    // only add if we have at least a valid start time
    if (start && end && !isNaN(start.getTime()) && !isNaN(end.getTime())) {
      const group = classifyNodeGroup(node)
      const id = node.id || crypto.randomUUID() // Fallback ID if missing

      items.push({
        id,
        label: node.name,
        start,
        end,
        depth,
        group,
        icon: getGroupIcon(group),
        color: getGroupColor(group, isDark.value),
        hasChildren: node.children.length > 0,
      })

      // process pre-filtered children only if not collapsed
      if (!uiStore.collapsedNodeIds.has(id)) {
        for (const child of node.children) {
          items.push(...flattenTrace(child as TraceNode, depth + 1))
        }
      }
    }

    return items
  }

  /**
   * Reactive source of timeline items derived from the selected trace in the store.
   * Re-computes whenever the selected trace or hidden groups change.
   */
  const data = computed<TimelineItem[]>(() => {
    const filteredRoot = uiStore.filteredTree
    if (!filteredRoot) return []

    return flattenTrace(filteredRoot)
  })

  return {
    data,
  }
}
