import { ref, onUnmounted } from 'vue'
import { useI18n } from 'vue-i18n'
import { useProgress } from './useProgress'
import useUserStore from '@/stores/use-user-store'
import { ucardApi } from '@/api/ucard'
import { userToken } from '@/composables/config'
// ================== 类型声明 ==================

declare const plus: any
declare const uni: any

interface PlusDownloaderDownload {
    filename: string
    pause?: () => void
    resume?: () => void
    start: () => void
    abort: () => void
    addEventListener: (event: string, callback: (data: any) => void) => void
    removeEventListener?: (event: string, callback: (data: any) => void) => void
}

// ================== 常量定义 ==================

/** 存储键名 */
const STORAGE_KEYS = {
    LAST_CHECK: 'last_update_check_time',
    SKIP_VERSION: 'skip_update_version',
    DOWNLOAD_CACHE: 'app_download_cache'
} as const

/** 下载状态码 */
enum DownloadState {
    DOWNLOADING = 3, // 下载中
    COMPLETED = 4    // 下载完成
}

/** HTTP 成功状态码 */
enum HttpStatus {
    OK = 200,            // 成功
    PARTIAL_CONTENT = 206 // 部分内容（断点续传）
}

/** 下载配置 */
const DOWNLOAD_CONFIG = {
    FILE_PATH: '_downloads/app_update.wgt',
    MAX_RETRY: 3,              // 最大重试次数
    RETRY_DELAY: 2000,         // 重试延迟（毫秒）
    TOAST_DURATION: 2000       // Toast 显示时长
} as const

// ================== 类型定义 ==================

/** 更新信息 */
interface UpdateInfo {
    version: string
    forceUpdate: boolean
    wgtUrl?: string
    iosStoreUrl?: string
}

/** 下载缓存 */
interface DownloadCache {
    url: string
    progress: number
    time: number
}

/** API 响应 */
interface ApiResponse<T = any> {
    code: number
    data?: T
    message?: string
}

/** 下载状态变化事件 */
interface DownloadStateEvent {
    state: number
    downloadedSize: number
    totalSize: number
}

/** 平台类型 */
type PlatformType = 'ios' | 'android'

/** 设备类型 */
type EquipmentType = 'ios' | 'Android'

// ================== 工具函数 ==================

/**
 * 获取当前应用版本
 */
function getCurrentVersion(): Promise<string> {
    return new Promise((resolve, reject) => {
        // #ifdef APP-PLUS
        try {
            plus.runtime.getProperty(plus.runtime.appid, (info) => {
                resolve(info.version)
            }, (error) => {
                reject(error)
            })
        } catch (error) {
            reject(error)
        }
        // #endif
        // #ifndef APP-PLUS
        reject(new Error('Not in APP-PLUS environment'))
        // #endif
    })
}

/**
 * 比较版本号
 * @returns 1: v1 > v2, -1: v1 < v2, 0: v1 === v2
 */
function compareVersion(v1: string, v2: string): number {
    const normalizeVersion = (v: string): number[] => {
        return v.split('.').map(segment => parseInt(segment || '0', 10))
    }

    const parts1 = normalizeVersion(v1)
    const parts2 = normalizeVersion(v2)
    const maxLength = Math.max(parts1.length, parts2.length)

    for (let i = 0; i < maxLength; i++) {
        const num1 = parts1[i] || 0
        const num2 = parts2[i] || 0
        if (num1 > num2) return 1
        if (num1 < num2) return -1
    }
    return 0
}

/**
 * 获取平台类型
 */
function getPlatform(): PlatformType {
    // #ifdef APP-PLUS
    try {
        const platform = uni.getSystemInfoSync().platform
        return platform === 'ios' ? 'ios' : 'android'
    } catch (error) {
        console.error('获取平台类型失败:', error)
        return 'android'
    }
    // #endif
    // #ifndef APP-PLUS
    return 'android'
    // #endif
}

/**
 * 获取设备类型（API 参数格式）
 */
function getEquipmentType(): EquipmentType {
    return getPlatform() === 'ios' ? 'ios' : 'Android'
}

/**
 * 显示 Toast 提示
 */
function showToast(message: string, duration = DOWNLOAD_CONFIG.TOAST_DURATION): void {
    uni.showToast({
        title: message,
        icon: 'none',
        duration
    })
}

/**
 * 安全地获取存储值
 */
function getStorageSync<T = any>(key: string, defaultValue: T | null = null): T | null {
    try {
        return uni.getStorageSync(key) || defaultValue
    } catch (error) {
        console.warn(`获取存储失败: ${key}`, error)
        return defaultValue
    }
}

/**
 * 安全地设置存储值
 */
function setStorageSync(key: string, value: any): boolean {
    try {
        uni.setStorageSync(key, value)
        return true
    } catch (error) {
        console.warn(`设置存储失败: ${key}`, error)
        return false
    }
}

/**
 * 安全地移除存储值
 */
function removeStorageSync(key: string): boolean {
    try {
        uni.removeStorageSync(key)
        return true
    } catch (error) {
        console.warn(`移除存储失败: ${key}`, error)
        return false
    }
}

// ================== 主函数 ==================

export function useAppUpdate() {
    const { t } = useI18n()
    const userStore = useUserStore()
    const progress = useProgress()

    const checking = ref(false)
    const updating = ref(false)

    let downloadTask: PlusDownloaderDownload | null = null
    let networkListener: ((res: any) => void) | null = null
    let downloadUrl = ''
    let retryCount = 0
    let stateChangeHandler: ((d: any) => void) | null = null

    // ================== 对外入口 ==================

    /**
     * 检查应用更新
     */
    async function checkUpdate(): Promise<void> {
        // #ifdef APP-PLUS
        if (checking.value) {
            console.warn('更新检查已在进行中')
            return
        }

        checking.value = true

        try {
            const equipmentType = getEquipmentType()
            if (!userToken.value) {
                return
            }
            const res: ApiResponse<UpdateInfo> = await ucardApi.getAppVersionDetail({ equipmentType })

            if (res.code !== 200 || !res.data) {
                const errorMsg = res.message || '获取版本信息失败'
                console.warn(errorMsg)
                return
            }

            const update = res.data
            const currentVersion = await getCurrentVersion()
            const needUpdate = compareVersion(update.version, currentVersion) > 0

            // 保存版本信息
            userStore.saveAppVersion({
                currentVersion,
                version: update.version,
                isUpdate: !needUpdate
            })

            if (!needUpdate) {
                console.log('当前已是最新版本')
                return
            }

            // 检查是否已跳过此版本
            // const skipVersion = getStorageSync<string>(STORAGE_KEYS.SKIP_VERSION)
            // if (!update.forceUpdate && skipVersion === update.version) {
            //     console.log('用户已跳过此版本更新')
            //     return
            // }

            // 显示更新提示
            if (update.forceUpdate) {
                showForceUpdate(update)
            } else {
                showOptionalUpdate(update)
            }
        } catch (error) {
            console.error('检查更新失败:', error)
            const errorMsg = error instanceof Error ? error.message : String(error)
            showToast(t('mine.p28') || `检查更新失败: ${errorMsg}`)
        } finally {
            checking.value = false
        }
        // #endif
    }

    // ================== 更新流程 ==================

    /**
     * 显示强制更新弹窗
     */
    function showForceUpdate(update: UpdateInfo): void {
        uni.showModal({
            title: t('mine.p22'),
            content: t('mine.p23'),
            showCancel: false,
            confirmText: t('mine.p35'),
            success: () => doUpdate(update)
        })
    }

    /**
     * 显示可选更新弹窗
     */
    function showOptionalUpdate(update: UpdateInfo): void {
        uni.showModal({
            title: t('mine.p24'),
            content: t('mine.p25', { version: `v${update.version}` }),
            confirmText: t('mine.p35'),
            cancelText: t('mine.p36'),
            success: (res) => {
                if (res.confirm) {
                    doUpdate(update)
                } else {
                    // 记录跳过的版本
                    setStorageSync(STORAGE_KEYS.SKIP_VERSION, update.version)
                }
            }
        })
    }

    /**
     * 执行更新
     */
    function doUpdate(update: UpdateInfo): void {
        const platform = getPlatform()

        if (platform === 'ios') {
            handleIosUpdate(update)
        } else {
            handleAndroidUpdate(update)
        }
    }

    /**
     * 处理 iOS 更新
     */
    function handleIosUpdate(update: UpdateInfo): void {
        if (!update.iosStoreUrl) {
            showToast(t('mine.p28') || 'iOS 更新链接不存在')
            return
        }

        try {
            plus.runtime.openURL(update.iosStoreUrl)
        } catch (error) {
            console.error('打开 App Store 失败:', error)
            showToast(t('mine.p28') || '打开 App Store 失败')
        }
    }

    /**
     * 处理 Android 更新
     */
    function handleAndroidUpdate(update: UpdateInfo): void {
        if (!update.wgtUrl) {
            showToast(t('mine.p28') || '更新包链接不存在')
            return
        }

        downloadWgt(update.wgtUrl)
    }

    // ================== 下载核心 ==================

    /**
     * 下载 wgt 更新包
     */
    function downloadWgt(url: string): void {
        // #ifdef APP-PLUS
        if (downloadTask) {
            console.warn('下载任务已存在')
            return
        }

        if (!url || !isValidUrl(url)) {
            handleDownloadFail(t('mine.p28') || '下载链接无效')
            return
        }

        downloadUrl = url
        retryCount = 0
        updating.value = true
        progress.show(t('mine.p29'))

        // 初始化网络监听
        initNetworkType()
        startNetworkMonitor()

        createDownloadTask(url)
        // #endif
    }

    /**
     * 创建下载任务
     */
    function createDownloadTask(url: string): void {
        try {
            downloadTask = plus.downloader.createDownload(
                url,
                { filename: DOWNLOAD_CONFIG.FILE_PATH },
                handleDownloadComplete
            )

            if (!downloadTask) {
                throw new Error('创建下载任务失败')
            }

            // 创建状态变化处理器
            stateChangeHandler = handleDownloadStateChanged
            downloadTask.addEventListener('statechanged', stateChangeHandler)
            downloadTask.start()
        } catch (error) {
            console.error('创建下载任务失败:', error)
            downloadTask = null
            handleDownloadFail(t('mine.p28') || '创建下载任务失败')
        }
    }

    /**
     * 验证 URL 格式
     */
    function isValidUrl(url: string): boolean {
        try {
            return /^https?:\/\/.+/.test(url)
        } catch {
            return false
        }
    }

    /**
     * 处理下载完成回调
     */
    function handleDownloadComplete(download: PlusDownloaderDownload, status: number): void {
        const isSuccess = status === HttpStatus.OK || status === HttpStatus.PARTIAL_CONTENT

        if (isSuccess) {
            console.log('下载成功，准备安装')
            clearCache()
            stopNetworkMonitor()
            installWgt(download.filename)
        } else {
            console.error('下载失败，状态码:', status)
            retryDownload()
        }
    }

    /**
     * 处理下载状态变化
     */
    function handleDownloadStateChanged(event: DownloadStateEvent): void {
        if (event.state === DownloadState.DOWNLOADING && event.totalSize > 0) {
            const percent = Math.min(100, Math.floor((event.downloadedSize / event.totalSize) * 100))
            const progressText = `${t('mine.p29')} ${percent}%`
            progress.update(percent, progressText)
            saveCache(percent)
        }
    }

    /**
     * 重试下载
     */
    function retryDownload(): void {
        if (retryCount >= DOWNLOAD_CONFIG.MAX_RETRY) {
            console.error(`下载失败，已重试 ${retryCount} 次`)
            handleDownloadFail(t('mine.p28') || '下载失败')
            return
        }

        retryCount++
        console.log(`下载失败，${DOWNLOAD_CONFIG.RETRY_DELAY / 1000}秒后重试 (${retryCount}/${DOWNLOAD_CONFIG.MAX_RETRY})`)

        cleanupDownloadTask()

        setTimeout(() => {
            if (downloadUrl) {
                createDownloadTask(downloadUrl)
            }
        }, DOWNLOAD_CONFIG.RETRY_DELAY)
    }

    /**
     * 初始化网络类型
     */
    function initNetworkType(): void {
        uni.getNetworkType({
            success: (res) => {
                console.log('当前网络类型:', res.networkType)
            },
            fail: (error) => {
                console.warn('获取网络类型失败:', error)
            }
        })
    }

    // ================== 网络处理 ==================

    /**
     * 启动网络监听
     */
    function startNetworkMonitor(): void {
        // #ifdef APP-PLUS
        if (networkListener) {
            console.warn('网络监听已存在')
            return
        }

        networkListener = (res: any) => {
            if (!downloadTask || !updating.value) {
                return
            }

            if (!res.isConnected) {
                // 网络断开，暂停下载
                pauseDownload()
                return
            }

            // 网络恢复，继续下载
            resumeDownload()
        }

        uni.onNetworkStatusChange(networkListener)
        // #endif
    }

    /**
     * 暂停下载
     */
    function pauseDownload(): void {
        if (!downloadTask) return

        try {
            if (typeof downloadTask.pause === 'function') {
                downloadTask.pause()
            }
        } catch (error) {
            console.error('暂停下载失败:', error)
        }
    }

    /**
     * 恢复下载
     */
    function resumeDownload(): void {
        if (!downloadTask) return

        try {
            if (typeof downloadTask.resume === 'function') {
                downloadTask.resume()
            } else if (typeof downloadTask.start === 'function') {
                downloadTask.start()
            }
        } catch (error) {
            console.error('恢复下载失败，尝试重新开始:', error)
            // 失败时尝试重新开始
            try {
                if (downloadTask.start) {
                    downloadTask.start()
                }
            } catch (e2) {
                console.error('重新开始下载也失败:', e2)
            }
        }
    }

    /**
     * 停止网络监听
     */
    function stopNetworkMonitor(): void {
        if (networkListener) {
            uni.offNetworkStatusChange(networkListener)
            networkListener = null
        }
    }

    // ================== 安装 ==================

    /**
     * 安装 wgt 更新包
     */
    function installWgt(path: string): void {
        // #ifdef APP-PLUS
        try {
            plus.runtime.install(
                path,
                { force: false },
                () => {
                    // 安装成功
                    progress.hide()
                    updating.value = false
                    uni.showModal({
                        title: t('mine.p37'),
                        content: t('mine.p38'),
                        showCancel: false,
                        success: () => {
                            plus.runtime.restart()
                        }
                    })
                },
                (error) => {
                    // 安装失败
                    console.error('安装失败:', error)
                    handleDownloadFail(t('mine.p33'))
                }
            )
        } catch (error) {
            console.error('安装异常:', error)
            handleDownloadFail(t('mine.p33'))
        }
        // #endif
    }

    // ================== 缓存管理 ==================

    /**
     * 保存下载缓存
     */
    function saveCache(progressPercent: number): void {
        const cache: DownloadCache = {
            url: downloadUrl,
            progress: progressPercent,
            time: Date.now()
        }
        setStorageSync(STORAGE_KEYS.DOWNLOAD_CACHE, cache)
    }

    /**
     * 清除下载缓存
     */
    function clearCache(): void {
        removeStorageSync(STORAGE_KEYS.DOWNLOAD_CACHE)
    }

    // ================== 错误处理 ==================

    /**
     * 处理下载失败
     */
    function handleDownloadFail(msg: string): void {
        progress.hide()
        updating.value = false
        retryCount = 0
        stopNetworkMonitor()
        cleanupDownloadTask()
        showToast(msg)
    }

    /**
     * 清理下载任务
     */
    function cleanupDownloadTask(): void {
        if (!downloadTask) return

        try {
            // 移除事件监听
            if (stateChangeHandler && downloadTask.removeEventListener) {
                downloadTask.removeEventListener('statechanged', stateChangeHandler)
            }

            // 中止下载
            downloadTask.abort()
        } catch (error) {
            console.warn('清理下载任务失败:', error)
        } finally {
            downloadTask = null
            stateChangeHandler = null
        }
    }

    /**
     * 取消更新
     */
    function cancelUpdate(): void {
        if (!updating.value) {
            console.warn('当前没有正在进行的更新')
            return
        }

        console.log('用户取消更新')
        handleDownloadFail(t('mine.p39') || '已取消更新')
    }

    // ================== 生命周期 ==================

    onUnmounted(() => {
        console.log('useAppUpdate 组件卸载，清理资源')
        stopNetworkMonitor()
        cleanupDownloadTask()
        retryCount = 0
    })

    return {
        checkUpdate,
        cancelUpdate,
        checking,
        updating
    }
}
