/**
 * @description 防抖函数
 * @param fn 要执行的回调函数
 * @param delay 延迟时间，单位毫秒
 * @returns 包装后的防抖函数
 */
export function debounce<T extends (...args: any[]) => void>(
  fn: T,
  delay: number
): (...args: Parameters<T>) => void {
  let timer: ReturnType<typeof setTimeout> | null = null

  return (...args: Parameters<T>): void => {
    // 如果上次的定时器还存在，清除它
    if (timer) {
      clearTimeout(timer)
    }

    // 设置新的定时器
    timer = setTimeout(() => {
      fn(...args) // 执行传入的函数
    }, delay)
  }
}

/**
 * @description 节流函数
 * @param fn 要执行的回调函数
 * @param delay 时间间隔，单位为毫秒
 * @returns 节流后的函数
 */
export function throttle<T extends (...args: any[]) => void>(
  fn: T,
  delay: number
): (...args: Parameters<T>) => void {
  let lastTime = 0

  return (...args: Parameters<T>): void => {
    const now = Date.now()

    if (now - lastTime >= delay) {
      lastTime = now
      fn(...args)
    }
  }
}

export const downloadAndSaveImage = (url: string) => {
  uni.downloadFile({
    url: url,
    success: downloadResult => {
      if (downloadResult.statusCode === 200) {
        uni.saveImageToPhotosAlbum({
          filePath: downloadResult.tempFilePath,
          success: () => {
            uni.showToast({
              title: '保存成功',
              icon: 'success'
            })
          },
          fail: () => {
            uni.showToast({
              title: '保存失败',
              icon: 'error'
            })
          }
        })
      }
    },
    fail: () => {
      uni.showToast({
        title: '下载失败',
        icon: 'error'
      })
    }
  })
}

export const saveBase64Image = (base64Data: any) => {
  const fileSystemManager = uni.getFileSystemManager()
  const [, format, bodyData] = /data:image\/(\w+);base64,(.*)/.exec(base64Data) || []
  const filePath = `${wx.env.USER_DATA_PATH}/temp_image.${format}`

  fileSystemManager.writeFile({
    filePath,
    data: bodyData,
    encoding: 'base64',
    success: () => {
      uni.saveImageToPhotosAlbum({
        filePath,
        success: () => {
          uni.showToast({
            title: '保存成功',
            icon: 'success'
          })
        },
        fail: () => {
          uni.showToast({
            title: '保存失败',
            icon: 'error'
          })
        }
      })
    },
    fail: () => {
      uni.showToast({
        title: '文件写入失败',
        icon: 'error'
      })
    }
  })
}

export const getFormatTime = (t: Date, f?: string) => {
  const pad = (num: number) => String(num).padStart(2, '0')

  const year = t.getFullYear()
  const month = pad(t.getMonth() + 1)
  const date = pad(t.getDate())
  const hours = pad(t.getHours())
  const minutes = pad(t.getMinutes())
  const seconds = pad(t.getSeconds())

  switch (f) {
    case 'YYYY-MM-DD':
      return `${year}-${month}-${date}`
    case 'YYYY-MM-DD HH:mm:ss':
      return `${year}-${month}-${date} ${hours}:${minutes}:${seconds}`
    case 'YYYY/MM/DD':
      return `${year}/${month}/${date}`
    case 'HH:mm:ss':
      return `${hours}:${minutes}:${seconds}`
    case 'HH:mm':
      return `${hours}:${minutes}`
    default:
      return `${year}-${month}-${date} ${hours}:${minutes}:${seconds}` // 默认格式YYYY-MM-DD HH:mm:ss
  }
}

export class TimeRecorder {
  private startTime: number = 0 // 记录开始时间的时间戳
  private elapsedTime: number = 0 // 累计的浏览时间（单位：毫秒）
  private running: boolean = false // 标记是否正在计时

  /**
   * 启动计时器，初始化计时
   */
  start(): void {
    if (this.running) {
      console.warn('计时器已经在运行中')
      return
    }
    this.startTime = Date.now() // 记录当前时间作为起始时间
    this.elapsedTime = 0 // 重置已用时间
    this.running = true
  }

  /**
   * 暂停计时器，保存当前的时间进度
   */
  pause(): void {
    if (!this.running) {
      console.warn('计时器尚未启动')
      return
    }
    this.elapsedTime += Date.now() - this.startTime // 累加已用时间
    this.running = false
  }

  /**
   * 恢复计时器，从暂停的地方继续
   */
  renew(): void {
    if (this.running) {
      console.warn('计时器已经在运行中')
      return
    }
    this.startTime = Date.now() // 重新记录开始时间
    this.running = true
  }

  /**
   * 终止计时器，放弃当前计时进度
   */
  abort(): void {
    this.elapsedTime = 0 // 放弃当前累计的时间
    this.running = false
  }

  /**
   * 获取当前已用的时间（单位：秒）
   * 如果计时器正在运行，返回当前时间与起始时间的差值加上已用的时间
   */
  getElapsedTime(): string {
    if (this.running) {
      return (this.elapsedTime + (Date.now() - this.startTime) / 1000).toFixed(0) // 计算当前时间到起始时间的差值
    }
    return (this.elapsedTime / 1000).toFixed(0) // 如果计时器已停止，返回累计的时间
  }
}
