// hooks/useNavBar.ts
import { computed, onMounted, ref } from 'vue'
import type { ComputedRef, Ref } from 'vue'

// 定义返回的类型
export interface NavBarInfo {
  // 状态栏高度（px）
  statusBarHeight: Ref<number>
  // 标题栏内容高度（px）- 与胶囊对齐的区域
  titleBarHeight: Ref<number>
  // 整个导航栏总高度（px）- 状态栏 + 标题栏
  totalNavHeight: ComputedRef<number>
  // 胶囊按钮信息
  menuButtonInfo: Ref<MenuButtonInfo | null>
  // 是否是小程序环境
  isMiniProgram: Ref<boolean>
  // 重新获取系统信息
  refresh: () => void
}

// 胶囊按钮信息类型
export interface MenuButtonInfo {
  width: number
  height: number
  top: number
  right: number
  bottom: number
  left: number
}

// 系统信息类型
interface SystemInfo {
  statusBarHeight: number
  platform: string
  system: string
  model: string
}

// 全局缓存
let cachedNavBarInfo: {
  statusBarHeight: number
  titleBarHeight: number
  menuButtonInfo: MenuButtonInfo | null
} | null = null

/**
 * 自定义导航栏 Hook
 * 用于处理 uniapp 自定义导航栏的高度适配和胶囊信息获取
 */
export function useNavBar(): NavBarInfo {
  // 状态栏高度
  const statusBarHeight = ref<number>(0)

  // 标题栏内容高度（与胶囊对齐的区域）
  const titleBarHeight = ref<number>(44)

  // 胶囊按钮信息
  const menuButtonInfo = ref<MenuButtonInfo | null>(null)

  // 是否是小程序环境
  const isMiniProgram = ref<boolean>(false)

  // 总高度（计算属性）
  const totalNavHeight = computed<number>(() => {
    return statusBarHeight.value + titleBarHeight.value
  })

  /**
   * 判断是否是小程序环境
   */
  const checkMiniProgramEnv = (): boolean => {
    // #ifdef MP-WEIXIN
    return true
    // #endif

    // #ifndef MP-WEIXIN
    return false
    // #endif
  }

  /**
   * 获取胶囊按钮信息（仅小程序有效）
   */
  const getMenuButtonInfo = (): MenuButtonInfo | null => {
    // #ifdef MP-WEIXIN
    try {
      const info = uni.getMenuButtonBoundingClientRect()
      if (info) {
        return {
          width: info.width,
          height: info.height,
          top: info.top,
          right: info.right,
          bottom: info.bottom,
          left: info.left,
        }
      }
    }
    catch (error) {
      console.warn('获取胶囊信息失败:', error)
    }
    // #endif

    return null
  }

  /**
   * 计算标题栏高度（与胶囊居中对齐）
   */
  const calculateTitleBarHeight = (statusHeight: number, menuBtn: MenuButtonInfo | null): number => {
    // 如果不是小程序环境或没有胶囊信息，返回默认值
    if (!isMiniProgram.value || !menuBtn) {
      return 44
    }

    // 核心公式：让自定义标题栏与胶囊垂直居中对齐
    // 标题栏高度 = 胶囊高度 + (胶囊顶部 - 状态栏高度) * 2
    const calculatedHeight = menuBtn.height + (menuBtn.top - statusHeight) * 2

    // 确保高度为正数且不低于最小高度
    return Math.max(calculatedHeight, 44)
  }

  /**
   * 获取系统信息
   */
  const getSystemInfo = (): SystemInfo => {
    const systemInfo = uni.getSystemInfoSync()
    return {
      statusBarHeight: systemInfo.statusBarHeight || 20,
      platform: systemInfo.platform,
      system: systemInfo.system,
      model: systemInfo.model,
    }
  }

  /**
   * 初始化导航栏信息
   */
  const initNavBarInfo = (): void => {
    // 检查环境
    isMiniProgram.value = checkMiniProgramEnv()

    // 获取系统信息
    const systemInfo = getSystemInfo()

    // 获取胶囊信息（仅小程序）
    const menuBtn = getMenuButtonInfo()

    // 计算高度
    const calculatedTitleBarHeight = calculateTitleBarHeight(systemInfo.statusBarHeight, menuBtn)

    // 更新响应式数据
    statusBarHeight.value = systemInfo.statusBarHeight
    titleBarHeight.value = calculatedTitleBarHeight
    menuButtonInfo.value = menuBtn

    // 缓存结果
    cachedNavBarInfo = {
      statusBarHeight: systemInfo.statusBarHeight,
      titleBarHeight: calculatedTitleBarHeight,
      menuButtonInfo: menuBtn,
    }
  }

  /**
   * 刷新导航栏信息（用于屏幕旋转等场景）
   */
  const refresh = (): void => {
    // 清除缓存
    cachedNavBarInfo = null
    // 重新初始化
    initNavBarInfo()
  }

  // 在组件挂载时初始化
  onMounted(() => {
    // 如果有缓存，直接使用缓存
    if (cachedNavBarInfo) {
      statusBarHeight.value = cachedNavBarInfo.statusBarHeight
      titleBarHeight.value = cachedNavBarInfo.titleBarHeight
      menuButtonInfo.value = cachedNavBarInfo.menuButtonInfo
      isMiniProgram.value = checkMiniProgramEnv()
    }
    else {
      initNavBarInfo()
    }
  })

  return {
    statusBarHeight,
    titleBarHeight,
    totalNavHeight,
    menuButtonInfo,
    isMiniProgram,
    refresh,
  }
}

/**
 * 获取状态栏高度的快捷方法（仅高度，不包含胶囊逻辑）
 */
export function useStatusBarHeight(): Ref<number> {
  const statusBarHeight = ref<number>(0)

  onMounted(() => {
    const systemInfo = uni.getSystemInfoSync()
    statusBarHeight.value = systemInfo.statusBarHeight || 20
  })

  return statusBarHeight
}

/**
 * 获取胶囊信息的快捷方法（仅小程序有效）
 */
export function useMenuButtonInfo(): Ref<MenuButtonInfo | null> {
  const menuButtonInfo = ref<MenuButtonInfo | null>(null)

  onMounted(() => {
    // #ifdef MP-WEIXIN
    try {
      const info = uni.getMenuButtonBoundingClientRect()
      if (info) {
        menuButtonInfo.value = {
          width: info.width,
          height: info.height,
          top: info.top,
          right: info.right,
          bottom: info.bottom,
          left: info.left,
        }
      }
    }
    catch (error) {
      console.warn('获取胶囊信息失败:', error)
    }
    // #endif
  })

  return menuButtonInfo
}
