import { HttpUtil } from './HttpUtil';
import { StorageManager } from './StorageManager';
import { WxSDK } from './WxSDK';
import { API_ENDPOINTS, API_TIMEOUT } from '../config/ApiConfig';
import { ApiEnvelope, WxLoginData, GameData, NextLevelData } from '../types/ApiTypes';

/**
 * 认证管理器
 * 单例模式，负责微信登录和 JWT token 管理
 */
export class AuthManager {
    private static _instance: AuthManager | null = null;

    private _userId: string = '';
    private _isLoggedIn: boolean = false;
    /** 服务端返回的已完成关卡数量，用于称号体系计算 */
    private _completedLevelCount: number = 0;
    /** game-data 返回的下一关数据，供 PageLoading 传给 LevelDataManager */
    private _nextLevel: NextLevelData | null = null;

    static get instance(): AuthManager {
        if (!this._instance) {
            this._instance = new AuthManager();
        }
        return this._instance;
    }

    private constructor() {}

    get isLoggedIn(): boolean {
        return this._isLoggedIn;
    }

    get userId(): string {
        return this._userId;
    }

    get completedLevelCount(): number {
        return this._completedLevelCount;
    }

    /** 获取 game-data 返回的下一关数据 */
    get nextLevel(): NextLevelData | null {
        return this._nextLevel;
    }

    addCompletedLevelCount(delta: number = 1): void {
        this._completedLevelCount = Math.max(0, this._completedLevelCount + delta);
    }

    /**
     * 初始化认证：尝试恢复 token 或执行微信登录
     */
    async initialize(): Promise<boolean> {
        const savedToken = StorageManager.getToken();
        if (savedToken) {
            HttpUtil.setAuthToken(savedToken);
            try {
                const valid = await this.validateToken();
                if (valid) {
                    console.log('[AuthManager] Token 恢复成功');
                    return true;
                }
            } catch {
                console.warn('[AuthManager] 本地 token 无效，重新登录');
            }
        }

        return this.wxLogin();
    }

    private async wxLogin(): Promise<boolean> {
        try {
            let code: string;

            if (WxSDK.isWechat()) {
                code = await WxSDK.login();
            } else {
                console.warn('[AuthManager] 非微信环境，使用开发模式 mock code');
                code = 'dev_mock_code';
            }

            const response = await HttpUtil.post<ApiEnvelope<WxLoginData>>(
                API_ENDPOINTS.WX_LOGIN,
                { code },
                API_TIMEOUT.DEFAULT
            );

            if (!response.success || !response.data) {
                console.error('[AuthManager] 登录失败:', response.message);
                return false;
            }

            const { token, user } = response.data;
            HttpUtil.setAuthToken(token);
            StorageManager.setToken(token);

            this._userId = user.id;
            this._isLoggedIn = true;

            // 登录响应中 stamina 是原始数值（不含实时恢复），先存储默认体力
            // 后续通过 game-data 接口获取完整 StaminaInfo
            console.log(`[AuthManager] 登录成功，用户: ${user.id}，体力: ${user.stamina}`);

            // 获取通关进度和完整体力信息
            await this.fetchGameData();

            return true;
        } catch (err) {
            console.error('[AuthManager] 登录异常:', err);
            return false;
        }
    }

    private async validateToken(): Promise<boolean> {
        const gameData = await this._fetchGameData();
        if (!gameData) return false;

        this._userId = gameData.user.id;
        this._isLoggedIn = true;
        StorageManager.setStamina(gameData.user.stamina);
        this._completedLevelCount = gameData.completedLevelCount;
        this._nextLevel = gameData.nextLevel;

        console.log(`[AuthManager] Token 验证成功，体力: ${gameData.user.stamina.current}/${gameData.user.stamina.max}，已完成: ${this._completedLevelCount} 关`);
        return true;
    }

    /**
     * 登录成功后获取游戏数据（体力 + 通关进度 + 下一关）
     */
    private async fetchGameData(): Promise<void> {
        const gameData = await this._fetchGameData();
        if (gameData) {
            this._completedLevelCount = gameData.completedLevelCount;
            this._nextLevel = gameData.nextLevel;
            StorageManager.setStamina(gameData.user.stamina);
        }
    }

    /**
     * 从服务端获取游戏数据（共用方法）
     */
    private async _fetchGameData(): Promise<GameData | null> {
        try {
            const response = await HttpUtil.get<ApiEnvelope<GameData>>(
                API_ENDPOINTS.USER_GAME_DATA,
                API_TIMEOUT.SHORT
            );
            return (response.success && response.data) ? response.data : null;
        } catch {
            console.warn('[AuthManager] 获取游戏数据失败');
            return null;
        }
    }
}
