/**
 * 获取元素的位置和尺寸信息（兼容uniapp各平台）
 * 返回类似 DOMRect 的对象
 */
export interface ElementRect {
  left: number
  top: number
  right: number
  bottom: number
  width: number
  height: number
  x: number
  y: number
}

/**
 * 获取元素的位置和尺寸（兼容uniapp app模式）
 * @param element HTML元素引用
 * @param selector 选择器（用于uniapp模式）
 * @param context Vue组件实例（用于uniapp模式）
 * @returns Promise<ElementRect>
 */
export async function getElementRect(
  element?: HTMLElement | null,
  selector?: string,
  context?: any,
): Promise<ElementRect> {
  // 优先使用 getBoundingClientRect（H5环境）
  if (element && typeof element.getBoundingClientRect === 'function') {
    const rect = element.getBoundingClientRect()
    return {
      left: rect.left,
      top: rect.top,
      right: rect.right,
      bottom: rect.bottom,
      width: rect.width,
      height: rect.height,
      x: rect.x,
      y: rect.y,
    }
  }

  // 如果element存在但没有getBoundingClientRect，尝试使用offset属性
  if (element) {
    // 获取元素位置（需要遍历父元素累加offset）
    let left = 0
    let top = 0
    let current: HTMLElement | null = element

    while (current) {
      left += current.offsetLeft || 0
      top += current.offsetTop || 0
      current = current.offsetParent as HTMLElement | null
    }

    const width = element.offsetWidth || 0
    const height = element.offsetHeight || 0

    return {
      left,
      top,
      right: left + width,
      bottom: top + height,
      width,
      height,
      x: left,
      y: top,
    }
  }

  // uniapp模式：使用 uni.createSelectorQuery
  if (selector && context) {
    return new Promise((resolve, reject) => {
      const query = uni.createSelectorQuery().in(context)
      query.select(selector).boundingClientRect((rect: any) => {
        if (rect) {
          resolve({
            left: rect.left,
            top: rect.top,
            right: rect.right,
            bottom: rect.bottom,
            width: rect.width,
            height: rect.height,
            x: rect.left,
            y: rect.top,
          })
        }
        else {
          reject(new Error('Failed to get element rect'))
        }
      }).exec()
    })
  }

  // 如果都不满足，返回默认值
  return Promise.reject(new Error('Unable to get element rect: element, selector, or context is required'))
}

/**
 * 同步获取元素位置（仅H5环境，使用offset属性）
 * 在uniapp app模式下不可靠，建议使用异步的 getElementRect
 */
export function getElementRectSync(element: HTMLElement | null): ElementRect | null {
  if (!element) {
    return null
  }

  // 优先使用 getBoundingClientRect
  if (typeof element.getBoundingClientRect === 'function') {
    const rect = element.getBoundingClientRect()
    return {
      left: rect.left,
      top: rect.top,
      right: rect.right,
      bottom: rect.bottom,
      width: rect.width,
      height: rect.height,
      x: rect.x,
      y: rect.y,
    }
  }

  // 备选方案：使用offset属性
  let left = 0
  let top = 0
  let current: HTMLElement | null = element

  while (current) {
    left += current.offsetLeft || 0
    top += current.offsetTop || 0
    current = current.offsetParent as HTMLElement | null
  }

  const width = element.offsetWidth || 0
  const height = element.offsetHeight || 0

  return {
    left,
    top,
    right: left + width,
    bottom: top + height,
    width,
    height,
    x: left,
    y: top,
  }
}
