import { EventSafety } from '@/common/js/event-safety.js'
import util from '@/common/js/util.js'

export class NavigationHelper {
  constructor() {
    this.navigationCache = new Map()
  }

  // 安全地获取导航栏高度
  async getNavigationHeight(component, options = {}) {
    const cacheKey = `nav_height`

    // 检查缓存
    if (this.navigationCache.has(cacheKey) && !options.forceRefresh) {
      return this.navigationCache.get(cacheKey)
    }

    // 获取高度
    try {
      // 尝试直接获取 uni-page-head
      const height = await this.getDirectNavigationHeight(component)
      if (height > 0) {
        this.navigationCache.set(cacheKey, height)
        return height
      }
      
      // 备用方案：平台特定方法
      const platformHeight = await this.getPlatformNavigationHeight()
      this.navigationCache.set(cacheKey, platformHeight)
      return platformHeight
    } catch (error) {
      console.warn('获取导航栏高度失败，使用默认值:', error)
      const defaultHeight = this.getDefaultNavHeight()
      this.navigationCache.set(cacheKey, defaultHeight)
      return defaultHeight
    }
  }
  
  // 直接查询导航栏高度
  getDirectNavigationHeight(component) {
    return new Promise((resolve) => {
      const query = uni.createSelectorQuery().in(component)
      
      query.select('.uni-page-head').boundingClientRect((rect) => {
        if (rect && rect.height > 0) {
          console.log('直接查询导航栏高度成功:', rect.height)
          resolve(rect.height)
        } else {
          console.warn('未找到 uni-page-head 元素或高度为0')
          resolve(0)
        }
      }).exec()
    })
  }
  
  // 平台特定的高度获取
  getPlatformNavigationHeight() {
    return new Promise((resolve) => {
      // #ifdef MP-WEIXIN
      // 微信小程序精确计算
      try {
        const menuButtonInfo = wx.getMenuButtonBoundingClientRect()
        let systemInfo = util.getDeviceInfo();
        
        const height = menuButtonInfo.bottom + 
                      (menuButtonInfo.top - systemInfo.statusBarHeight)
        console.log('微信小程序导航栏高度:', height)                    
        resolve(height)
      } catch (error) {
        console.error('微信小程序高度计算失败:', error)
        resolve(44)
      }

      // #endif
      
      // #ifdef H5
      // H5环境：尝试获取自定义导航栏或使用默认值
      if (typeof document !== 'undefined') {
        const customNav = document.querySelector('.uni-page-head')
        if (customNav) {
          resolve(customNav.offsetHeight)
        } else {
          resolve(44) // 默认导航栏高度
        }
      } else {
        resolve(44)
      }
      // #endif
      
      // #ifdef APP-PLUS
      // App端：状态栏 + 导航栏
      try {
        const statusBarHeight = plus.navigator.getStatusbarHeight()
        resolve(statusBarHeight + 44)
      } catch (error) {
        console.error('App端高度获取失败:', error)
        resolve(88)
      }
      // #endif
      
      // 默认值
      resolve(44)
    })
  }
  
  // 获取默认高度
  getDefaultHeight() {
    // #ifdef MP-WEIXIN
    return 44 // 微信小程序默认
    // #endif
    // #ifdef H5
    return 44 // H5默认
    // #endif
    // #ifdef APP-PLUS
    return 88 // App默认（状态栏44 + 导航栏44）
    // #endif
    return 44
  }
  
  // 获取状态栏高度
  getStatusBarHeight() {
    // #ifdef MP-WEIXIN
    let systemInfo = util.getDeviceInfo();
    return systemInfo.statusBarHeight || 20
    // #endif
    // #ifdef H5
    return 0 // H5通常没有状态栏
    // #endif
    // #ifdef APP-PLUS
    try {
      return plus.navigator.getStatusbarHeight()
    } catch (error) {
      return 44
    }
    // #endif
    return 0
  }

  // 获取安全区域
  getSafeAreaInsets() {
    try {
      let systemInfo = util.getDeviceInfo();
      return systemInfo.safeArea || {
        top: 0,
        bottom: 0,
        left: 0,
        right: 0
      }
    } catch (error) {
      return {
        top: 0,
        bottom: 0,
        left: 0,
        right: 0
      }
    }
  } 

  // 创建安全的事件处理器
  createSafeEventHandler(handler, options = {}) {
    return EventSafety.wrapEventHandler(handler, options)
  }  

  // 安全地处理服务请求事件
  createServiceRequestHandler(component) {
    return this.createSafeEventHandler((event) => {
      return this.handleServiceRequest(event, component)
    }, {
      onError: (error, event) => {
        this.handleNavigationError(error, event, component)
      }
    })
  }  

  // 处理服务请求
  async handleServiceRequest(event, component) {
    console.log('处理导航相关服务请求:', event.type)
    
    // 安全检查事件目标
    if (this.shouldProcessNavigationRequest(event)) {
      await this.processNavigationRequest(event, component)
    }
  }
  
  // 检查是否应该处理导航请求
  shouldProcessNavigationRequest(event) {
    // 方法1：检查事件类型
    if (event.type === 'service.requestComponentInfo') {
      return true
    }
    
    // 方法2：检查目标元素
    if (event.matches('.navigation-component') || event.matches('.uni-page-head')) {
      return true
    }
    
    // 方法3：检查事件详情
    if (event.detail && event.detail.componentType === 'navigation') {
      return true
    }
    
    return false
  }
  
  // 处理导航请求
  async processNavigationRequest(event, component) {
    try {
      // 获取导航栏信息
      const navInfo = await this.getNavigationInfo(component)
      
      // 发送响应
      this.emitNavigationResponse(navInfo, component)
      
    } catch (error) {
      console.error('处理导航请求失败:', error)
      throw error
    }
  }  
  

  // 获取完整的导航信息
  async getNavigationInfo(component) {
    const [navHeight, statusBarHeight, safeArea] = await Promise.all([
      this.getNavigationHeight(component),
      this.getStatusBarHeight(),
      this.getSafeAreaInsets()
    ])
    
    return {
      navHeight,
      statusBarHeight,
      safeArea,
      timestamp: Date.now()
    }
  }
  
  // 发送导航响应
  emitNavigationResponse(navInfo, component) {
    if (component && component.$emit) {
      component.$emit('navigation.infoResponse', {
        success: true,
        data: navInfo,
        timestamp: Date.now()
      })
    }
  }  

  // 错误处理
  handleNavigationError(error, event, component) {
    console.error('导航处理错误:', {
      error: error.message,
      eventType: event?.type,
      component: component?.$options?.name
    })
    
    // 发送错误响应
    if (component && component.$emit) {
      component.$emit('navigation.infoError', {
        success: false,
        error: error.message,
        timestamp: Date.now()
      })
    }
    
    // 显示用户友好的错误信息
    this.showError('导航服务暂时不可用')
  }
  
  // 显示错误提示
  showError(message) {
    uni.showToast({
      title: message,
      icon: 'none',
      duration: 2000
    })
  }  
  
  // 清理缓存
  clearCache() {
    this.navigationCache.clear()
    console.log('导航缓存已清理')
  }
  
}

// 创建全局实例
const navigationHelper = new NavigationHelper()

export default navigationHelper