import { dialog, app } from 'electron'
import { autoUpdater } from 'electron-updater'
import { platform } from '@electron-toolkit/utils'
import { logger } from './logger'
import { getActiveProxyUrl } from './network/proxy'
import { closeWorkerAsync } from './worker/workerManager'

// R2 镜像源 URL（速度更快，作为主要更新源）
const R2_MIRROR_URL = 'https://chatlab.1app.top/releases/download'

// 更新源类型
type UpdateSource = 'github' | 'r2'

// 当前使用的更新源（默认 R2 优先）
let currentSource: UpdateSource = 'r2'

// 是否已尝试过备用源
let hasTriedFallback = false

/**
 * 配置自动更新的代理设置
 * electron-updater 通过环境变量读取代理配置
 */
function configureUpdateProxy(): void {
  const proxyUrl = getActiveProxyUrl()

  if (proxyUrl) {
    // 设置环境变量，electron-updater 会自动读取
    process.env.HTTPS_PROXY = proxyUrl
    process.env.HTTP_PROXY = proxyUrl
    logger.info(`[Update] 使用代理: ${proxyUrl}`)
  } else {
    // 清除代理环境变量
    delete process.env.HTTPS_PROXY
    delete process.env.HTTP_PROXY
  }
}

/**
 * 切换到 R2 镜像源
 */
function switchToR2Mirror(): void {
  currentSource = 'r2'
  autoUpdater.setFeedURL({
    provider: 'generic',
    url: R2_MIRROR_URL,
  })
  logger.info(`[Update] 使用 R2 镜像源: ${R2_MIRROR_URL}`)
}

/**
 * 切换到 GitHub 源（备用更新源）
 */
function switchToGitHub(): void {
  currentSource = 'github'
  // 使用 GitHub 作为 generic provider
  autoUpdater.setFeedURL({
    provider: 'github',
    owner: 'hellodigua',
    repo: 'ChatLab',
  })
  logger.info('[Update] 已切换到 GitHub 备用源')
}

/**
 * 重置为默认更新源（R2 优先）
 */
function resetToDefaultSource(): void {
  hasTriedFallback = false
  switchToR2Mirror()
}

/**
 * 判断错误是否为网络相关错误
 */
function isNetworkError(error: Error): boolean {
  const networkErrorKeywords = [
    'ECONNREFUSED',
    'ENOTFOUND',
    'ETIMEDOUT',
    'ECONNRESET',
    'ENETUNREACH',
    'EAI_AGAIN',
    'socket hang up',
    'network',
    'connect',
    'timeout',
    'getaddrinfo',
  ]
  const errorMessage = error.message?.toLowerCase() || ''
  const errorCode = (error as NodeJS.ErrnoException).code?.toLowerCase() || ''

  return networkErrorKeywords.some(
    (keyword) => errorMessage.includes(keyword.toLowerCase()) || errorCode.includes(keyword.toLowerCase())
  )
}

/**
 * 判断版本号是否为预发布版本
 * 预发布版本格式：0.3.0-beta.1, 0.4.2-alpha.23, 1.0.0-rc.1 等
 * 标准版本格式：0.3.0, 1.0.0, 2.1.3 等
 */
function isPreReleaseVersion(version: string): boolean {
  // 预发布版本包含连字符后跟预发布标识（alpha, beta, rc, dev, canary 等）
  return /-/.test(version)
}

let isFirstShow = true
// 标记是否为手动检查更新（手动检查时即使是预发布版本也显示弹窗）
let isManualCheck = false
const checkUpdate = (win) => {
  // 配置代理
  configureUpdateProxy()

  autoUpdater.autoDownload = false // 自动下载
  autoUpdater.autoInstallOnAppQuit = true // 应用退出后自动安装

  // 开发模式下模拟更新检测（需要创建 dev-app-update.yml 文件）
  // 取消下面的注释来启用开发模式更新测试
  // if (!app.isPackaged) {
  //   Object.defineProperty(app, 'isPackaged', {
  //     get() {
  //       return true
  //     },
  //   })
  // }

  let showUpdateMessageBox = false
  autoUpdater.on('update-available', (info) => {
    // win.webContents.send('show-message', 'electron:发现新版本')
    if (showUpdateMessageBox) return

    // 检查是否为预发布版本
    const isPreRelease = isPreReleaseVersion(info.version)

    // 预发布版本仅在手动检查时显示更新弹窗
    if (isPreRelease && !isManualCheck) {
      console.log(`[Update] 发现预发布版本 ${info.version}，跳过自动更新提示`)
      logger.info(`[Update] 发现预发布版本 ${info.version}，跳过自动更新提示（需手动检查更新）`)
      return
    }

    showUpdateMessageBox = true

    dialog
      .showMessageBox({
        title: '发现新版本 v' + info.version,
        message: '发现新版本 v' + info.version,
        detail: '是否立即下载并安装新版本？',
        buttons: ['立即下载', '取消'],
        defaultId: 0,
        cancelId: 1,
        type: 'question',
        noLink: true,
      })
      .then((result) => {
        showUpdateMessageBox = false
        if (result.response === 0) {
          autoUpdater
            .downloadUpdate()
            .then(() => {
              console.log('wait for post download operation')
            })
            .catch((downloadError) => {
              // 下载失败记录到日志，不显示给用户
              logger.error(`[Update] 下载更新失败: ${downloadError}`)
            })
        }
      })
  })

  // 监听下载进度事件
  autoUpdater.on('download-progress', (progressObj) => {
    console.log(`更新下载进度: ${progressObj.percent}%`)
    win.webContents.send('update-download-progress', progressObj.percent)
  })

  // 下载完成
  autoUpdater.on('update-downloaded', () => {
    dialog
      .showMessageBox({
        title: '下载完成',
        message: '新版本已准备就绪，是否现在安装？',
        buttons: ['安装', platform.isMacOS ? '之后提醒' : '稍后（应用退出后自动安装）'],
        defaultId: 1,
        cancelId: 2,
        type: 'question',
      })
      .then(async (result) => {
        if (result.response === 0) {
          win.webContents.send('begin-install')
          // @ts-ignore
          app.isQuiting = true

          // Windows 上先关闭 Worker 线程，确保进程能正常退出
          // 否则 NSIS 安装器可能无法关闭旧进程
          if (platform.isWindows) {
            logger.info('[Update] Windows: 关闭 Worker 后再执行安装...')
            try {
              await closeWorkerAsync()
            } catch (error) {
              logger.error(`[Update] 关闭 Worker 失败: ${error}`)
            }
          }

          setTimeout(() => {
            setImmediate(() => {
              autoUpdater.quitAndInstall()
            })
          }, 100)
        }
      })
  })

  // 不需要更新
  autoUpdater.on('update-not-available', (info) => {
    // 客户端打开会默认弹一次，用isFirstShow来控制不弹
    if (isFirstShow) {
      isFirstShow = false
    } else {
      win.webContents.send('show-message', {
        type: 'success',
        message: '已是最新版本',
      })
    }
  })

  // 错误处理（智能切换备用源）
  autoUpdater.on('error', (err) => {
    logger.error(`[Update] 更新错误 (${currentSource}): ${err.message || err}`)

    // 如果是 R2 源且为网络错误，尝试切换到 GitHub 备用源
    if (currentSource === 'r2' && !hasTriedFallback && isNetworkError(err)) {
      hasTriedFallback = true
      logger.info('[Update] R2 镜像源访问失败，尝试切换到 GitHub 备用源...')

      switchToGitHub()

      // 延迟 1 秒后重试检查更新
      setTimeout(() => {
        autoUpdater.checkForUpdates().catch((retryErr) => {
          logger.error(`[Update] GitHub 备用源检查更新也失败: ${retryErr}`)
        })
      }, 1000)
    }
  })

  // 等待 3 秒再检查更新，确保窗口准备完成，用户进入系统
  setTimeout(() => {
    isManualCheck = false // 自动检查
    resetToDefaultSource() // 重置为默认更新源（R2 优先）

    autoUpdater.checkForUpdates().catch((err) => {
      console.log('[Update] 检查更新失败:', err)
    })
  }, 3000)
}

/**
 * 手动检查更新
 * 手动检查时，即使是预发布版本也会显示更新弹窗
 */
const manualCheckForUpdates = () => {
  // 配置代理
  configureUpdateProxy()

  isManualCheck = true // 手动检查
  isFirstShow = false // 手动检查时，无论结果都显示提示
  resetToDefaultSource() // 重置为默认更新源（R2 优先）

  autoUpdater.checkForUpdates().catch((err) => {
    console.log('[Update] 手动检查更新失败:', err)
    logger.error(`[Update] 手动检查更新失败: ${err}`)
  })
}

/**
 * 模拟更新弹窗（仅用于开发测试）
 * 控制台通过：window.api.app.simulateUpdate() 测试
 */
const simulateUpdateDialog = (win) => {
  dialog.showMessageBox({
    title: '发现新版本 v9.9.9',
    message: '发现新版本 v9.9.9',
    detail: '是否立即下载并安装新版本？',
    buttons: ['立即下载', '取消'],
    defaultId: 0,
    cancelId: 1,
    type: 'question',
    noLink: true,
  })
}

export { checkUpdate, simulateUpdateDialog, manualCheckForUpdates }
