/**
 * uni-app 通用工具函数
 * 封装常用的 uni-app API，提供更便捷的调用方式
 */

/**
 * 显示消息提示框
 * @param {string} title - 提示的内容
 * @param {string} icon - 图标类型：success/error/loading/none
 * @param {number} duration - 提示的延迟时间，单位毫秒
 * @param {boolean} mask - 是否显示透明蒙层，防止触摸穿透
 */
export const showToast = (title, icon = 'none', duration = 2000, mask = false) => {
  return new Promise((resolve) => {
    uni.showToast({
      title,
      icon,
      duration,
      mask,
      success: resolve,
      fail: resolve
    })
  })
}

/**
 * 显示 loading 提示框
 * @param {string} title - 提示的内容
 * @param {boolean} mask - 是否显示透明蒙层，防止触摸穿透
 */
export const showLoading = (title = '加载中...', mask = true) => {
  return new Promise((resolve) => {
    uni.showLoading({
      title,
      mask,
      success: resolve,
      fail: resolve
    })
  })
}

/**
 * 隐藏 loading 提示框
 */
export const hideLoading = () => {
  return new Promise((resolve) => {
    uni.hideLoading({
      success: resolve,
      fail: resolve
    })
  })
}

/**
 * 显示模态弹窗
 * @param {Object} options - 配置选项
 */
export const showModal = (options = {}) => {
  const defaultOptions = {
    title: '提示',
    content: '',
    showCancel: true,
    cancelText: '取消',
    confirmText: '确定',
    cancelColor: '#000000',
    confirmColor: '#576B95'
  }
  
  return new Promise((resolve) => {
    uni.showModal({
      ...defaultOptions,
      ...options,
      success: resolve,
      fail: resolve
    })
  })
}

/**
 * 显示操作菜单
 * @param {Array} itemList - 按钮的文字数组
 * @param {string} itemColor - 按钮的文字颜色
 */
export const showActionSheet = (itemList, itemColor = '#000000') => {
  return new Promise((resolve) => {
    uni.showActionSheet({
      itemList,
      itemColor,
      success: resolve,
      fail: resolve
    })
  })
}

/**
 * 设置导航栏标题
 * @param {string} title - 页面标题
 */
export const setNavigationBarTitle = (title) => {
  return new Promise((resolve) => {
    uni.setNavigationBarTitle({
      title,
      success: resolve,
      fail: resolve
    })
  })
}

/**
 * 设置导航栏颜色
 * @param {string} frontColor - 前景颜色值，包括按钮、标题、状态栏的颜色
 * @param {string} backgroundColor - 背景颜色值
 * @param {Object} animation - 动画效果
 */
export const setNavigationBarColor = (frontColor, backgroundColor, animation = {}) => {
  return new Promise((resolve) => {
    uni.setNavigationBarColor({
      frontColor,
      backgroundColor,
      animation,
      success: resolve,
      fail: resolve
    })
  })
}

/**
 * 页面跳转
 * @param {string} url - 需要跳转的应用内非 tabBar 的页面的路径
 * @param {Object} params - 页面参数
 */
export const navigateTo = (url, params = {}) => {
  let fullUrl = url
  if (Object.keys(params).length > 0) {
    const queryString = Object.keys(params)
      .map(key => `${key}=${encodeURIComponent(params[key])}`)
      .join('&')
    fullUrl += `?${queryString}`
  }
  
  return new Promise((resolve) => {
    uni.navigateTo({
      url: fullUrl,
      success: resolve,
      fail: resolve
    })
  })
}

/**
 * 关闭当前页面，跳转到应用内的某个页面
 * @param {string} url - 需要跳转的应用内非 tabBar 的页面的路径
 * @param {Object} params - 页面参数
 */
export const redirectTo = (url, params = {}) => {
  let fullUrl = url
  if (Object.keys(params).length > 0) {
    const queryString = Object.keys(params)
      .map(key => `${key}=${encodeURIComponent(params[key])}`)
      .join('&')
    fullUrl += `?${queryString}`
  }
  
  return new Promise((resolve) => {
    uni.redirectTo({
      url: fullUrl,
      success: resolve,
      fail: resolve
    })
  })
}

/**
 * 跳转到 tabBar 页面
 * @param {string} url - 需要跳转的 tabBar 页面的路径
 */
export const switchTab = (url) => {
  return new Promise((resolve) => {
    uni.switchTab({
      url,
      success: resolve,
      fail: resolve
    })
  })
}

/**
 * 关闭当前页面，返回上一页面或多级页面
 * @param {number} delta - 返回的页面数，如果 delta 大于现有页面数，则返回到首页
 */
export const navigateBack = (delta = 1) => {
  return new Promise((resolve) => {
    uni.navigateBack({
      delta,
      success: resolve,
      fail: resolve
    })
  })
}

/**
 * 关闭所有页面，打开到应用内的某个页面
 * @param {string} url - 需要跳转的应用内页面路径
 * @param {Object} params - 页面参数
 */
export const reLaunch = (url, params = {}) => {
  let fullUrl = url
  if (Object.keys(params).length > 0) {
    const queryString = Object.keys(params)
      .map(key => `${key}=${encodeURIComponent(params[key])}`)
      .join('&')
    fullUrl += `?${queryString}`
  }
  
  return new Promise((resolve) => {
    uni.reLaunch({
      url: fullUrl,
      success: resolve,
      fail: resolve
    })
  })
}

/**
 * 获取当前页面栈
 */
export const getCurrentPages = () => {
  return getCurrentPages()
}

/**
 * 获取系统信息
 */
export const getSystemInfo = () => {
  return new Promise((resolve, reject) => {
    uni.getSystemInfo({
      success: resolve,
      fail: reject
    })
  })
}

/**
 * 获取系统信息同步版本
 */
export const getSystemInfoSync = () => {
  return uni.getSystemInfoSync()
}

/**
 * 获取网络类型
 */
export const getNetworkType = () => {
  return new Promise((resolve, reject) => {
    uni.getNetworkType({
      success: resolve,
      fail: reject
    })
  })
}

/**
 * 监听网络状态变化
 * @param {Function} callback - 网络状态变化的回调函数
 */
export const onNetworkStatusChange = (callback) => {
  uni.onNetworkStatusChange(callback)
}

/**
 * 取消监听网络状态变化
 * @param {Function} callback - 网络状态变化的回调函数
 */
export const offNetworkStatusChange = (callback) => {
  uni.offNetworkStatusChange(callback)
}

/**
 * 选择图片
 * @param {Object} options - 配置选项
 */
export const chooseImage = (options = {}) => {
  const defaultOptions = {
    count: 9,
    sizeType: ['original', 'compressed'],
    sourceType: ['album', 'camera']
  }
  
  return new Promise((resolve, reject) => {
    uni.chooseImage({
      ...defaultOptions,
      ...options,
      success: resolve,
      fail: reject
    })
  })
}

/**
 * 预览图片
 * @param {Array} urls - 需要预览的图片链接列表
 * @param {number} current - 当前显示图片的索引
 */
export const previewImage = (urls, current = 0) => {
  return new Promise((resolve) => {
    uni.previewImage({
      urls,
      current,
      success: resolve,
      fail: resolve
    })
  })
}

/**
 * 保存图片到系统相册
 * @param {string} filePath - 图片文件路径
 */
export const saveImageToPhotosAlbum = (filePath) => {
  return new Promise((resolve, reject) => {
    uni.saveImageToPhotosAlbum({
      filePath,
      success: resolve,
      fail: reject
    })
  })
}

/**
 * 上传文件
 * @param {Object} options - 配置选项
 */
export const uploadFile = (options) => {
  return new Promise((resolve, reject) => {
    const uploadTask = uni.uploadFile({
      ...options,
      success: resolve,
      fail: reject
    })
    
    // 返回上传任务，可以监听上传进度
    return uploadTask
  })
}

/**
 * 下载文件
 * @param {Object} options - 配置选项
 */
export const downloadFile = (options) => {
  return new Promise((resolve, reject) => {
    const downloadTask = uni.downloadFile({
      ...options,
      success: resolve,
      fail: reject
    })
    
    // 返回下载任务，可以监听下载进度
    return downloadTask
  })
}

/**
 * 获取位置信息
 * @param {Object} options - 配置选项
 */
export const getLocation = (options = {}) => {
  const defaultOptions = {
    type: 'wgs84',
    altitude: false
  }
  
  return new Promise((resolve, reject) => {
    uni.getLocation({
      ...defaultOptions,
      ...options,
      success: resolve,
      fail: reject
    })
  })
}

/**
 * 打开地图选择位置
 * @param {Object} options - 配置选项
 */
export const chooseLocation = (options = {}) => {
  return new Promise((resolve, reject) => {
    uni.chooseLocation({
      ...options,
      success: resolve,
      fail: reject
    })
  })
}

/**
 * 使用应用内置地图查看位置
 * @param {Object} options - 配置选项
 */
export const openLocation = (options) => {
  return new Promise((resolve, reject) => {
    uni.openLocation({
      ...options,
      success: resolve,
      fail: reject
    })
  })
}

/**
 * 扫码
 * @param {Object} options - 配置选项
 */
export const scanCode = (options = {}) => {
  const defaultOptions = {
    onlyFromCamera: false,
    scanType: ['barCode', 'qrCode']
  }
  
  return new Promise((resolve, reject) => {
    uni.scanCode({
      ...defaultOptions,
      ...options,
      success: resolve,
      fail: reject
    })
  })
}

/**
 * 设置剪贴板内容
 * @param {string} data - 需要设置的内容
 */
export const setClipboardData = (data) => {
  return new Promise((resolve, reject) => {
    uni.setClipboardData({
      data,
      success: resolve,
      fail: reject
    })
  })
}

/**
 * 获取剪贴板内容
 */
export const getClipboardData = () => {
  return new Promise((resolve, reject) => {
    uni.getClipboardData({
      success: resolve,
      fail: reject
    })
  })
}

/**
 * 拨打电话
 * @param {string} phoneNumber - 需要拨打的电话号码
 */
export const makePhoneCall = (phoneNumber) => {
  return new Promise((resolve, reject) => {
    uni.makePhoneCall({
      phoneNumber,
      success: resolve,
      fail: reject
    })
  })
}

/**
 * 震动
 * @param {string} type - 震动强度类型，有效值为：heavy、medium、light
 */
export const vibrateShort = (type = 'medium') => {
  return new Promise((resolve) => {
    uni.vibrateShort({
      type,
      success: resolve,
      fail: resolve
    })
  })
}

/**
 * 长震动
 */
export const vibrateLong = () => {
  return new Promise((resolve) => {
    uni.vibrateLong({
      success: resolve,
      fail: resolve
    })
  })
}

/**
 * 获取用户信息
 * @param {Object} options - 配置选项
 */
export const getUserInfo = (options = {}) => {
  return new Promise((resolve, reject) => {
    uni.getUserInfo({
      ...options,
      success: resolve,
      fail: reject
    })
  })
}

/**
 * 获取用户设置
 */
export const getSetting = () => {
  return new Promise((resolve, reject) => {
    uni.getSetting({
      success: resolve,
      fail: reject
    })
  })
}

/**
 * 调起客户端小程序设置界面
 */
export const openSetting = () => {
  return new Promise((resolve, reject) => {
    uni.openSetting({
      success: resolve,
      fail: reject
    })
  })
}

/**
 * 提前向用户发起授权请求
 * @param {string} scope - 需要获取权限的 scope
 */
export const authorize = (scope) => {
  return new Promise((resolve, reject) => {
    uni.authorize({
      scope,
      success: resolve,
      fail: reject
    })
  })
}

/**
 * 页面滚动到指定位置
 * @param {number} scrollTop - 滚动到页面的目标位置
 * @param {number} duration - 滚动动画的时长
 */
export const pageScrollTo = (scrollTop, duration = 300) => {
  return new Promise((resolve) => {
    uni.pageScrollTo({
      scrollTop,
      duration,
      success: resolve,
      fail: resolve
    })
  })
}

/**
 * 创建动画实例
 * @param {Object} options - 配置选项
 */
export const createAnimation = (options = {}) => {
  const defaultOptions = {
    duration: 400,
    timingFunction: 'linear',
    delay: 0,
    transformOrigin: '50% 50% 0'
  }
  
  return uni.createAnimation({
    ...defaultOptions,
    ...options
  })
}

/**
 * 节流函数
 * @param {Function} func - 需要节流的函数
 * @param {number} delay - 延迟时间
 */
export const throttle = (func, delay = 300) => {
  let timer = null
  return function (...args) {
    if (!timer) {
      timer = setTimeout(() => {
        func.apply(this, args)
        timer = null
      }, delay)
    }
  }
}

/**
 * 防抖函数
 * @param {Function} func - 需要防抖的函数
 * @param {number} delay - 延迟时间
 */
export const debounce = (func, delay = 300) => {
  let timer = null
  return function (...args) {
    if (timer) clearTimeout(timer)
    timer = setTimeout(() => {
      func.apply(this, args)
    }, delay)
  }
}