import { _decorator, Node, EditBox, instantiate, Vec3, Button, Label, Sprite, SpriteFrame, AudioClip, AudioSource, UITransform, Prefab } from 'cc';
import { BaseView } from 'db://assets/scripts/core/BaseView';
import { ViewManager } from 'db://assets/scripts/core/ViewManager';
import { StorageManager } from 'db://assets/scripts/utils/StorageManager';
import { StaminaManager } from 'db://assets/scripts/utils/StaminaManager';
import { WxSDK } from 'db://assets/scripts/utils/WxSDK';
import { LevelDataManager } from 'db://assets/scripts/utils/LevelDataManager';
import { RuntimeLevelConfig } from 'db://assets/scripts/types/LevelTypes';
import { ToastManager } from 'db://assets/scripts/utils/ToastManager';
import { ShareManager } from 'db://assets/scripts/utils/ShareManager';
import { PassModal } from 'db://assets/prefabs/PassModal';
import { StaminaInfo } from 'db://assets/scripts/types/ApiTypes';
const { ccclass, property } = _decorator;

/**
 * 关卡页面组件
 * 继承 BaseView，实现页面生命周期
 */
@ccclass('PageLevel')
export class PageLevel extends BaseView {
    /** 静态常量：零位置 */
    private static readonly ZERO_POS = new Vec3(0, 0, 0);

    /** 默认体力上限，服务端未返回 max 时使用 */
    private static readonly DEFAULT_STAMINA_MAX = 50;

    // ========== 节点引用 ==========
    @property(Node)
    inputLayout: Node | null = null;

    @property(Node)
    submitButton: Node | null = null;

    @property(Node)
    inputTemplate: Node | null = null;

    @property(Node)
    actionNode: Node | null = null;

    @property(Node)
    iconSetting: Node | null = null;

    @property(Node)
    tipsLayout: Node | null = null;

    @property(Node)
    mainImage: Node | null = null;

    @property(Node)
    mainImage2: Node | null = null;

    @property(Label)
    image1DescLabel: Label | null = null;

    @property(Label)
    image2DescLabel: Label | null = null;

    @property(Label)
    punchlineLabel: Label | null = null;

    @property(Node)
    tipsItem1: Node | null = null;

    @property(Node)
    tipsItem2: Node | null = null;

    @property(Node)
    tipsItem3: Node | null = null;

    @property(Node)
    unLockTipsBtn: Node | null = null;

    @property(Node)
    addTimeBtn: Node | null = null;

    @property(Label)
    clockLabel: Label | null = null;

    /** 体力值显示标签（prefab 中序列化名为 liveLabel，保持兼容） */
    @property(Label)
    liveLabel: Label | null = null;

    // ========== 配置属性 ==========
    @property({
        min: 0,
        tooltip: '当前关卡索引'
    })
    currentLevelIndex: number = 0;

    @property(AudioClip)
    clickAudio: AudioClip | null = null;

    @property(AudioClip)
    successAudio: AudioClip | null = null;

    @property(AudioClip)
    failAudio: AudioClip | null = null;

    @property(Prefab)
    passModalPrefab: Prefab | null = null;

    // ========== 内部状态 ==========
    /** 当前创建的输入框节点数组 */
    private _inputNodes: Node[] = [];

    /** 倒计时剩余秒数 */
    private _countdown: number = 60;

    /** 关卡开始时间戳（ms），用于准确计算耗时 */
    private _levelStartTime: number = 0;

    /** 倒计时是否结束 */
    private _isTimeUp: boolean = false;

    /** 当前关卡配置 */
    private _currentConfig: RuntimeLevelConfig | null = null;

    /** 是否正在切换关卡（防止重复提交） */
    private _isTransitioning: boolean = false;

    /** 是否正在解锁提示（防止双击重复触发） */
    private _isUnlocking: boolean = false;

    /** 下一个待解锁的线索序号（2 或 3），超过 3 表示全部已解锁 */
    private _nextClueIndex: number = 2;

    /** 通关弹窗实例 */
    private _passModalNode: Node | null = null;

    /** 是否处于分享挑战模式 */
    private _isShareMode: boolean = false;

    /** 体力恢复倒计时定时器 */
    private _staminaTimerId: ReturnType<typeof setInterval> | null = null;

    /**
     * 页面首次加载时调用
     */
    onViewLoad(): void {
        console.log('[PageLevel] onViewLoad');

        const params = this.getParams();
        this._isShareMode = params?.shareMode === true;

        if (this._isShareMode) {
            this.currentLevelIndex = 0;
            console.log('[PageLevel] 进入分享挑战模式');
        } else {
            // 根据关卡列表找到第一个未通关的关卡
            this.currentLevelIndex = LevelDataManager.instance.getFirstUncompletedIndex();
            StorageManager.setCurrentLevelIndex(this.currentLevelIndex);
            console.log(`[PageLevel] 进入第一个未通关关卡: 第 ${this.currentLevelIndex + 1} 关`);
        }
        this.updateStaminaLabel();
        this.initIconSetting();
        this.initUnlockButtons();
        this.initSubmitButton();

        // 异步加载关卡资源并调用进入关卡接口，完成后启动倒计时
        this._enterAndInitLevel().catch(err => {
            console.error('[PageLevel] 进入关卡失败:', err);
        });
    }

    /**
     * 页面每次显示时调用
     */
    onViewShow(): void {
        console.log('[PageLevel] onViewShow');
        this.updateStaminaLabel();
        this._startStaminaRecoverTimer();
    }

    /**
     * 页面隐藏时调用
     */
    onViewHide(): void {
        console.log('[PageLevel] onViewHide');
        this._stopStaminaRecoverTimer();
    }

    /**
     * 页面销毁时调用
     */
    onViewDestroy(): void {
        console.log('[PageLevel] onViewDestroy');
        this.clearInputNodes();
        this.stopCountdown();
        this._closePassModal();
        this._stopStaminaRecoverTimer();

        // 清理事件监听
        this.iconSetting?.off(Node.EventType.TOUCH_END, this.onIconSettingClick, this);
        this.unLockTipsBtn?.off(Node.EventType.TOUCH_END);
        this.addTimeBtn?.off(Node.EventType.TOUCH_END);
        this.submitButton?.off(Node.EventType.TOUCH_END, this.onSubmitAnswer, this);
    }

    /**
     * 进入关卡并初始化
     * 1. 加载关卡图片资源
     * 2. 调用进入关卡接口（消耗体力，获取答案和线索）
     * 3. 启动倒计时
     */
    private async _enterAndInitLevel(): Promise<void> {
        // 先加载关卡图片资源
        let config: RuntimeLevelConfig | null = null;

        if (this._isShareMode) {
            config = await ShareManager.instance.ensureShareLevelReady(this.currentLevelIndex);
        } else {
            config = LevelDataManager.instance.getLevelConfig(this.currentLevelIndex);
            if (!config) {
                console.log(`[PageLevel] 关卡 ${this.currentLevelIndex + 1} 资源未缓存，开始加载...`);
                config = await LevelDataManager.instance.ensureLevelReady(this.currentLevelIndex);
            }
        }

        if (!config) {
            console.warn(`[PageLevel] 没有找到关卡配置，索引: ${this.currentLevelIndex}`);
            return;
        }

        // 非分享模式下，调用进入关卡接口获取答案和线索
        if (!this._isShareMode) {
            const levelId = LevelDataManager.instance.getLevelId(this.currentLevelIndex);
            if (levelId) {
                const enterData = await StaminaManager.instance.enterLevel(levelId);
                if (!enterData) {
                    // 进入关卡失败（可能是体力不足）
                    const stamina = StaminaManager.instance.getStamina();
                    if (stamina.current <= 0) {
                        ToastManager.show('体力不足，请等待恢复');
                        this._startStaminaRecoverTimer();
                    } else {
                        ToastManager.show('进入关卡失败，请重试');
                    }
                    this.updateStaminaLabel();
                    return;
                }

                // 提示用户消耗体力
                ToastManager.show(`消耗1点体力，剩余 ${enterData.stamina.current}/${this._getStaminaMax(enterData.stamina)}`);

                // 用 enter 接口返回的数据更新关卡配置（填充答案和线索）
                LevelDataManager.instance.updateLevelDetails(
                    this.currentLevelIndex,
                    {
                        answer: enterData.answer,
                        hint1: enterData.hint1,
                        hint2: enterData.hint2,
                        hint3: enterData.hint3,
                    }
                );

                // 重新获取更新后的配置
                config = LevelDataManager.instance.getLevelConfig(this.currentLevelIndex);
                if (!config) {
                    console.error('[PageLevel] 更新关卡详情后获取配置失败');
                    return;
                }

                // 更新体力显示
                this.updateStaminaLabel();
            }
        }

        console.log(`[PageLevel] 初始化关卡 ${this.currentLevelIndex + 1}: ${config.name}`);
        this._applyLevelConfig(config);
        this.startCountdown();
    }

    /**
     * 应用关卡配置（通用初始化逻辑）
     */
    private _applyLevelConfig(config: RuntimeLevelConfig): void {
        this._currentConfig = config;

        // 重置关卡切换状态，允许再次提交
        this._isTransitioning = false;

        // 重置倒计时状态
        this._isTimeUp = false;
        this._countdown = 60;

        // 设置主图（图片1）
        this.setMainImage(config.spriteFrame1);

        // 设置图片2
        this.setMainImage2(config.spriteFrame2);

        // 设置图片描述
        this.setImageDescriptions(config.image1Description, config.image2Description);

        // 隐藏谐音梗说明（通关后才显示）
        this.setPunchline(null);

        // 设置线索1（默认解锁，如果有的话）
        if (config.clue1) {
            this.setClue(1, config.clue1);
        }

        // 重置线索解锁进度
        this._nextClueIndex = 2;

        // 线索2、3 保持显示，写入"待解锁"占位文案
        this.setClue(2, '待解锁');
        this.setClue(3, '待解锁');

        // 显示解锁按钮（单个统一按钮）
        this.showUnlockButton();

        // 根据答案长度创建单个输入框
        if (config.answer) {
            this.createSingleInput(config.answer.length);
        }

        // 更新倒计时显示
        this.updateClockLabel();

        // 预加载下一关图片（静默加载，不阻塞）
        if (this._isShareMode) {
            const nextIndex = this.currentLevelIndex + 1;
            if (nextIndex < ShareManager.instance.getShareLevelCount()) {
                ShareManager.instance.ensureShareLevelReady(nextIndex).catch(() => {});
            }
        } else {
            LevelDataManager.instance.preloadNextLevel(this.currentLevelIndex);
        }

        console.log(`[PageLevel] 初始化关卡 ${this.currentLevelIndex + 1}, 答案长度: ${config.answer?.length ?? 0}`);
    }

    /**
     * 创建单个输入框
     * @param answerLength 答案长度，用于设置 placeholder 和宽度
     */
    private createSingleInput(answerLength: number): void {
        if (!this.inputLayout || !this.inputTemplate) {
            console.error('[PageLevel] inputLayout 或 inputTemplate 未设置');
            return;
        }

        // 清理现有输入框
        this.clearInputNodes();

        // 隐藏模板节点
        this.inputTemplate.active = false;

        // 创建单个输入框
        const inputNode = instantiate(this.inputTemplate);
        inputNode.active = true;
        inputNode.name = 'singleInput';

        // 设置位置
        inputNode.setPosition(PageLevel.ZERO_POS);

        // 获取 EditBox 组件
        const editBox = inputNode.getComponent(EditBox);
        if (editBox) {
            // 设置 placeholder 提示
            editBox.placeholder = `(${answerLength}个字)`;

            // 设置最大长度为答案长度
            editBox.maxLength = answerLength;

            // 清空输入内容
            editBox.string = '';

            // 监听事件
            editBox.node.on(EditBox.EventType.TEXT_CHANGED, this.onInputTextChanged, this);
            editBox.node.on(EditBox.EventType.EDITING_DID_ENDED, this.onInputEditingEnded, this);
        }

        // 动态调整输入框宽度
        const uitransform = inputNode.getComponent(UITransform);
        let inputWidth = 200;
        if (uitransform) {
            // 每个字符约 60px，加上 padding
            inputWidth = Math.min(600, Math.max(200, answerLength * 60 + 40));
            uitransform.setContentSize(inputWidth, 100);
        }

        // 调整下划线宽度与输入框一致
        const underLine = inputNode.getChildByName('UnderLine');
        if (underLine) {
            const underLineTransform = underLine.getComponent(UITransform);
            if (underLineTransform) {
                underLineTransform.setContentSize(inputWidth, underLineTransform.height);
            }
        }

        this.inputLayout.addChild(inputNode);
        this._inputNodes.push(inputNode);

        console.log(`[PageLevel] 创建单个输入框，答案长度: ${answerLength}`);
    }

    /**
     * 清理所有输入框节点
     */
    private clearInputNodes(): void {
        for (const node of this._inputNodes) {
            if (node.isValid) {
                const editBox = node.getComponent(EditBox);
                if (editBox) {
                    editBox.node.off(EditBox.EventType.TEXT_CHANGED, this.onInputTextChanged, this);
                    editBox.node.off(EditBox.EventType.EDITING_DID_ENDED, this.onInputEditingEnded, this);
                }
                node.destroy();
            }
        }
        this._inputNodes = [];
    }

    /**
     * 获取所有输入框的值
     */
    getInputValues(): string[] {
        if (this._inputNodes.length === 0) return [];
        const editBox = this._inputNodes[0].getComponent(EditBox);
        const str = (editBox?.string ?? '').trim();
        return [str];
    }

    /**
     * 获取拼接后的答案字符串
     */
    getAnswer(): string {
        if (this._inputNodes.length === 0) return '';
        const editBox = this._inputNodes[0].getComponent(EditBox);
        return (editBox?.string ?? '').trim();
    }

    // ========== EditBox 事件回调 ==========

    /**
     * 输入框文本变化回调
     */
    private onInputTextChanged(_editBox: EditBox): void {
        console.log('[PageLevel] 输入内容变化');
    }

    /**
     * 输入框编辑结束回调
     */
    private onInputEditingEnded(_editBox: EditBox): void {
        console.log('[PageLevel] 输入编辑结束');
    }

    // ========== IconSetting 按钮相关 ==========

    /**
     * 初始化 IconSetting 按钮事件
     */
    private initIconSetting(): void {
        if (!this.iconSetting) {
            console.warn('[PageLevel] iconSetting 节点未设置');
            return;
        }

        const button = this.iconSetting.getComponent(Button);
        if (!button) {
            console.warn('[PageLevel] iconSetting 节点缺少 Button 组件');
            return;
        }

        this.iconSetting.on(Node.EventType.TOUCH_END, this.onIconSettingClick, this);
        console.log('[PageLevel] IconSetting 按钮事件已绑定');
    }

    /**
     * IconSetting 按钮点击回调
     */
    private onIconSettingClick(): void {
        console.log('[PageLevel] IconSetting 点击，返回主页');
        this.playClickSound();

        // 分享模式下栈中没有 PageHome，需要清除分享状态并直接打开首页
        if (this._isShareMode) {
            ShareManager.instance.clearShareMode();
            ViewManager.instance.replace('PageHome');
        } else {
            ViewManager.instance.back();
        }
    }

    // ========== 线索相关方法 ==========

    /**
     * 获取线索节点
     */
    private getTipsItem(index: number): Node | null {
        switch (index) {
            case 1: return this.tipsItem1;
            case 2: return this.tipsItem2;
            case 3: return this.tipsItem3;
            default: return null;
        }
    }

    /**
     * 设置线索内容
     */
    private setClue(index: number, content: string): void {
        const tipsItem = this.getTipsItem(index);
        if (!tipsItem) return;

        // 查找 TipsLabel 节点：Content -> TipsLabel
        const contentNode = tipsItem.getChildByName('Content');
        if (!contentNode) return;

        const tipsLabelNode = contentNode.getChildByName('TipsLabel');
        if (!tipsLabelNode) return;

        const label = tipsLabelNode.getComponent(Label);
        if (label) {
            label.string = `提示 ${index}: ${content}`;
            console.log(`[PageLevel] 设置线索${index}: ${content}`);
        }
    }

    /**
     * 显示线索
     */
    private showClue(index: number): void {
        const tipsItem = this.getTipsItem(index);
        if (tipsItem) {
            tipsItem.active = true;
            console.log(`[PageLevel] 显示线索${index}`);
        }
    }

    /**
     * 隐藏线索
     */
    private hideClue(index: number): void {
        const tipsItem = this.getTipsItem(index);
        if (tipsItem) {
            tipsItem.active = false;
            console.log(`[PageLevel] 隐藏线索${index}`);
        }
    }

    /**
     * 显示解锁按钮
     */
    private showUnlockButton(_index?: number): void {
        if (this.unLockTipsBtn) {
            this.unLockTipsBtn.active = true;
            console.log('[PageLevel] 显示解锁按钮');
        }
    }

    /**
     * 隐藏解锁按钮
     */
    private hideUnlockButton(_index?: number): void {
        if (this.unLockTipsBtn) {
            this.unLockTipsBtn.active = false;
            console.log('[PageLevel] 隐藏解锁按钮');
        }
    }

    /**
     * 初始化解锁按钮事件
     */
    private initUnlockButtons(): void {
        if (this.unLockTipsBtn) {
            this.unLockTipsBtn.on(Node.EventType.TOUCH_END, this.onUnlockClue, this);
        }

        if (this.addTimeBtn) {
            this.addTimeBtn.on(Node.EventType.TOUCH_END, this.onAddTime, this);
        }

        console.log('[PageLevel] 解锁按钮事件已绑定');
    }

    /**
     * 初始化提交按钮事件
     */
    private initSubmitButton(): void {
        if (!this.submitButton) {
            console.warn('[PageLevel] submitButton 节点未设置');
            return;
        }

        this.submitButton.on(Node.EventType.TOUCH_END, this.onSubmitAnswer, this);
        console.log('[PageLevel] 提交按钮事件已绑定');
    }

    /**
     * 点击解锁线索（顺序解锁：先线索2，再线索3；全部解锁后提示已解锁完毕）
     */
    private onUnlockClue(): void {
        // 全部已解锁，提示用户
        if (this._nextClueIndex > 3) {
            ToastManager.show('已解锁完毕');
            return;
        }

        if (!this._currentConfig) return;

        const index = this._nextClueIndex;
        const clueContent = index === 2 ? this._currentConfig.clue2 : this._currentConfig.clue3;
        if (!clueContent) {
            ToastManager.show('该提示暂未配置');
            return;
        }

        this.playClickSound();
        this.setClue(index, clueContent);

        // 推进到下一条待解锁线索
        this._nextClueIndex++;

        // 全部解锁完毕则隐藏按钮
        if (this._nextClueIndex > 3) {
            this.hideUnlockButton();
        }

        console.log(`[PageLevel] 解锁线索${index}`);
    }

    /**
     * 点击增加时间按钮（倒计时增加 60 秒）
     */
    private onAddTime(): void {
        if (this._isTimeUp) {
            ToastManager.show('时间已结束，无法增加');
            return;
        }

        this._countdown += 60;
        this.updateClockLabel();
        this.playClickSound();
        ToastManager.show('已成功增加60秒！');
        console.log(`[PageLevel] 增加60秒倒计时，当前剩余: ${this._countdown}s`);
    }

    // ========== 主图相关方法 ==========

    /**
     * 设置主图（图片1）
     */
    private setMainImage(spriteFrame: SpriteFrame | null): void {
        if (!this.mainImage) return;

        const sprite = this.mainImage.getComponent(Sprite);
        if (sprite && spriteFrame) {
            sprite.spriteFrame = spriteFrame;
            console.log('[PageLevel] 设置主图1');
        }
    }

    /**
     * 设置图片2
     */
    private setMainImage2(spriteFrame: SpriteFrame | null): void {
        if (!this.mainImage2) return;

        const sprite = this.mainImage2.getComponent(Sprite);
        if (sprite && spriteFrame) {
            sprite.spriteFrame = spriteFrame;
            console.log('[PageLevel] 设置主图2');
        }
    }

    /**
     * 设置图片描述文本
     */
    private setImageDescriptions(desc1: string | null, desc2: string | null): void {
        if (this.image1DescLabel) {
            this.image1DescLabel.string = desc1 ?? '';
        }
        if (this.image2DescLabel) {
            this.image2DescLabel.string = desc2 ?? '';
        }
    }

    /**
     * 设置谐音梗说明（通关后展示，未通关时传 null 隐藏）
     */
    private setPunchline(punchline: string | null): void {
        if (!this.punchlineLabel) return;

        if (punchline) {
            this.punchlineLabel.node.active = true;
            this.punchlineLabel.string = punchline;
        } else {
            this.punchlineLabel.node.active = false;
            this.punchlineLabel.string = '';
        }
    }

    // ========== 音效相关方法 ==========

    /**
     * 播放音效（通用方法）
     */
    private playSound(clip: AudioClip | null): void {
        if (!clip) return;
        const audioSource = this.node.getComponent(AudioSource);
        audioSource?.playOneShot(clip);
    }

    /**
     * 播放点击音效
     */
    private playClickSound(): void {
        this.playSound(this.clickAudio);
    }

    /**
     * 播放成功音效
     */
    private playSuccessSound(): void {
        this.playSound(this.successAudio);
    }

    /**
     * 播放失败音效
     */
    private playFailSound(): void {
        this.playSound(this.failAudio);
    }

    // ========== 倒计时相关方法 ==========

    /**
     * 开始倒计时
     */
    private startCountdown(): void {
        this._countdown = 60;
        this._isTimeUp = false;
        this._levelStartTime = Date.now();
        this.updateClockLabel();
        this.schedule(this.onCountdownTick, 1);
        console.log('[PageLevel] 开始倒计时 60 秒');
    }

    /**
     * 停止倒计时
     */
    private stopCountdown(): void {
        this.unschedule(this.onCountdownTick);
    }

    /**
     * 倒计时每秒回调
     */
    private onCountdownTick(): void {
        if (this._isTimeUp) return;

        this._countdown--;
        this.updateClockLabel();

        if (this._countdown <= 0) {
            this._isTimeUp = true;
            this.stopCountdown();
            this.onTimeUp();
        }
    }

    /**
     * 更新倒计时显示
     */
    private updateClockLabel(): void {
        if (this.clockLabel) {
            this.clockLabel.string = `${this._countdown}s`;
        }
    }

    /**
     * 倒计时结束
     */
    private onTimeUp(): void {
        console.log('[PageLevel] 倒计时结束！');
        this.playFailSound();
        // 可以在这里添加游戏结束逻辑
    }

    // ========== 体力值相关方法 ==========

    /** 上次显示的体力值，用于变更检测 */
    private _lastDisplayedStamina: number = -1;

    /** 上次显示的体力上限，用于变更检测 */
    private _lastDisplayedStaminaMax: number = -1;

    /**
     * 获取体力上限，服务端未返回时使用默认值兜底
     */
    private _getStaminaMax(stamina: StaminaInfo): number {
        return typeof stamina.max === 'number' ? stamina.max : PageLevel.DEFAULT_STAMINA_MAX;
    }

    /**
     * 更新体力值显示（仅值变化时更新 UI）
     */
    private updateStaminaLabel(): void {
        if (this.liveLabel) {
            const stamina = StaminaManager.instance.getStamina();
            const maxStamina = this._getStaminaMax(stamina);
            if (stamina.current !== this._lastDisplayedStamina || maxStamina !== this._lastDisplayedStaminaMax) {
                this.liveLabel.string = `${stamina.current}/${maxStamina}`;
                this._lastDisplayedStamina = stamina.current;
                this._lastDisplayedStaminaMax = maxStamina;
            }
        }
    }

    /**
     * 启动体力恢复倒计时 UI
     */
    private _startStaminaRecoverTimer(): void {
        this._stopStaminaRecoverTimer();

        const stamina = StaminaManager.instance.getStamina();
        const maxStamina = this._getStaminaMax(stamina);
        if (!stamina.nextRecoverAt || stamina.current >= maxStamina) {
            return;
        }

        const targetTime = new Date(stamina.nextRecoverAt).getTime();
        if (isNaN(targetTime)) return;

        this._staminaTimerId = setInterval(() => {
            if (targetTime - Date.now() > 0) return;

            // 恢复一点体力
            const currentStamina = StaminaManager.instance.getStamina();
            const currentMaxStamina = this._getStaminaMax(currentStamina);
            const newCurrent = Math.min(currentStamina.current + 1, currentMaxStamina);
            const newStamina: StaminaInfo = {
                ...currentStamina,
                max: currentMaxStamina,
                current: newCurrent,
                nextRecoverAt: newCurrent < currentMaxStamina
                    ? new Date(Date.now() + 10 * 60 * 1000).toISOString()
                    : null,
            };
            StaminaManager.instance.updateStamina(newStamina);
            this.updateStaminaLabel();

            this._stopStaminaRecoverTimer();

            if (newCurrent < currentStamina.max) {
                this._startStaminaRecoverTimer();
            }
        }, 1000);
    }

    /**
     * 停止体力恢复倒计时
     */
    private _stopStaminaRecoverTimer(): void {
        if (this._staminaTimerId !== null) {
            clearInterval(this._staminaTimerId);
            this._staminaTimerId = null;
        }
    }

    // ========== 答案提交与关卡切换 ==========

    /**
     * 提交答案
     */
    onSubmitAnswer(): void {
        if (!this._currentConfig) return;
        if (this._isTransitioning) return;

        const userAnswer = this.getAnswer();
        console.log(`[PageLevel] 提交答案: ${userAnswer}, 正确答案: ${this._currentConfig.answer}`);

        if (userAnswer === this._currentConfig.answer) {
            // 答案正确，只播放成功音效（不播放点击音效，避免重合）
            this.showSuccess();
        } else {
            // 答案错误
            this.showError();
        }
    }

    /**
     * 显示成功提示并上报通关
     */
    private async showSuccess(): Promise<void> {
        console.log('[PageLevel] 答案正确！');

        // 标记正在切换关卡，防止重复提交
        this._isTransitioning = true;

        // 停止倒计时
        this.stopCountdown();

        // 播放成功音效
        this.playSuccessSound();

        // 通关后展示谐音梗说明
        if (this._currentConfig?.punchline) {
            this.setPunchline(this._currentConfig.punchline);
        }

        const levelId = this._currentConfig?.id ?? '';
        const timeSpent = Math.max(0, Math.round((Date.now() - this._levelStartTime) / 1000));

        if (!this._isShareMode) {
            // 上报通关耗时
            const result = await StaminaManager.instance.completeLevel(levelId, timeSpent);
            if (result) {
                console.log(`[PageLevel] 通关上报成功，首次通关: ${result.firstClear}`);
            }
            // 标记关卡为已通关（本地缓存）
            LevelDataManager.instance.markLevelCompleted(this.currentLevelIndex);
        } else {
            // fire-and-forget: errors are logged inside reportLevelProgress
            void ShareManager.instance.reportLevelProgress(levelId, true, timeSpent);
        }

        // 显示通关弹窗
        this._showPassModal();
    }

    /**
     * 显示通关弹窗
     * 将弹窗添加到 Canvas 根节点下（而非 PageLevel 子节点）
     * 这样 Widget 可以正确对齐到全屏
     */
    private _showPassModal(): void {
        if (!this.passModalPrefab) {
            console.warn('[PageLevel] passModalPrefab 未设置');
            return;
        }

        // 如果弹窗已显示，不再重复创建
        if (this._passModalNode && this._passModalNode.isValid) {
            return;
        }

        // 实例化弹窗
        const modalNode = instantiate(this.passModalPrefab);
        modalNode.setPosition(PageLevel.ZERO_POS);
        modalNode.setSiblingIndex(PassModal.MODAL_Z_INDEX);

        // 找到 Canvas 根节点并添加弹窗
        const canvasNode = this.node.parent;
        if (canvasNode) {
            canvasNode.addChild(modalNode);
        } else {
            this.node.addChild(modalNode);
        }
        this._passModalNode = modalNode;

        // 获取 PassModal 组件并设置回调
        const passModal = modalNode.getComponent(PassModal);
        if (passModal) {
            passModal.setParams({ levelIndex: this.currentLevelIndex + 1 });
            passModal.setCallbacks({
                onNextLevel: () => {
                    this._closePassModal();
                    this.nextLevel();
                },
                onShare: () => {
                    // 分享后不关闭弹窗，用户可继续点击下一关
                    console.log('[PageLevel] 分享完成');
                }
            });
            // 手动调用 onViewLoad 和 onViewShow
            passModal.onViewLoad();
            passModal.onViewShow();
        }

        console.log('[PageLevel] 显示通关弹窗');
    }

    /**
     * 关闭通关弹窗
     */
    private _closePassModal(): void {
        if (this._passModalNode && this._passModalNode.isValid) {
            this._passModalNode.destroy();
            this._passModalNode = null;
            console.log('[PageLevel] 关闭通关弹窗');
        }
    }

    /**
     * 显示错误提示
     */
    private showError(): void {
        console.log('[PageLevel] 答案错误！');

        // 播放失败音效
        this.playFailSound();

        // 触发手机震动
        WxSDK.vibrateLong();

        // 显示 Toast 提示
        ToastManager.show('答案错误，再试试吧！');
    }

    /**
     * 进入下一关
     */
    private async nextLevel(): Promise<void> {
        // 标记当前关卡已通关
        if (!this._isShareMode) {
            StorageManager.onLevelCompleted(this.currentLevelIndex);
            LevelDataManager.instance.markLevelCompleted(this.currentLevelIndex);
        }

        // 查找下一个未通关的关卡
        if (this._isShareMode) {
            this.currentLevelIndex++;
            const totalLevels = ShareManager.instance.getShareLevelCount();
            if (this.currentLevelIndex >= totalLevels) {
                console.log('[PageLevel] 分享关卡全部完成');
                this.stopCountdown();
                ShareManager.instance.clearShareMode();
                ViewManager.instance.replace('PageHome');
                return;
            }
        } else {
            const nextIndex = LevelDataManager.instance.getNextUncompletedIndex(this.currentLevelIndex);
            if (nextIndex < 0) {
                // 所有关卡全部通关
                console.log('[PageLevel] 恭喜通关！所有关卡已完成');
                this.stopCountdown();
                ViewManager.instance.back();
                return;
            }
            this.currentLevelIndex = nextIndex;
            StorageManager.setCurrentLevelIndex(this.currentLevelIndex);
        }

        // 重置并加载下一关（包含进入关卡接口调用）
        await this._enterAndInitLevel();
        console.log(`[PageLevel] 进入关卡 ${this.currentLevelIndex + 1}`);
    }
}
