import type { NodesFilters } from '@/common/interface/filters'
import type { Trace, TraceNode } from '@/common/interface/trace'
import { classifyNodeGroup } from '@/utils/nodeGroups'

export function matchNode(node: TraceNode, filters: NodesFilters): boolean {
  const { name, group } = filters

  let nameOk = true
  if (name) {
    const nodeName = ((node as Trace).name || '').toLowerCase()
    if (!nodeName.includes(name.toLowerCase())) {
      nameOk = false
    }
  }

  let groupOk = true
  if (group) {
    const nodeGrp = classifyNodeGroup(node)

    if (!group.includes(nodeGrp)) {
      groupOk = false
    }
  }

  if (!nameOk || !groupOk) {
    if (node.children && node.children.length > 0) {
      return node.children.some((child) => matchNode(child, filters))
    }
    return false
  }

  return true
}

export function filterTraceNode(node: TraceNode, filters: NodesFilters): TraceNode | undefined {
  if (!matchNode(node, filters)) return undefined

  const filteredChildren = node.children
    .map((child) => filterTraceNode(child, filters))
    .filter((c): c is TraceNode => c !== undefined) as TraceNode[]

  return {
    ...node,
    children: filteredChildren
  }
}

export function getDateRange(traces: Trace[]): [Date, Date] {
  const min = traces.reduce((acc, trace) => {
    if (trace.begin && (trace.begin <= acc || acc == '')) {
      return trace.begin
    }

    return acc
  }, '')
  const minDate = new Date(min)
  minDate.setHours(0, 0, 0, 0)

  const max = traces.reduce((acc, trace) => {
    if (trace.begin && (trace.begin >= acc || acc == '')) {
      return trace.begin
    }

    return acc
  }, '')
  const maxDate = new Date(max)
  maxDate.setHours(23, 59, 59, 999)

  return [minDate, maxDate]
}

export function getDurationRange(traces: Trace[]): [number, number] {
  const durations = traces.map((trace: Trace) => trace.duration || 0)
  const minDuration = Math.min(...durations)
  const maxDuration = Math.max(...durations)

  return [minDuration, maxDuration]
}
