import { defineStore } from 'pinia'
import { ref } from 'vue'
import { Message } from '@arco-design/web-vue'
import { formatBytes as formatFileSize } from '@/utils/fileUtils'
import {
  CheckUpdate, GetUpdateConfig, DownloadUpdate, InstallUpdate
} from '../wailsjs/v3-bindings/u-desk/app'
import { On, Off } from '@wailsio/events'

/**
 * 更新管理 Store
 * 统一管理版本检查、下载、安装等更新相关逻辑
 */
export const useUpdateStore = defineStore('update', () => {
  // ==================== 状态 ====================
  const updateInfo = ref<UpdateInfo | null>(null)
  const showUpdate = ref(false)
  const checking = ref(false)
  const downloading = ref(false)
  const installing = ref(false)
  const downloadProgress = ref(0)
  const downloadStatus = ref<'active' | 'exception' | 'success'>('active')
  const progressInfo = ref({
    speed: 0,
    downloaded: 0,
    total: 0
  })

  // 节流：防止过度更新
  let lastUpdateTime = 0
  const UPDATE_THROTTLE = 100 // 100ms 最小更新间隔

  // 最小显示时间：确保进度条至少显示 5 秒
  let downloadStartTime = 0
  const MIN_DISPLAY_TIME = 5000 // 5 秒最小显示时间

  // ==================== 工具函数 ====================
  const parseEventData = (event: unknown) => {
    try {
      return typeof event === 'string' ? JSON.parse(event) : (event as Record<string, unknown>)
    } catch {
      return {}
    }
  }

  const formatSpeed = (bytesPerSecond: number): string => {
    return formatFileSize(bytesPerSecond) + '/s'
  }

  // ==================== 核心方法 ====================
  /**
   * 检查更新
   * @param silent 是否静默模式（不显示消息）
   */
  const checkForUpdates = async (silent = false) => {
    if (checking.value) return

    checking.value = true

    try {
      const configResult = await GetUpdateConfig()
      if (!configResult.success) return

      const { auto_check_enabled } = configResult.data || {}
      if (!auto_check_enabled) return

      const result = await CheckUpdate()
      if (result.success && result.data?.has_update) {
        updateInfo.value = result.data
        showUpdate.value = true

        // 系统通知：发现新版本
        try {
          window.runtime?.SendNotification?.({
            title: 'U-Desk',
            body: `发现新版本 ${result.data.latest_version}，点击查看`
          })
        } catch { /* 通知不可用时忽略 */ }

        if (!silent) {
          Message.success('发现新版本！')
        }
      } else if (!silent) {
        Message.success('已是最新版本')
      }
    } catch (error) {
      if (!silent) {
        console.error('检查更新失败:', error)
        Message.error('检查更新失败：' + (error as Error).message)
      }
    } finally {
      checking.value = false
    }
  }

  /**
   * 下载更新
   */
  const downloadUpdate = async () => {
    const url = updateInfo.value?.download_url
    if (!url) {
      Message.warning('下载地址不存在')
      return
    }

    // 记录开始时间
    downloadStartTime = Date.now()

    // 重置下载状态
    downloading.value = true
    downloadProgress.value = 1  // 设置为 1 而不是 0，确保进度条显示
    downloadStatus.value = 'active'
    progressInfo.value = { speed: 0, downloaded: 0, total: 0 }

    try {
      const result = await DownloadUpdate(url)
      if (!result.success) {
        downloadStatus.value = 'exception'
        downloading.value = false
        Message.error(result.message || '下载启动失败')
        return
      }
      Message.success('下载请求已发送，等待后端发送进度事件...')
    } catch (error) {
      console.error('下载失败：', error)
      downloadStatus.value = 'exception'
      downloading.value = false
      Message.error('下载失败：' + (error as Error).message)
    }
  }

  /**
   * 安装更新
   */
  const installUpdate = async (filePath: string) => {
    if (!filePath) {
      Message.warning('请先下载更新包')
      return
    }

    installing.value = true

    try {
      const result = await InstallUpdate(filePath, true)
      if (result.success) {
        Message.success({
          content: '安装成功！应用将在几秒后重启...',
          duration: 3000
        })
        return
      }
      Message.error(result.message || '安装失败')
    } catch (error) {
      Message.error('安装失败：' + (error as Error).message)
    } finally {
      installing.value = false
    }
  }

  /**
   * 下载进度处理
   */
  const onDownloadProgress = (event: unknown) => {
    const now = Date.now()
    if (now - lastUpdateTime < UPDATE_THROTTLE) {
      return
    }

    lastUpdateTime = now
    const data = parseEventData(event)

    progressInfo.value = {
      speed: (data.speed as number) || 0,
      downloaded: (data.downloaded as number) || 0,
      total: (data.total as number) || 0
    }

    const rawProgress = Number(data.progress) || 0
    const safeProgress = Math.min(100, Math.max(0, Math.round(rawProgress)))
    downloadProgress.value = safeProgress
  }

  /**
   * 下载完成处理
   */
  const onDownloadComplete = (event: unknown) => {
    const data = parseEventData(event)

    // 错误处理
    if (data.error) {
      console.error('下载失败：', data.error)
      downloadStatus.value = 'exception'
      downloading.value = false
      Message.error('下载失败：' + data.error)
      return
    }

    // 数据验证
    if (!data.success || !data.file_path) {
      console.error('下载数据不完整：', data)
      downloadStatus.value = 'exception'
      downloading.value = false
      Message.error('下载完成但数据不完整')
      return
    }

    // 完成下载
    downloadProgress.value = 100
    downloadStatus.value = 'success'

    const fileSize = (data.file_size as number) || 0

    // 系统通知：下载完成
    try {
      window.runtime?.SendNotification?.({
        title: 'U-Desk',
        body: `更新包下载完成 (${formatFileSize(fileSize)})，正在安装...`
      })
    } catch { /* 通知不可用时忽略 */ }
    progressInfo.value = {
      speed: 0,
      downloaded: fileSize,
      total: fileSize
    }

    // 计算已经显示的时间
    const elapsed = Date.now() - downloadStartTime
    const remainingTime = Math.max(0, MIN_DISPLAY_TIME - elapsed)

    // 确保进度条至少显示 3 秒
    setTimeout(() => {
      downloading.value = false  // 安装前才关闭下载状态
      installUpdate(data.file_path as string)
    }, remainingTime)
  }

  /**
   * 设置事件监听
   */
  const setupEventListeners = () => {
    On('download-progress', onDownloadProgress)
    On('download-complete', onDownloadComplete)
  }

  /**
   * 移除事件监听
   */
  const removeEventListeners = () => {
    Off('download-progress')
    Off('download-complete')
  }

  // ==================== 返回 ====================
  return {
    // 状态
    updateInfo,
    showUpdate,
    checking,
    downloading,
    installing,
    downloadProgress,
    downloadStatus,
    progressInfo,

    // 方法
    checkForUpdates,
    downloadUpdate,
    installUpdate,
    setupEventListeners,
    removeEventListeners,
    formatFileSize,
    formatSpeed
  }
})

// ==================== 类型定义 ====================
interface UpdateInfo {
  has_update: boolean
  current_version: string
  latest_version: string
  download_url: string
  changelog: string
  force_update: boolean
  release_date: string
  file_size: number
}
