var tdv_sdk = {
    // --- KHO DỮ LIỆU NỘI BỘ ---
    list: [],
    currentQuestion: null,
    level: 0,
    totalQuestions: 0,
    userResults: [],
    gameID: null,
    userId: null,
    leaderboardData: null,
    gameStartTime: null,
    endTime: null,
    instructions: "Sắp xếp các từ thành câu đúng!",
    serverDataLoaded: false,

    // ===== GAME MODE =====
    gameMode: "fill_blank", // "full_order" | "fill_blank"
    missingIndices: [],     // lưu index các slot bị thiếu
    blankIndexes: [], // danh sách index bị trống
    missingWords: [],

    blankCount: 1, // số ô trống (server control)

    currentWords: [],       // Mảng các từ đã shuffle
    correctSentence: "",    // Câu đúng (gốc)
    correctWords: [],       // Mảng các từ đúng (theo thứ tự)
    listPosX: [],
    newWidth: 150,
    maxWWidth: 1200,
    margin: 40,

    // --- DỮ LIỆU MẶC ĐỊNH (FALLBACK) ---
    defaultData: {
        game_id: "SQ_SENTENCE_001",
        user_id: "guest_user",
        blank_count: 2,
        end_time_iso: null,
        instructions: "Arrange the words to form correct sentences!",
        data: [
            {
                "sentence": "There are some toys in the box.",
                "parts": [
                    "There",
                    "are",
                    "some",
                    "toys",
                    "in",
                    "the",
                    "box."
                ],
                "is_scrambled": true,
                "original_quote": "1. some toys are There in the box.",
                "id": "SE-1768646900503-0",
                "game_type": "sequence"
            },
            {
                "sentence": "She is eating a cake.",
                "parts": [
                    "She",
                    "is",
                    "eating",
                    "a",
                    "cake."
                ],
                "is_scrambled": true,
                "original_quote": "2. is She a cake . eating",
                "id": "SE-1768646900503-1",
                "game_type": "sequence"
            },
            {
                "sentence": "May I visit the gift shop?",
                "parts": [
                    "May",
                    "I",
                    "visit",
                    "the",
                    "gift",
                    "shop?"
                ],
                "is_scrambled": true,
                "original_quote": "3. visit May I gift shop ? the",
                "id": "SE-1768646900503-2",
                "game_type": "sequence"
            }
        ]
    },

    // Leaderboard mặc định
    defaultLeaderboard: {
        top_players: [
            { rank: 1, name: "Player 1", score: 10, time_spent: 45 },
            { rank: 2, name: "You", score: 9, time_spent: 52 },
            { rank: 3, name: "Player 3", score: 8, time_spent: 60 }
        ],
        user_rank: { rank: "2", name: "You", score: 9, time_spent: 52 }
    },

    themeSettings: {
        current_bg: "bg",
        bg_list: ["bg1", "bg2", "bg3", "bg4", "bg5", "bg6", "bg7", "bg8", "bg9", "bg10"]
    },

    // --- CÁC HÀM CALLBACK ---
    onGameStart: function () { console.log("SDK: Sentence Game Started"); },
    onAnswerChecked: function (isCorrect, data) { console.log("SDK: Answer Checked", isCorrect); },
    onGameFinished: function (finalData) { console.log("SDK: Game Finished", finalData,data); },
    onLeaderboardLoaded: function (data) { console.log("SDK: Leaderboard Loaded",data); },

    // --- KHỞI TẠO & LOAD DỮ LIỆU ---
    init: function () {
        var self = this;
        const urlParams = new URLSearchParams(window.location.search);
        const bgParam = urlParams.get('bg');
        if (bgParam) {
            this.themeSettings.current_bg = bgParam.startsWith('bg') ? bgParam : "bg" + bgParam;
        }
        const id = urlParams.get('game_id') || this.gameID;
        console.log("🔌 SDK: Sentence Game Initialized. Waiting for data...");
        window.parent.postMessage({
            type: "GAME_READY",
            game_id: id,
            available_bgs: this.themeSettings.bg_list,
            selected_bg: this.themeSettings.current_bg
        }, "*");

        if (urlParams.has('offline') || urlParams.has('demo')) {
            console.log("🔧 SDK: Offline/Demo mode - Loading default data");
            this.loadDefaultData();
        } else {
            setTimeout(function () {
                if (!self.serverDataLoaded && self.list.length === 0) {
                    console.warn("⚠️ SDK: No server data after 3s - Loading default data");
                    self.loadDefaultData();
                }
            }, 3000);
        }
    },

    loadDefaultData: function () {
        if (this.list && this.list.length > 0) {
            console.log("📦 SDK: Data already loaded, skipping default");
            return;
        }
        var now = new Date();
        var endTime = new Date(now.getTime() + (180 * 1000)); // 3 phút
        var defaultJson = JSON.parse(JSON.stringify(this.defaultData));
        defaultJson.end_time_iso = endTime.toISOString();
        console.log("📦 SDK: Loading default data with", defaultJson.data.length, "sentences");
        this.load(defaultJson);
    },

    load: function (inputJson) {
        if (!inputJson) return;
        this.serverDataLoaded = true;
        this.list = inputJson.data || inputJson.questions || [];
        this.gameID = inputJson.game_id;
        this.userId = inputJson.user_id;
        this.totalQuestions = this.list.length;
        this.blankCount = inputJson.blank_count || 1;


        if (inputJson.end_time_iso) {
            this.endTime = new Date(inputJson.end_time_iso);
        } else {
            let fallbackSeconds = inputJson.total_time || 180;
            this.endTime = new Date(Date.now() + fallbackSeconds * 1000);
        }

        if (inputJson.metadata && inputJson.metadata.description) {
            this.instructions = inputJson.metadata.description;
        }

        const completedData = inputJson.completed_question_ids || [];
        this.userResults = [];
        let resumeLevel = 0;
        for (let i = 0; i < this.list.length; i++) {
            const done = completedData.find(item => (item.id || item) === this.list[i].id);
            if (done) {
                this.userResults.push({ id: this.list[i].id, result: done.result !== undefined ? done.result : 0 });
                resumeLevel = i + 1;
            } else {
                resumeLevel = i;
                break;
            }
        }
        this.level = Math.min(resumeLevel, this.totalQuestions - 1);
        this.gameStartTime = new Date();
        this.loadQuestions();
        this.onGameStart();
        if (window['TDVTriger']) window['TDVTriger'].runtime.trigger(cr.plugins_.TDVplugin.prototype.cnds.OnLoad, window['TDVTriger']);
    },

    // --- LOGIC THỜI GIAN ---
    getRemainingTime: function () {
        if (!this.endTime) return 0;
        let diff = Math.floor((this.endTime - new Date()) / 1000);
        return diff > 0 ? diff : 0;
    },

    getTimeSpent: function () {
        if (!this.gameStartTime) return 0;
        const now = new Date();
        return Math.floor((now - this.gameStartTime) / 1000);
    },

    formatTime: function (seconds) {
        if (seconds === undefined || seconds === null) return "00:00";
        const mins = Math.floor(seconds / 60);
        const secs = seconds % 60;
        return String(mins).padStart(2, '0') + ":" + String(secs).padStart(2, '0');
    },

    // ==================== LOGIC CHÍNH: LOAD CÂU HỎI ====================
    lastLoadedLevel: -1,

    loadQuestions: function () {
        if (this.lastLoadedLevel === this.level && this.currentWords.length > 0) {
            console.log("⏭️ Sentence", this.level + 1, "already loaded, skipping...");
            return;
        }

        this.currentQuestion = this.list[this.level];
        if (this.currentQuestion) {
            // Lấy câu đúng từ field "sentence"
            this.correctSentence = String(this.currentQuestion.sentence || "").trim();

            // PHƯƠNG THỨC 1: Nhận parts đã chia sẵn từ server
            if (this.currentQuestion.parts && Array.isArray(this.currentQuestion.parts) && this.currentQuestion.parts.length > 0) {
                // Server đã gửi sẵn parts (có thể đã shuffle hoặc chưa)
                this.currentWords = [...this.currentQuestion.parts];

                // Tách correctWords từ sentence để so sánh
                this.correctWords = this.correctSentence.split(/\s+/).filter(w => w.length > 0);

                console.log("📦 Using server-provided parts:", this.currentWords);
            }
            // PHƯƠNG THỨC 2: Tự tách câu và shuffle (fallback)
            else {
                // TÁCH CÂU THÀNH CÁC TỪ (by space)
                this.correctWords = this.correctSentence.split(/\s+/).filter(w => w.length > 0);

                // Shuffle các từ
                this.currentWords = this.shuffleArray([...this.correctWords]);

                console.log("🔀 Auto-split and shuffled words");
            }
            // ===== FILL BLANK MODE =====
            this.missingIndices = [];

            if (this.gameMode === "fill_blank") {
                var total = this.correctWords.length;

                // random 1 slot bị thiếu
                var missing = Math.floor(Math.random() * total);
                this.missingIndices.push(missing);

                console.log("🕳️ Missing slot index:", missing);
            }
            // Tính width dựa trên số từ và độ dài từ
            this.newWidth = this.calculateWordWidth(this.currentWords);

            // Tính vị trí X cho từng từ
            this.listPosX = this.getObjectPositions(this.currentWords.length, this.newWidth, this.margin, this.maxWWidth);

            // Đánh dấu đã load level này
            this.lastLoadedLevel = this.level;

            console.log("📝 Correct sentence:", this.correctSentence);
            console.log("📝 Display words:", this.currentWords);
            console.log("📝 Word count:", this.currentWords.length);
            this.generateBlankIndexes();
            this.generateMissingWords();

        }
    },

    // Tính width dựa trên số từ và độ dài từ dài nhất
    calculateWordWidth: function (words) {
        var count = words.length;
        var maxLen = Math.max(...words.map(w => w.length));

        // Base width theo độ dài từ
        var baseWidth = Math.max(80, maxLen * 15 + 20);

        // Điều chỉnh theo số từ để vừa màn hình
        if (count <= 3) return Math.min(200, baseWidth);
        if (count <= 5) return Math.min(180, baseWidth);
        if (count <= 7) return Math.min(150, baseWidth);
        return Math.min(120, baseWidth);
    },
    generateBlankIndexes: function () {
    this.blankIndexes = [];

    var total = this.correctWords.length;
    var need = Math.min(this.blankCount, total);

    var pool = [];
    for (var i = 0; i < total; i++) {
        pool.push(i);
    }

    // shuffle pool
    for (var i = pool.length - 1; i > 0; i--) {
        var j = Math.floor(Math.random() * (i + 1));
        var tmp = pool[i];
        pool[i] = pool[j];
        pool[j] = tmp;
    }

    // lấy need phần tử đầu
    this.blankIndexes = pool.slice(0, need);

    console.log("🕳️ Blank indexes:", this.blankIndexes);
    },
    generateMissingWords: function () {
    this.missingWords = [];
    for (var i = 0; i < this.blankIndexes.length; i++) {
        var idx = this.blankIndexes[i];
        this.missingWords.push(this.correctWords[idx]);
    }
    // shuffle
    this.shuffleArray(this.missingWords);
    console.log("🧩 Missing words:", this.missingWords);
    },

    // ==================== TÍNH SCALE CHO TỪ ====================
    getWordScale: function () {
        var wordCount = this.currentWords.length;
        if (wordCount <= 3) return 1.2;
        if (wordCount <= 4) return 1.1;
        if (wordCount <= 5) return 1.0;
        if (wordCount <= 6) return 0.9;
        if (wordCount <= 7) return 0.85;
        return 0.8;
    },

    getTextScale: function () {
        return this.getWordScale();
    },

    getFontSize: function (baseSize) {
        var base = baseSize || 40;
        return Math.round(base * this.getWordScale());
    },

    // ==================== KIỂM TRA ĐÁP ÁN ====================
    play: function (userAnswer, isTimeout = false) {
        if (!this.currentQuestion) return 0;
        var isActuallyTimeout = (isTimeout === true || String(isTimeout) === "true");

        if (this.userResults.some(r => r.id === this.currentQuestion.id)) {
            return this.userResults.find(r => r.id === this.currentQuestion.id).result;
        }

        let isCorrect = false;
        let finalChoice = isActuallyTimeout ? "TIMEOUT" : String(userAnswer).trim();

        if (!isActuallyTimeout) {
            // So sánh câu user sắp xếp với câu đúng (case-insensitive)
            let cleanCorrect = this.correctSentence.toLowerCase().replace(/\s+/g, ' ').trim();
            let cleanUser = finalChoice.toLowerCase().replace(/\s+/g, ' ').trim();
            isCorrect = (cleanUser === cleanCorrect);
        }

        const report = {
            question_id: this.currentQuestion.id,
            result: isCorrect ? 1 : 0,
            choice: finalChoice,
            is_timeout: isActuallyTimeout
        };

        console.log("📤 Report Sent:", report);
        this.userResults.push({ id: report.question_id, result: report.result });
        window.parent.postMessage({ type: "ANSWER_REPORT", data: report }, "*");
        return report.result;
    },

    // ==================== TRACKING TỪ THEO VỊ TRÍ SLOT ====================
    placedWords: [],    // Mảng lưu từ theo vị trí slot [0, 1, 2, 3, ...]
    canSubmit: 0,       // 0 = chưa đủ từ, 1 = đủ từ có thể submit

    // Reset mảng placedWords khi bắt đầu câu hỏi mới
    resetPlacedWords: function () {
        var count = this.currentWords.length;
        this.placedWords = new Array(count).fill("");
        this.canSubmit = 0;
        console.log("🔄 Reset placedWords:", this.placedWords);
    },

    // Alias cho tương thích
    resetPlacedLetters: function () {
        return this.resetPlacedWords();
    },

    // Kiểm tra slot có trống không
    isSlotEmpty: function (slotIndex) {
        if (slotIndex < 0 || slotIndex >= this.placedWords.length) {
            return 0;
        }
        return this.placedWords[slotIndex] === "" ? 1 : 0;
    },

    // Đặt từ vào slot (vị trí từ 0)
    // Trả về 1 = thành công, 0 = thất bại (slot đã có từ)
    setWordAtSlot: function (word, slotIndex) {
        if (slotIndex >= 0 && slotIndex < this.placedWords.length) {
            if (this.placedWords[slotIndex] !== "") {
                console.log("⚠️ Slot " + (slotIndex + 1) + " already has word '" + this.placedWords[slotIndex] + "'");
                return 0;
            }
            this.placedWords[slotIndex] = word;
            console.log("📍 Word '" + word + "' placed at Slot " + (slotIndex + 1));
            this.updateSubmitState();
            return 1;
        }
        return 0;
    },

    // Alias cho tương thích với SQ Word
    setLetterAtSlot: function (word, slotIndex) {
        return this.setWordAtSlot(word, slotIndex);
    },

    // Xóa từ khỏi slot
    clearWordAtSlot: function (slotIndex) {
        if (slotIndex >= 0 && slotIndex < this.placedWords.length) {
            this.placedWords[slotIndex] = "";
            console.log("🗑️ Cleared Slot " + (slotIndex + 1));
            this.updateSubmitState();
        }
    },

    // Alias cho tương thích
    clearLetterAtSlot: function (slotIndex) {
        return this.clearWordAtSlot(slotIndex);
    },

    // Cập nhật trạng thái Submit
    updateSubmitState: function () {
        var required = (this.gameMode === "fill_blank")
            ? this.blankIndexes.length
            : this.currentWords.length;

        var allPlaced = this.getPlacedCount() === required;

        var oldState = this.canSubmit;
        this.canSubmit = allPlaced ? 1 : 0;

        if (this.canSubmit !== oldState) {
            if (this.canSubmit === 1) {
                console.log("✅ All words placed! Submit button should appear.");
            } else {
                console.log("⏳ Not all words placed. Submit hidden.");
            }
        }
    },
    getMissingCount: function () {
    return this.missingWords.length;
    },
    getMissingWordByIndex: function (index) {
    if (this.missingIndices.indexOf(index) === -1) return "";
    console.log("🧩 Missing words:", this.missingWords);
    console.log("🧩 Missing words:", this.index);
    return this.correctWords[index] || "";
    },
    isBlankIndex: function (index) {
    return this.blankIndexes.indexOf(index) !== -1 ? 1 : 0;
    },

    getBlankCount: function () {
        return this.blankIndexes.length;
    },
    // Lấy câu đã ghép (nối các từ theo thứ tự slot)
    getPlacedSentence: function () {
    var result = [];

    for (var i = 0; i < this.correctWords.length; i++) {
        // Nếu là blank slot → lấy từ user đặt
        if (this.isBlankIndex(i)) {
            result.push(this.placedWords[i] || "");
        }
        // Nếu là preset slot → lấy từ đúng
        else {
            result.push(this.correctWords[i]);
        }
    }

        return result.join(" ").replace(/\s+/g, " ").trim();
    },
    // Alias
    getPlacedWord: function () {
        return this.getPlacedSentence();
    },

    // Đếm số slot đã có từ
    getPlacedCount: function () {
        return this.placedWords.filter(w => w !== "").length;
    },

    // Kiểm tra đã đặt đủ từ chưa
    isAllPlaced: function () {
        return this.canSubmit;
    },

    canSubmitAnswer: function () {
        return this.canSubmit;
    },

    // ==================== SUBMIT ĐÁP ÁN ====================
    submitAnswer: function () {
        if (this.canSubmit !== 1) {
            console.log("❌ Cannot submit - not all words placed!");
            return -1;
        }

        var userSentence = this.getPlacedSentence();
        console.log("📝 SUBMIT:", userSentence, "vs", this.correctSentence);
        return this.play(userSentence, false);
    },

    checkAnswer: function () {
        return this.submitAnswer();
    },

    logPlacedWord: function (wordValue, positionIndex) {
        console.log(`📍 Word Placed: "${wordValue}" at Slot ${positionIndex + 1}`);
    },

    // Alias cho tương thích
    logPlacedLetter: function (wordValue, positionIndex) {
        return this.logPlacedWord(wordValue, positionIndex);
    },
        // ===== FILL BLANK GETTERS =====
    isPresetSlot: function (index) {
        if (this.gameMode !== "fill_blank") return 0;
        return this.missingIndices.indexOf(index) === -1 ? 1 : 0;
    },

    isBlankSlot: function (index) {
        if (this.gameMode !== "fill_blank") return 0;
        return this.missingIndices.indexOf(index) !== -1 ? 1 : 0;
    },

    // --- CÁC HÀM GETTER & TIỆN ÍCH ---
    getWordsCount: function () { return this.currentWords.length; },
    getLettersCount: function () { return this.currentWords.length; },  // Alias

    // Lấy từ theo index (đã shuffle)
    getWordByIndex: function (i) { return this.currentWords[i] || ""; },
    getLetterByIndex: function (i) { return this.currentWords[i] || ""; },  // Alias

    // Lấy từ đúng theo index (chưa shuffle)
    getCorrectWordByIndex: function (i) {
        return this.correctWords[i] || "";
    },
    getCorrectLetterByIndex: function (i) { return this.getCorrectWordByIndex(i); },  // Alias

    // Lấy câu đúng
    getCorrectSentence: function () { return this.correctSentence; },
    getCorrectWord: function () { return this.correctSentence; },  // Alias

    getWidth: function () { return this.newWidth; },
    getPosXbyIndex: function (i) { return this.listPosX[i] || 0; },

    // ==================== TÍNH WIDTH/SIZE CHO TỪNG TỪ RIÊNG ====================

    // Tính width cho từng từ dựa trên độ dài
    // Sử dụng: Browser.ExecJS("tdv_sdk.getWidthByIndex(" & loopindex & ")")
    getWidthByIndex: function (index) {
        var word = this.currentWords[index] || "";
        return this.getWidthByWord(word);
    },

    // Tính width dựa trên độ dài từ
    // charWidth: pixel/ký tự (mặc định 30)
    // minWidth: width tối thiểu (mặc định 100)
    // maxWidth: width tối đa (mặc định 350)
    getWidthByWord: function (word, charWidth, minWidth, maxWidth) {
        var len = String(word || "").length;
        var cw = charWidth || 30;   // Tăng từ 25 lên 30
        var min = minWidth || 100;  // Tăng từ 80 lên 100
        var max = maxWidth || 350;  // Tăng từ 250 lên 350

        var w = len * cw + 50;  // +50 padding (tăng từ 40)
        return Math.max(min, Math.min(max, w));
    },

    // Tính font size cho từng từ dựa trên độ dài
    // baseSize: font size cơ bản (mặc định 40)
    // Sử dụng: Browser.ExecJS("tdv_sdk.getFontSizeByIndex(" & loopindex & ", 40)")
    getFontSizeByIndex: function (index, baseSize, boxWidth) {
        var word = this.currentWords[index] || "";
        return this.getFontSizeByWord(word, baseSize, boxWidth);
    },

    // Tính font size để text VỪA VỚI BOX
    // Đơn giản: từ dài → font nhỏ hơn
    getFontSizeByWord: function (word, baseSize, boxWidth) {
        var len = String(word || "").length;
        var base = baseSize || 50;

        // Quy tắc đơn giản: cứ mỗi ký tự > 5 thì giảm font
        if (len <= 2) return base;           // "I", "He"
        if (len <= 3) return base;           // "The", "cat"
        if (len <= 4) return base;           // "love", "goes"
        if (len <= 5) return base;           // "plays", "happy"
        if (len <= 6) return Math.round(base * 0.95);  // "school" → 42
        if (len <= 7) return Math.round(base * 0.85);  // "English" → 37
        if (len <= 8) return Math.round(base * 0.75);  // "football", "everyday" → 32
        if (len <= 9) return Math.round(base * 0.6);  // → 27
        if (len <= 10) return Math.round(base * 0.6);  // "basketball" → 25
        return Math.round(base * 0.6);                  // > 10 → 20
    },

    // Tính font size ĐỒNG ĐỀU cho tất cả từ (dựa trên từ dài nhất)
    // Sử dụng: Browser.ExecJS("tdv_sdk.getUniformFontSize(40, 200)")
    getUniformFontSize: function (baseSize, boxWidth) {
        var base = baseSize || 40;
        var box = boxWidth || 200;

        // Tìm từ dài nhất
        var maxLen = 0;
        for (var i = 0; i < this.currentWords.length; i++) {
            if (this.currentWords[i].length > maxLen) {
                maxLen = this.currentWords[i].length;
            }
        }

        if (maxLen === 0) return base;

        var neededWidth = maxLen * base * 0.6;
        if (neededWidth <= (box - 20)) return base;

        var fitSize = Math.floor((box - 20) / (maxLen * 0.6));
        var minSize = Math.max(16, base * 0.4);

        return Math.max(minSize, fitSize);
    },

    // ==================== TÍNH SCALE ĐỂ TEXT VỪA BOX ====================

    // Tính scale cho text/sprite để vừa với box cố định
    // boxWidth: width của box (mặc định 200)
    // charPixel: số pixel trung bình mỗi ký tự ở scale 1 (mặc định 25)
    // Sử dụng: Browser.ExecJS("tdv_sdk.getScaleByIndex(" & loopindex & ", 200)")
    getScaleByIndex: function (index, boxWidth, charPixel) {
        var word = this.currentWords[index] || "";
        return this.getScaleByWord(word, boxWidth, charPixel);
    },

    // Tính scale dựa trên từ và boxWidth
    getScaleByWord: function (word, boxWidth, charPixel) {
        var len = String(word || "").length;
        var box = boxWidth || 200;
        var charW = charPixel || 25;  // Pixel/ký tự ở scale 1

        // Tính width cần thiết cho text ở scale 1
        var neededWidth = len * charW;

        // Nếu vừa box → scale 1, nếu không → scale nhỏ lại
        if (neededWidth <= box) {
            return 1.0;
        }

        // Scale = boxWidth / neededWidth (với padding)
        var scale = (box - 20) / neededWidth;  // -20 padding

        // Giới hạn scale tối thiểu 0.4 để text không quá nhỏ
        return Math.max(0.4, Math.round(scale * 100) / 100);
    },

    // Tính scale đồng đều cho TẤT CẢ từ (dựa trên từ dài nhất)
    // Sử dụng: Browser.ExecJS("tdv_sdk.getUniformScale(200)")
    getUniformScale: function (boxWidth, charPixel) {
        var box = boxWidth || 200;
        var charW = charPixel || 25;

        // Tìm từ dài nhất
        var maxLen = 0;
        for (var i = 0; i < this.currentWords.length; i++) {
            var len = this.currentWords[i].length;
            if (len > maxLen) maxLen = len;
        }

        var neededWidth = maxLen * charW;
        if (neededWidth <= box) return 1.0;

        var scale = (box - 20) / neededWidth;
        return Math.max(0.4, Math.round(scale * 100) / 100);
    },

    getCurrentImage: function () { return this.currentQuestion ? (this.currentQuestion.image || "") : ""; },
    getCurrentAudio: function () { return this.currentQuestion ? (this.currentQuestion.audio || "") : ""; },
    getCurrentNumber: function () { return this.level + 1; },
    getTotalQuestions: function () { return this.totalQuestions; },
    getInstructions: function () { return this.instructions; },

    getCurrentScore: function () {
        if (this.totalQuestions === 0) return 0;
        const seenIds = new Set();
        let correctCount = 0;
        for (let i = this.userResults.length - 1; i >= 0; i--) {
            const item = this.userResults[i];
            if (!seenIds.has(item.id)) {
                if (item.result === 1) correctCount++;
                seenIds.add(item.id);
            }
        }
        let score = (correctCount / this.totalQuestions) * 10;
        return Math.round(score * 10) / 10;
    },

    getFinalScore: function () {
        let correct = this.userResults.filter(r => r.result === 1).length;
        return correct * 100;
    },

    getCorrectCountText: function () {
        const seenIds = new Set();
        let correctCount = 0;
        for (let i = this.userResults.length - 1; i >= 0; i--) {
            const item = this.userResults[i];
            if (!seenIds.has(item.id)) {
                if (item.result === 1) correctCount++;
                seenIds.add(item.id);
            }
        }
        return correctCount + " / " + this.totalQuestions;
    },

    getCorrectResultText: function () {
        return this.getCorrectCountText();
    },

    getObjectPositions: function (n, objectWidth, margin, maxWidth) {
        const totalWidth = n * objectWidth + (n - 1) * margin;
        const startX = (maxWidth - totalWidth) / 2;
        let positions = [];
        for (let i = 0; i < n; i++) {
            positions.push(startX + i * (objectWidth + margin));
        }
        return positions.map(pos => pos + objectWidth / 2);
    },

    // ==================== VỊ TRÍ VỚI MARGIN CỐ ĐỊNH ====================
    // leftMargin: khoảng cách bên trái (mặc định 200)
    // rightMargin: khoảng cách bên phải (mặc định 200)
    // screenWidth: width màn hình (mặc định 1920)

    // Tính vị trí tất cả các ô với margin cố định
    getFixedMarginPositions: function (leftMargin, rightMargin, screenWidth) {
        var left = leftMargin || 200;
        var right = rightMargin || 200;
        var screen = screenWidth || 1920;
        var n = this.currentWords.length;

        if (n <= 0) return [];

        // Vùng khả dụng
        var availableWidth = screen - left - right;

        // Tính khoảng cách giữa các ô
        var spacing = availableWidth / n;

        // Tính vị trí tâm của mỗi ô
        var positions = [];
        for (var i = 0; i < n; i++) {
            positions.push(left + spacing * i + spacing / 2);
        }

        // Lưu lại để dùng
        this.listPosX = positions;

        console.log("📍 Fixed margin positions:", positions);
        return positions;
    },

    // Lấy vị trí X của ô theo index (với margin cố định)
    // Sử dụng: Browser.ExecJS("tdv_sdk.getFixedPosX(" & loopindex & ", 200, 200, 1920)")
    getFixedPosX: function (index, leftMargin, rightMargin, screenWidth) {
        var left = leftMargin || 200;
        var right = rightMargin || 200;
        var screen = screenWidth || 1920;
        var n = this.currentWords.length;

        if (n <= 0 || index < 0 || index >= n) return 0;

        var availableWidth = screen - left - right;
        var spacing = availableWidth / n;

        return left + spacing * index + spacing / 2;
    },
    
    // Tính width mỗi ô (với margin cố định, các ô cùng size)
    // Sử dụng: Browser.ExecJS("tdv_sdk.getFixedWidth(200, 200, 1920, 20)")
    getFixedWidth: function (leftMargin, rightMargin, screenWidth, gap) {
        var left = leftMargin || 200;
        var right = rightMargin || 200;
        var screen = screenWidth || 1920;
        var g = gap || 20;  // Khoảng cách giữa các ô
        var n = this.currentWords.length;

        if (n <= 0) return 0;

        var availableWidth = screen - left - right;
        var totalGap = (n - 1) * g;
        var boxWidth = (availableWidth - totalGap) / n;

        return Math.floor(boxWidth);
    },

    // ==================== VỊ TRÍ CĂN GIỮA VỚI SPACING CỐ ĐỊNH ====================
    // ===== LAYOUT CONFIG =====
    startY: 840,
    spacingX: 210,
    spacingY: 95,

    // ===== HELPER: chia số ô theo số dòng =====
    getRowConfig: function () {
    var n = this.currentWords.length;

    // 1 dòng
    if (n <= 5) {
        return [n];
    }

    // 2 dòng (dòng trên nặng hơn)
    if (n <= 10) {
        var top = Math.ceil(n * 0.6);
        var bottom = n - top;
        return [top, bottom];
    }

    // 3 dòng (giảm dần)
    var rows = [];
    var remain = n;

    // dòng 1 ~ 40%
    var r1 = Math.ceil(n * 0.4);
    rows.push(r1);
    remain -= r1;

    // dòng 2 ~ 35% của phần còn lại
    var r2 = Math.ceil(remain * 0.5);
    rows.push(r2);
    remain -= r2;

    // dòng 3: còn lại
    rows.push(remain);

        return rows;
    },


    // ===== X POSITION =====
    getCenteredPosX: function (index) {
        var rows = this.getRowConfig();
        var centerX = this.maxWWidth / 2;

        var acc = 0;
        var row = 0;
        var col = 0;

        for (var i = 0; i < rows.length; i++) {
            if (index < acc + rows[i]) {
                row = i;
                col = index - acc;
                break;
            }
            acc += rows[i];
        }

        var itemsInRow = rows[row];
        var totalWidth = (itemsInRow - 1) * this.spacingX;
        var startX = centerX - totalWidth / 2;

        return startX + col * this.spacingX;
    },

    // ===== Y POSITION =====
    getCenteredPosY: function (index) {
        var rows = this.getRowConfig();

        var acc = 0;
        var row = 0;

        for (var i = 0; i < rows.length; i++) {
            if (index < acc + rows[i]) {
                row = i;
                break;
            }
            acc += rows[i];
        }

        return this.startY + row * this.spacingY;
    },

    // ===== CHECKER Y (luôn dưới answers) =====
    getCheckerBaseY: function (index) {
    var rows = this.getRowConfig();

    // Tổng chiều cao answers
    var answerBlockHeight = rows.length * this.spacingY;

    // Xác định checker đang ở dòng nào
    var acc = 0;
    var row = 0;

    for (var i = 0; i < rows.length; i++) {
        if (index < acc + rows[i]) {
            row = i;
            break;
        }
        acc += rows[i];
    }

    // Checker nằm dưới answers + theo dòng tương ứng
    return this.startY
        + this.spacingY         // khoảng cách giữa answers & checker
        + row * this.spacingY   // dòng checker
        + 10;                   // padding nhỏ
    },

// centerX: 600,     // Tâm màn hình X
//     startY: 800,      // Y của dòng đầu tiên
//     spacingX: 210,     // Khoảng cách giữa các ô (X & Y)
//     spacingY: 95,  
//     maxPerRow: 5,     // Số ô mỗi dòng
//     // Lấy vị trí X của ô theo index (căn giữa + spacing cố định)
//     // Sử dụng: Browser.ExecJS("tdv_sdk.getCenteredPosX(" & loopindex & ", 960, 200)")
//     getCenteredPosX: function (index) {

//         var n = this.currentWords.length;
//         if (n <= 0) return this.centerX;

//         var row = Math.floor(index / this.maxPerRow);

//         // Số ô trong dòng hiện tại
//         var itemsInRow = Math.min(
//             this.maxPerRow,
//             n - row * this.maxPerRow
//         );

//         var totalWidth = (itemsInRow - 1) * this.spacingX;
//         var startX = this.centerX - totalWidth / 2;

//         var col = index % this.maxPerRow;
//         return startX + col * this.spacingX;
//     },

//     // ===== TÍNH Y (XUỐNG DÒNG) =====
//     getCenteredPosY: function () {

//         // var row = Math.floor(index / this.maxPerRow);
//         return this.startY;
//     },
//     getCheckerBaseY: function (index) {
    
//     var n = this.currentWords.length;
//     if (n <= 0) return this.startY;

//     var row = Math.floor(index / this.maxPerRow);
//     // checker nằm dưới dòng answers cuối
//     return this.startY + 1 * this.spacingY + row * this.spacingY + 10;
//     },
    shuffleArray: function (array) {
        for (let i = array.length - 1; i > 0; i--) {
            const j = Math.floor(Math.random() * (i + 1));
            [array[i], array[j]] = [array[j], array[i]];
        }
        return array;
    },

    nextQuestion: function () {
        if (this.level < this.totalQuestions - 1) {
            this.level++;
            this.loadQuestions();
            return 1;
        }
        return 0;
    },

    // --- AUDIO ---
    playAudio: function () {
        var audioSrc = this.getCurrentAudio();
        if (!audioSrc) {
            console.log("No audio for this sentence");
            return;
        }

        if (window.audio && !window.audio.paused) {
            window.audio.pause();
            window.audio.currentTime = 0;
        }

        var audio = new Audio(audioSrc);
        window.audio = audio;
        audio.play().catch(e => console.error("Audio error:", e));
        console.log("🔊 Playing audio:", audioSrc);
    },

    // --- KẾT THÚC & LEADERBOARD ---
    forceFinishGame: function () { this.result(); },

    result: function () {
        const uniqueResults = [];
        const seenIds = new Set();
        for (let i = this.userResults.length - 1; i >= 0; i--) {
            if (!seenIds.has(this.userResults[i].id)) {
                uniqueResults.unshift(this.userResults[i]);
                seenIds.add(this.userResults[i].id);
            }
        }

        const totalScore = this.getCurrentScore();
        const timeSpent = this.getTimeSpent();

        const finalData = {
            game_id: this.gameID,
            user_id: this.userId,
            score: totalScore,
            time_spent: timeSpent,
            details: uniqueResults
        };

        console.log("📊 Final Result - Score:", totalScore, "Time Spent:", timeSpent, "s");
        this.onGameFinished(finalData);
        window.parent.postMessage({ type: "FINAL_RESULT", data: finalData }, "*");
        this.leaderboard();
    },

    // --- LEADERBOARD ---
    leaderboard: function () {
        var self = this;
        window.parent.postMessage({ type: "GET_LEADERBOARD", game_id: this.gameID }, "*");

        setTimeout(function () {
            if (!self.leaderboardData) {
                console.warn("⚠️ SDK: No leaderboard from server - Generating with user score");
                self.loadLeaderboard(self.generateUserLeaderboard());
            }
        }, 2000);
    },

    generateUserLeaderboard: function () {
        var userScore = this.getCurrentScore();
        var userName = this.userId || "You";
        var userTimeSpent = this.getTimeSpent();

        var topPlayers = JSON.parse(JSON.stringify(this.defaultLeaderboard.top_players));
        var userPlayer = { rank: 0, name: userName, score: userScore, time_spent: userTimeSpent };

        var userRankIndex = -1;
        for (var i = 0; i < topPlayers.length; i++) {
            if (userScore > topPlayers[i].score ||
                (userScore === topPlayers[i].score && userTimeSpent < topPlayers[i].time_spent)) {
                userRankIndex = i;
                break;
            }
        }

        var result = { top_players: [], user_rank: null };

        if (userRankIndex !== -1) {
            topPlayers.splice(userRankIndex, 0, userPlayer);
            topPlayers = topPlayers.slice(0, 3);
            for (var j = 0; j < topPlayers.length; j++) {
                topPlayers[j].rank = j + 1;
            }
            result.top_players = topPlayers;
            result.user_rank = topPlayers[userRankIndex];
        } else {
            result.top_players = topPlayers;
            result.user_rank = { rank: 4, name: userName, score: userScore, time_spent: userTimeSpent };
        }

        console.log("📊 Generated leaderboard - User rank:", result.user_rank.rank);
        return result;
    },

    loadLeaderboard: function (data) {
        this.leaderboardData = data;
        if (window['TDVTriger']) window['TDVTriger'].runtime.trigger(cr.plugins_.TDVplugin.prototype.cnds.OnLeaderboardLoaded, window['TDVTriger']);
    },

    getLbLength: function () {
        return (this.leaderboardData && this.leaderboardData.top_players) ? this.leaderboardData.top_players.length : 0;
    },

    getLbItemY: function (index, startY, spacing) {
        return startY + (index * spacing);
    },

    getLbAttr: function (index, attr) {
        if (!this.leaderboardData || !this.leaderboardData.top_players) return "";
        var i = parseInt(index);
        if (!isNaN(i) && this.leaderboardData.top_players[i]) {
            var value = this.leaderboardData.top_players[i][attr];
            if (attr === 'rank' && value !== undefined) return value;
            if (attr === 'time_spent' && value !== undefined) return value + "s";
            return value !== undefined ? value : "";
        }
        return "";
    },

    getLbUserAttr: function (attr) {
        if (this.leaderboardData && this.leaderboardData.user_rank) {
            var value = this.leaderboardData.user_rank[attr];
            if (attr === 'rank' && value) return value;
            if (attr === 'time_spent' && value !== undefined) return value + "s";
            return value !== undefined ? value : "";
        }
        return (attr === 'score') ? "0" : (attr === 'time_spent') ? "0s" : "";
    }
};

window.addEventListener("message", function (event) {
    if (!event.data) return;
    if (event.data.type === "SERVER_PUSH_DATA") tdv_sdk.load(event.data.jsonData);
    if (event.data.type === "SERVER_PUSH_LEADERBOARD") tdv_sdk.loadLeaderboard(event.data.leaderboardData);
});
