/**
 * 下载文件
 * @param blob 文件流
 * @param fileName 文件名
 */
export function downloadFile(blob: Blob, fileName: string) {
  if (!(blob instanceof Blob)) {
    console.error('downloadFile: data is not a Blob')
    return
  }
  const url = window.URL.createObjectURL(blob)
  const link = document.createElement('a')
  link.href = url
  link.download = fileName
  link.click()
  window.URL.revokeObjectURL(url)
}

/**
 * 解析文件 JSON 字符串，并清洗 URL 中的异常字符
 * @param jsonStr JSON 字符串
 * @returns 解析后的文件数组
 */
export function parseFileJson(jsonStr: any): any[] {
  if (!jsonStr)
    return []

  let parsed: any

  // 如果已经是对象或数组，直接使用
  if (typeof jsonStr === 'object') {
    parsed = jsonStr
  }
  else {
    try {
      // 1. 尝试直接解析
      // 如果字符串包含 [object Object]，说明是之前错误的序列化结果，直接返回空
      if (typeof jsonStr === 'string' && jsonStr.includes('[object Object]')) {
        return []
      }
      parsed = JSON.parse(jsonStr)

      // 2. 如果解析出来还是字符串（比如双重序列化），再解析一次
      if (typeof parsed === 'string') {
        try {
          parsed = JSON.parse(parsed)
        }
        catch {
          // 忽略第二次解析失败
        }
      }
    }
    catch (error) {
      console.error('JSON 解析失败:', error)
      return []
    }
  }

  // 3. 统一转换为数组
  const list = Array.isArray(parsed) ? parsed : [parsed]

  // 4. 清洗数据
  return list.map((item: any) => {
    if (typeof item === 'string') {
      const t = item.trim()
      if ((t.startsWith('{') && t.endsWith('}')) || (t.startsWith('[') && t.endsWith(']'))) {
        try {
          item = JSON.parse(t)
        }
        catch {
          // 忽略，按普通字符串处理
        }
      }
    }

    if (item && typeof item === 'object') {
      // 清洗 URL
      if (item.url && typeof item.url === 'string') {
        // 去除反引号和首尾空格
        item.url = item.url.replace(/`/g, '').trim()
      }
      // 如果没有名字，从 URL 中提取
      if (!item.name && item.url) {
        item.name = item.url.split('/').pop()?.split('?')[0] || 'file'
      }
      return item
    }
    // 如果是字符串格式，转换为对象
    if (typeof item === 'string' && item) {
      const url = item.replace(/`/g, '').trim()
      return {
        url,
        name: url.split('/').pop()?.split('?')[0] || 'file',
      }
    }
    return item
  }).filter((item: any) => item && item.url) // 过滤无效项
}

/**
 * 从多种格式的输入中提取图片 URL 数组
 * @param inputs 输入数据（字符串、数组、对象等）
 * @returns URL 数组
 */
export function collectImageUrls(...inputs: any[]): string[] {
  const res: string[] = []
  inputs.forEach((v) => {
    if (!v)
      return

    let parsed = v
    // 尝试解析 JSON 字符串
    if (typeof v === 'string' && (v.trim().startsWith('[') || v.trim().startsWith('{'))) {
      const jsonRes = parseFileJson(v)
      if (jsonRes.length > 0)
        parsed = jsonRes
    }

    if (Array.isArray(parsed)) {
      parsed.forEach((x: any) => {
        if (typeof x === 'string' && x)
          res.push(x)
        else if (x && typeof x === 'object' && typeof x.url === 'string')
          res.push(x.url)
      })
    }
    else if (typeof parsed === 'string' && parsed) {
      res.push(parsed)
    }
    else if (typeof parsed === 'object' && typeof parsed.url === 'string') {
      res.push(parsed.url)
    }
  })
  return res
}

/**
 * 判断文件名是否为图片
 * @param filename 文件名或 URL
 */
export function isImage(filename: string): boolean {
  if (!filename)
    return false
  // 移除查询参数并去除首尾空格
  const cleanName = filename.split('?')[0].trim()
  return /\.(?:jpg|jpeg|png|gif|webp)$/i.test(cleanName)
}

/**
 * 通过 URL 下载文件
 * @param url 文件 URL
 * @param filename 文件名
 */
export async function downloadByUrl(url: string, filename?: string) {
  if (!url)
    return
  const name = filename || url.split('/').pop() || 'file'

  try {
    const response = await fetch(url)
    const blob = await response.blob()
    downloadFile(blob, name)
  }
  catch (error) {
    console.error('Blob下载失败，尝试直接下载:', error)
    const link = document.createElement('a')
    link.href = url
    link.download = name
    link.target = '_blank'
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
  }
}

/**
 * 限制 n-input-number 只能输入数字，拦截字母 e、E 和其他非数值字符
 * @param e 键盘事件
 */
export function handleInputNumberKeyDown(e: any) {
  const letters = /^[a-z]$/i
  if (letters.test(e.key) && !['Backspace', 'Delete', 'Tab', 'ArrowLeft', 'ArrowRight', 'Home', 'End', 'Enter', 'Escape'].includes(e.key)) {
    e.preventDefault()
  }
}

/**
 * n-input 的 allow-input 公共校验：只允许输入数字
 * @param value 当前输入值
 */
export function onlyAllowNumber(value: string) {
  if (!value)
    return true

  return /^\d+$/.test(value)
}

/**
 * n-input 的 allow-input 公共校验：只允许输入数字和英文字母
 * @param value 当前输入值
 */
export function onlyAllowNumberAndLetter(value: string) {
  if (!value)
    return true

  return /^[a-z0-9]+$/i.test(value)
}
