/**
 * 地址数据加载器 - 支持缓存和版本控制
 * 优化90M+地址JSON文件的加载性能
 */
import IndexedDBHelper from '@/common/IndexedDBHelper.js';

class AddressDataLoader {
    constructor() {
        this.dbHelper = null;
        this.dbName = 'AddressDataDB';
        this.storeName = 'addressData';
        this.cacheKey = 'address_data_cache';
        this.versionKey = 'address_data_version';
        this.cacheExpireDays = 7; // 缓存有效期7天
        this.isInitialized = false;
    }

    /**
     * 初始化数据库
     */
    async init() {
        if (this.isInitialized && this.dbHelper) {
            return;
        }

        try {
            this.dbHelper = new IndexedDBHelper(this.dbName, 1);
            await this.dbHelper.openDB([{
                name: this.storeName,
                keyPath: 'key',
                indexes: [
                    { name: 'version', key: 'version', unique: false },
                    { name: 'updateTime', key: 'updateTime', unique: false }
                ]
            }]);
            this.isInitialized = true;
            console.log('✅ 地址数据加载器初始化成功');
        } catch (error) {
            console.error('❌ 地址数据加载器初始化失败:', error);
            // 降级到 uni.storage
            this.isInitialized = true;
        }
    }

    /**
     * 获取缓存版本号
     */
    async getCacheVersion() {
        try {
            const cached = await this.dbHelper?.get(this.storeName, this.versionKey);
            return cached?.version || null;
        } catch (e) {
            // 降级方案：从 uni.storage 读取
            return uni.getStorageSync(this.versionKey) || null;
        }
    }

    /**
     * 保存版本号
     */
    async saveVersion(version) {
        try {
            if (this.dbHelper) {
                const versionData = {
                    key: this.versionKey,
                    version: version,
                    updateTime: Date.now()
                };
                // 先尝试获取，如果不存在则添加，存在则更新
                try {
                    const existing = await this.dbHelper.get(this.storeName, this.versionKey);
                    if (existing) {
                        await this.dbHelper.update(this.storeName, versionData);
                    } else {
                        await this.dbHelper.add(this.storeName, versionData);
                    }
                } catch (e) {
                    // 如果获取失败，尝试直接添加
                    await this.dbHelper.add(this.storeName, versionData);
                }
            }
        } catch (e) {
            // 降级方案：保存到 uni.storage
            uni.setStorageSync(this.versionKey, version);
        }
    }

    /**
     * 从缓存获取数据
     */
    async getCachedData() {
        try {
            if (this.dbHelper) {
                const cached = await this.dbHelper.get(this.storeName, this.cacheKey);
                if (cached && cached.data) {
                    // 检查缓存是否过期
                    const updateTime = cached.updateTime || 0;
                    const expireTime = this.cacheExpireDays * 24 * 60 * 60 * 1000;
                    if (Date.now() - updateTime < expireTime) {
                        console.log('✅ 从 IndexedDB 缓存加载地址数据');
                        return cached.data;
                    } else {
                        console.log('⚠️ 缓存已过期，需要重新加载');
                    }
                }
            }
        } catch (e) {
            console.warn('从 IndexedDB 读取缓存失败，尝试 uni.storage:', e);
        }

        // 降级方案：从 uni.storage 读取
        try {
            const cached = uni.getStorageSync(this.cacheKey);
            if (cached && cached.data) {
                const updateTime = cached.updateTime || 0;
                const expireTime = this.cacheExpireDays * 24 * 60 * 60 * 1000;
                if (Date.now() - updateTime < expireTime) {
                    console.log('✅ 从 uni.storage 缓存加载地址数据');
                    return cached.data;
                }
            }
        } catch (e) {
            console.warn('从 uni.storage 读取缓存失败:', e);
        }

        return null;
    }

    /**
     * 保存数据到缓存
     */
    async saveToCache(data) {
        const cacheData = {
            key: this.cacheKey,
            data: data,
            updateTime: Date.now()
        };

        try {
            if (this.dbHelper) {
                // 先尝试获取，如果不存在则添加，存在则更新
                try {
                    const existing = await this.dbHelper.get(this.storeName, this.cacheKey);
                    if (existing) {
                        await this.dbHelper.update(this.storeName, cacheData);
                    } else {
                        await this.dbHelper.add(this.storeName, cacheData);
                    }
                    console.log('✅ 地址数据已保存到 IndexedDB');
                } catch (e) {
                    // 如果获取失败，尝试直接添加
                    await this.dbHelper.add(this.storeName, cacheData);
                    console.log('✅ 地址数据已保存到 IndexedDB');
                }
                return;
            }
        } catch (e) {
            console.warn('保存到 IndexedDB 失败，降级到 uni.storage:', e);
        }

        // 降级方案：保存到 uni.storage
        try {
            uni.setStorageSync(this.cacheKey, cacheData);
            console.log('✅ 地址数据已保存到 uni.storage');
        } catch (e) {
            console.error('❌ 保存缓存失败，可能超出存储限制:', e);
            // 如果存储空间不足，尝试清理旧数据
            if (e.errMsg?.includes('exceed')) {
                await this.clearOldCache();
                // 重试保存
                try {
                    uni.setStorageSync(this.cacheKey, cacheData);
                } catch (e2) {
                    console.error('❌ 重试保存仍然失败:', e2);
                }
            }
        }
    }

    /**
     * 清理过期缓存
     */
    async clearOldCache() {
        try {
            if (this.dbHelper) {
                await this.dbHelper.delete(this.storeName, this.cacheKey);
            }
            uni.removeStorageSync(this.cacheKey);
            console.log('✅ 已清理旧缓存');
        } catch (e) {
            console.warn('清理缓存失败:', e);
        }
    }

    /**
     * 从服务器获取数据版本号（如果服务器支持）
     */
    async fetchRemoteVersion() {
        try {
            // 如果服务器提供版本接口，可以在这里实现
            // const res = await uni.request({
            //     url: 'http://124.243.245.42/ks_cms/address_version.json',
            //     method: 'GET'
            // });
            // return res.data?.version || null;
            return null;
        } catch (e) {
            return null;
        }
    }

    /**
     * 从服务器加载地址数据
     */
    async fetchRemoteData(url, onProgress) {
        return new Promise((resolve, reject) => {
            console.log('📥 开始从服务器加载地址数据...');
            const startTime = Date.now();

            uni.request({
                url: url,
                method: 'GET',
                timeout: 300000, // 5分钟超时
                success: (res) => {
                    const endTime = Date.now();
                    const duration = ((endTime - startTime) / 1000).toFixed(2);
                    console.log(`✅ 地址数据加载完成，耗时 ${duration} 秒`);

                    if (res.statusCode === 200) {
                        // 如果返回的是字符串，尝试解析JSON
                        let data = res.data;
                        if (typeof data === 'string') {
                            try {
                                data = JSON.parse(data);
                            } catch (e) {
                                reject(new Error('JSON解析失败: ' + e.message));
                                return;
                            }
                        }
                        resolve(data);
                    } else {
                        reject(new Error(`请求失败，状态码: ${res.statusCode}`));
                    }
                },
                fail: (err) => {
                    console.error('❌ 地址数据加载失败:', err);
                    reject(err);
                }
            });

            // 注意：uni.request 不支持进度回调，如果需要进度提示，可以考虑：
            // 1. 使用流式请求（如果服务器支持）
            // 2. 显示固定加载提示
            if (onProgress) {
                onProgress({ loaded: 0, total: 0, percent: 0 });
            }
        });
    }

    /**
     * 加载地址数据（带缓存）
     * @param {string} url - 地址数据URL
     * @param {boolean} forceRefresh - 是否强制刷新
     * @param {Function} onProgress - 进度回调
     */
    async loadAddressData(url = 'http://124.243.245.42/ks_cms/address.json', forceRefresh = false, onProgress = null) {
        // 初始化数据库
        await this.init();

        // 如果不是强制刷新，先尝试从缓存加载
        if (!forceRefresh) {
            const cachedData = await this.getCachedData();
            if (cachedData) {
                return cachedData;
            }
        }

        // 检查版本（如果服务器支持版本控制）
        const remoteVersion = await this.fetchRemoteVersion();
        if (remoteVersion) {
            const cachedVersion = await this.getCacheVersion();
            if (cachedVersion === remoteVersion && !forceRefresh) {
                const cachedData = await this.getCachedData();
                if (cachedData) {
                    console.log('✅ 使用缓存数据（版本匹配）');
                    return cachedData;
                }
            }
        }

        // 显示加载提示
        uni.showLoading({
            title: '正在加载地址数据...',
            mask: true
        });

        try {
            // 从服务器加载数据
            const data = await this.fetchRemoteData(url, onProgress);

            // 保存到缓存
            await this.saveToCache(data);

            // 保存版本号
            if (remoteVersion) {
                await this.saveVersion(remoteVersion);
            }

            return data;
        } catch (error) {
            console.error('❌ 加载地址数据失败:', error);
            
            // 如果加载失败，尝试使用缓存数据（即使已过期）
            if (!forceRefresh) {
                try {
                    const cachedData = await this.getCachedData();
                    if (cachedData) {
                        console.log('⚠️ 使用过期缓存数据');
                        uni.showToast({
                            title: '使用缓存数据',
                            icon: 'none',
                            duration: 2000
                        });
                        return cachedData;
                    }
                } catch (e) {
                    console.warn('获取缓存数据失败:', e);
                }
            }

            throw error;
        } finally {
            uni.hideLoading();
        }
    }

    /**
     * 清除所有缓存
     */
    async clearCache() {
        await this.init();
        await this.clearOldCache();
        await this.saveVersion(null);
        console.log('✅ 已清除所有地址数据缓存');
    }
}

// 单例模式
const addressDataLoader = new AddressDataLoader();

export default addressDataLoader;

