import { sys } from 'cc';
import { StaminaInfo } from '../types/ApiTypes';

/**
 * 用户进度数据结构
 */
interface UserProgress {
    /** 当前关卡索引（0-based） */
    currentLevelIndex: number;
    /** 已通关的最高关卡索引 */
    maxUnlockedLevelIndex: number;
}

/**
 * 用户信息结构
 */
interface UserInfo {
    avatarUrl: string;
    nickName: string;
}

/**
 * 本地存储管理器
 * 统一管理用户数据的本地持久化存储
 */
export class StorageManager {
    /** 体力值存储键 */
    private static readonly KEY_STAMINA = 'game_stamina';

    /** 用户进度存储键 */
    private static readonly KEY_PROGRESS = 'game_progress';

    /** 认证 token 存储键 */
    private static readonly KEY_TOKEN = 'auth_token';

    /** 用户信息存储键 */
    private static readonly KEY_USER_INFO = 'user_info';

    /** 默认体力值 */
    private static readonly DEFAULT_STAMINA: StaminaInfo = {
        current: 50,
        max: 50,
        nextRecoverAt: null,
    };

    /** 默认进度 */
    private static readonly DEFAULT_PROGRESS: UserProgress = {
        currentLevelIndex: 0,
        maxUnlockedLevelIndex: 0
    };

    /** 进度缓存（避免重复读取 localStorage） */
    private static _progressCache: UserProgress | null = null;

    /** 体力缓存（避免重复 JSON 解析） */
    private static _staminaCache: StaminaInfo | null = null;

    // ==================== 体力值管理 ====================

    /**
     * 获取当前体力信息（带内存缓存，避免重复 JSON 解析）
     */
    static getStamina(): StaminaInfo {
        if (StorageManager._staminaCache) {
            return { ...StorageManager._staminaCache };
        }

        const stored = sys.localStorage.getItem(StorageManager.KEY_STAMINA);
        if (stored === null || stored === '') {
            StorageManager.setStamina(StorageManager.DEFAULT_STAMINA);
            return { ...StorageManager.DEFAULT_STAMINA };
        }
        try {
            const stamina = JSON.parse(stored) as StaminaInfo;
            if (typeof stamina.current !== 'number' || typeof stamina.max !== 'number') {
                StorageManager.setStamina(StorageManager.DEFAULT_STAMINA);
                return { ...StorageManager.DEFAULT_STAMINA };
            }
            StorageManager._staminaCache = stamina;
            return { ...stamina };
        } catch {
            StorageManager.setStamina(StorageManager.DEFAULT_STAMINA);
            return { ...StorageManager.DEFAULT_STAMINA };
        }
    }

    /**
     * 设置体力信息（同时更新缓存）
     */
    static setStamina(stamina: StaminaInfo): void {
        StorageManager._staminaCache = stamina;
        sys.localStorage.setItem(StorageManager.KEY_STAMINA, JSON.stringify(stamina));
        console.log(`[StorageManager] 体力已更新: ${stamina.current}/${stamina.max}`);
    }

    /**
     * 检查是否有足够的体力
     */
    static hasStamina(): boolean {
        return StorageManager.getStamina().current > 0;
    }

    // ==================== 认证 Token 管理 ====================

    /**
     * 获取认证 token
     */
    static getToken(): string | null {
        const token = sys.localStorage.getItem(StorageManager.KEY_TOKEN);
        return (token === null || token === '') ? null : token;
    }

    /**
     * 设置认证 token
     */
    static setToken(token: string): void {
        sys.localStorage.setItem(StorageManager.KEY_TOKEN, token);
        console.log('[StorageManager] Token 已保存');
    }

    /**
     * 清除认证 token
     */
    static clearToken(): void {
        sys.localStorage.removeItem(StorageManager.KEY_TOKEN);
        console.log('[StorageManager] Token 已清除');
    }

    // ==================== 关卡进度管理 ====================

    /**
     * 获取用户进度数据（带缓存）
     * @returns 用户进度对象的副本
     */
    private static _getProgress(): UserProgress {
        // 返回缓存副本
        if (StorageManager._progressCache !== null) {
            return { ...StorageManager._progressCache };
        }

        const stored = sys.localStorage.getItem(StorageManager.KEY_PROGRESS);
        if (stored === null || stored === '') {
            // 新用户，返回默认进度
            StorageManager._progressCache = { ...StorageManager.DEFAULT_PROGRESS };
            return { ...StorageManager._progressCache };
        }

        try {
            const progress = JSON.parse(stored) as UserProgress;
            // 验证数据有效性
            if (typeof progress.currentLevelIndex !== 'number' ||
                typeof progress.maxUnlockedLevelIndex !== 'number' ||
                progress.currentLevelIndex < 0 ||
                progress.maxUnlockedLevelIndex < 0) {
                console.warn('[StorageManager] 进度数据无效，使用默认值');
                StorageManager._progressCache = { ...StorageManager.DEFAULT_PROGRESS };
            } else {
                StorageManager._progressCache = progress;
            }
            return { ...StorageManager._progressCache };
        } catch (e) {
            console.warn('[StorageManager] 解析进度数据失败，使用默认值');
            StorageManager._progressCache = { ...StorageManager.DEFAULT_PROGRESS };
            return { ...StorageManager._progressCache };
        }
    }

    /**
     * 保存用户进度数据
     * @param progress 进度对象
     */
    private static _saveProgress(progress: UserProgress): void {
        StorageManager._progressCache = progress;
        sys.localStorage.setItem(StorageManager.KEY_PROGRESS, JSON.stringify(progress));
    }

    /**
     * 获取当前关卡索引
     * @returns 当前关卡索引（0-based）
     */
    static getCurrentLevelIndex(): number {
        return StorageManager._getProgress().currentLevelIndex;
    }

    /**
     * 设置当前关卡索引
     * @param index 关卡索引
     */
    static setCurrentLevelIndex(index: number): void {
        if (index < 0) {
            console.warn('[StorageManager] 关卡索引不能为负数');
            return;
        }
        const progress = StorageManager._getProgress();
        progress.currentLevelIndex = index;
        StorageManager._saveProgress(progress);
        console.log(`[StorageManager] 当前关卡已更新: ${progress.currentLevelIndex}`);
    }

    /**
     * 获取已解锁的最高关卡索引
     * @returns 最高关卡索引（0-based）
     */
    static getMaxUnlockedLevelIndex(): number {
        return StorageManager._getProgress().maxUnlockedLevelIndex;
    }

    /**
     * 通关后更新进度
     * 当玩家通关第 N 关后，设置当前关卡为 N+1，解锁关卡更新为 max(N, 已解锁)
     * @param completedLevelIndex 刚通关的关卡索引
     */
    static onLevelCompleted(completedLevelIndex: number): void {
        if (completedLevelIndex < 0) {
            console.warn('[StorageManager] 通关关卡索引不能为负数');
            return;
        }
        const progress = StorageManager._getProgress();
        const nextLevelIndex = completedLevelIndex + 1;

        // 更新当前关卡为下一关
        progress.currentLevelIndex = nextLevelIndex;

        // 更新最高解锁关卡
        progress.maxUnlockedLevelIndex = Math.max(progress.maxUnlockedLevelIndex, completedLevelIndex);

        StorageManager._saveProgress(progress);
        console.log(`[StorageManager] 通关第 ${completedLevelIndex + 1} 关，下一关: ${nextLevelIndex + 1}`);
    }

    /**
     * 检查指定关卡是否已解锁
     * @param levelIndex 关卡索引
     * @returns 是否已解锁
     */
    static isLevelUnlocked(levelIndex: number): boolean {
        const progress = StorageManager._getProgress();
        return levelIndex <= progress.maxUnlockedLevelIndex;
    }

    /**
     * 重置所有进度
     */
    static resetProgress(): void {
        StorageManager._progressCache = null;
        sys.localStorage.removeItem(StorageManager.KEY_PROGRESS);
        console.log('[StorageManager] 进度已重置');
    }

    /**
     * 重置所有数据（体力 + 进度）
     */
    static resetAll(): void {
        StorageManager.setStamina(StorageManager.DEFAULT_STAMINA);
        StorageManager.resetProgress();
        StorageManager.clearToken();
        StorageManager.clearUserInfo();
        console.log('[StorageManager] 所有数据已重置');
    }

    // ==================== 用户信息管理 ====================

    /**
     * 保存用户信息（头像、昵称）
     * @param userInfo 用户信息对象
     */
    static setUserInfo(userInfo: UserInfo): void {
        sys.localStorage.setItem(StorageManager.KEY_USER_INFO, JSON.stringify(userInfo));
        console.log('[StorageManager] 用户信息已保存');
    }

    /**
     * 获取本地缓存的用户信息
     * @returns 用户信息对象或 null
     */
    static getUserInfo(): UserInfo | null {
        const data = sys.localStorage.getItem(StorageManager.KEY_USER_INFO);
        if (!data) return null;
        try {
            return JSON.parse(data) as UserInfo;
        } catch {
            return null;
        }
    }

    /**
     * 清除用户信息缓存
     */
    static clearUserInfo(): void {
        sys.localStorage.removeItem(StorageManager.KEY_USER_INFO);
        console.log('[StorageManager] 用户信息已清除');
    }
}
