/**
 * 选项类，表示游戏中的一个问题选项
 */
export class Option {
    /** 选项类型 */
    public type;
    /** 选项文本 */
    public txt;
    /** 图片URL */
    public picUrl;
    /** 音频URL */
    public audioUrl;
    /** 是否为正确选项 */
    public right: boolean;
    /** 选项数据 */
    public data;
    /** 选项ID */
    public id: number;
    /** 计数器 */
    public count: number;
    /** 持续时间 */
    public time: number;
    /** 是否触摸正确 */
    public touchRight: boolean;
    /** 父对象引用 */
    public parent;
    /**
     * 构造函数，初始化选项属性
     * @param data 选项数据
     * @param id 选项ID
     */
    constructor(data, id) {
        this.id = id;
        this.type = data.type;
        this.txt = data.text;
        this.time = data.duration;
        this.picUrl = data.image;
        this.audioUrl = data.audio;
        this.right = data.right;
        this.touchRight = false;
    }
}
/**
 * 角色基类，定义角色的基本属性和方法
 */
class Role {
    /** 得分 */
    public score: number;
    /** 正确次数 */
    public right: number;
    /** 错误次数 */
    public error: number;
    /** 语音记录 */
    public voices: Array<any>;
    /**
     * 构造函数，初始化角色属性
     */
    constructor() {
        this.score = 0;
        this.error = 0;
        this.right = 0;
        this.voices = [];
    }
    /**
     * 增加分数
     * @param score 增加的分数，默认为1
     */
    addScore(score: number = 1) {
        this.score += score;
    }
    /**
     * 增加错误次数
     * @param score 增加的错误次数，默认为1
     */
    addError(score: number = 1) {
        this.error += score;
    }
    /**
     * 增加正确次数
     */
    addRight() {
        this.right += 1;
    }
    /**
     * 添加语音记录
     * @param obj 语音对象
     */
    addVoice(obj: any) {
        // 检查是否已存在相同题目ID的记录
        const existingIndex = this.voices.findIndex(voice => voice.questionId === obj.questionId);
        if (existingIndex !== -1) {
            // 如果存在，先移除旧记录
            this.voices.splice(existingIndex, 1);
        }
        // 添加新记录
        this.voices.push(obj);
    }
    getLastVoice(){
        return this.voices[this.voices.length - 1];
    }
}
/**
 * 玩家类，继承自角色基类
 */
export class Player extends Role {
    /**
     * 构造函数
     */
    constructor() {
        super();
    }
    /**
     * 重置玩家数据
     */
    reset() {
        this.score = 0;
        this.error = 0;
        this.right = 0;
        this.voices = [];
    }
}
/**
 * 游戏状态枚举
 */
export enum GAME_STATE {
    /** 等待状态 */
    WAIT,
    /** 运行状态 */
    RUNNING,
    /** 结束状态 */
    OVER
}
/**
 * 游戏主控制类，负责管理游戏状态、问题选项和玩家信息
 * 采用单例模式设计，确保全局只有一个游戏实例
 */
export default class Game {
    /** 单例实例 */
    private static ins: Game;
    /**
     * 获取游戏实例
     * @returns Game实例
     */
    public static getIns(): Game {
        if (!Game.ins) Game.ins = new Game();
        return Game.ins;
    }
    /** 游戏数据源数组 */
    private data: Array<any>;
    /** 玩家实例 */
    public player: Player;
    /** 游戏状态 */
    public state: GAME_STATE;
    /** 数据总数 */
    public total: number;
    /** 每页数据数量 */
    public pageSize: number;

    /**
     * 构造函数，初始化游戏基本属性
     */
    constructor() {
        this.start = false;
        this.data = [];
        this.page = 0;
        this.pageSize = 6;
        this.player = new Player();
        this.state = GAME_STATE.WAIT;
    }
    /**
     * 获取当前数据源长度
     * @returns 数据源长度
     */
    get len() {
        return this.data ? this.data.length : 0;
    }
    /** 问题信息，包含文本和音频 */
    public question: { text, audio };
    /** 游戏标题 */
    public title: string;
    /** 背景音乐URL */
    public bgAudio: string;
    /** 问题文本 */
    public questionText: string;
    /**
     * 初始化游戏数据
     * @param data 游戏配置数据
     */
    public init(data) {
        this.pageSize = 6; // 每页最多6个数据
        this.question = { text: data.questionText, audio: data.questionTextAudio };
        this.title = data.title;
        this.bgAudio = data.bgAudio || "";
        this.questionText = data.questionText;
        this.start = false;
        this.page = 0; // 页码从0开始
        this.data = data.questions;
        this.total = this.data.length;
    }
    /** 游戏是否已开始 */
    public start: boolean;
    /** 当前页码/进度 */
    public page: number;
    /**
     * 重置游戏状态
     * 重置玩家数据，初始化游戏状态，准备开始新游戏
     */
    reset() {
        this.player.reset();
        this.page = 0; // 页码从0开始
        this.start = true;
        this.state = GAME_STATE.WAIT;
        this.total = this.data.length;
    }
    /**
     * 获取当前页的数据
     * @param {number} pageIndex 页码索引，默认为当前页码（页码从0开始）
     * @returns {Array<Option>} 当前页的选项数据数组
     */
    getPageData(pageIndex?: number) {
        // 如果没有指定页码索引，则使用当前页码（页码从0开始）
        const index = pageIndex !== undefined ? pageIndex : this.page;
        
        // 计算当前页的起始索引和结束索引
        const startIndex = index * this.pageSize;
        const endIndex = Math.min(startIndex + this.pageSize, this.data.length);
        
        // 如果起始索引超出数据范围，返回空数组
        if (startIndex >= this.data.length) {
            return [];
        }
        
        // 提取当前页的数据并转换为Option对象
        const pageData: Array<Option> = [];
        for (let i = startIndex; i < endIndex; i++) {
            pageData.push(new Option(this.data[i], i));
        }
        
        return pageData;
    }


    /**
     * 获取总页数
     * @returns 总页数（向上取整）
     */
    getTotalPageNum() {
        return Math.ceil(this.data.length / this.pageSize);
    }
    
    /**
     * 获取当前页码
     * @returns 当前页码（从0开始）
     */
    getCurrentPageNum() {
        return this.page;
    }
    
    /**
     * 页码加1，用于游戏进度更新
     */
    addPage() {
        this.page += 1;
    }
    
    /**
     * 获取数据总数
     * @returns 数据总数
     */
    get getTotal() {
        return this.data.length;
    }
    
    /**
     * 获取当前页的卡片信息
     * @returns 当前页的选项数据数组
     */
    getCardInfo() {
        const currentPageData = this.getPageData();
        if (currentPageData.length === 0) {
            return null;
        }
        return currentPageData[0]; // 返回当前页的第一个选项
    }
    
    /**
     * 判断游戏是否结束
     * @returns 当前页码是否超过或等于总页数
     */
    get isOver() {
        return this.page >= this.getTotalPageNum();
    }
}