/** Build nested partial object from path like root.Network.Timeout (aligned with OTA Electron resolvePath). */
export function resolvePathPartial(data: any, path: string): Record<string, unknown> {
  const raw = path.replace(/^root\.?/, '')
  if (!raw) {
    if (data != null && typeof data === 'object' && !Array.isArray(data)) {
      return { ...(data as Record<string, unknown>) }
    }
    return {}
  }
  const keys = raw.split(/\.|\[|\]/).filter(Boolean)
  if (!keys.length) return {}
  let result = data
  const currentObject: Record<string, unknown> = {}
  keys.reduce((acc: any, key: string, index: number, array: string[]) => {
    if (index === array.length - 1) {
      acc[key] = result?.[key]
    } else {
      acc[key] = {}
    }
    result = result?.[key]
    return acc[key]
  }, currentObject)
  return currentObject
}

export interface JsonTreeNode {
  label: string
  path: string
  valuePreview: string
  selectable: boolean
  children?: JsonTreeNode[]
}

export function jsonToTree(data: unknown, path = 'root', depth = 0): JsonTreeNode[] {
  if (data == null || typeof data !== 'object') return []
  if (Array.isArray(data)) {
    return data.map((item, i) => {
      const p = `${path}[${i}]`
      const isObj = item != null && typeof item === 'object'
      return {
        label: `[${i}]`,
        path: p,
        valuePreview: preview(item),
        selectable: false,
        children: isObj && depth < 8 ? jsonToTree(item, p, depth + 1) : undefined
      }
    })
  }
  return Object.keys(data as object).map((key) => {
    const val = (data as any)[key]
    const p = path === 'root' ? `root.${key}` : `${path}.${key}`
    const isObj = val != null && typeof val === 'object'
    return {
      label: key,
      path: p,
      valuePreview: preview(val),
      selectable: true,
      children: isObj && depth < 8 ? jsonToTree(val, p, depth + 1) : undefined
    }
  })
}

function preview(v: unknown): string {
  if (v == null) return 'null'
  if (typeof v === 'string') return v.length > 40 ? `"${v.slice(0, 40)}…"` : `"${v}"`
  if (typeof v === 'number' || typeof v === 'boolean') return String(v)
  if (Array.isArray(v)) return `Array(${v.length})`
  return `Object(${Object.keys(v as object).length})`
}

export function getValueAtPath(data: any, path: string): unknown {
  const keys = path
    .replace(/^root\.?/, '')
    .split(/\.|\[|\]/)
    .filter(Boolean)
  let cur = data
  for (const k of keys) {
    if (cur == null) return undefined
    cur = cur[k]
  }
  return cur
}
