/**
 * ========== SENA SDK - MERGED COMPLETE VERSION ==========
 * Combines all features from root, update_1, and update_2
 * - Advanced game type support (G1-G9, G26)
 * - PostMessage handling with late arrival support
 * - Multi-question and single-question modes
 * - G4, G5, G9 specific implementations
 * - Matching, WordSearch, GroupSort, Crossword, Puzzle support
 */

/**
 * ========== GAME TYPES CONFIG ==========
 */
var SENA_GAME_TYPES = {
    1: { name: 'Quiz', description: 'Trắc nghiệm' },
    2: { name: 'Sort', description: 'Sắp xếp' },
    3: { name: 'Match', description: 'Nối cặp', sdk: 'tdv_sdk' },
    4: { name: 'Fill', description: 'Điền từ' },
    5: { name: 'Custom', description: 'Tùy chỉnh' },
    6: { name: 'OddOneOut', description: 'Chọn khác loại' },
    7: { name: 'WordSearch', description: 'Tìm từ ẩn', sdk: 'tdv_wordsearch' },
    8: { name: 'GroupSort', description: 'Phân loại nhóm', sdk: 'tdv_groupsort' },
    9: { name: 'Crossword', description: 'Ô chữ', sdk: 'tdv_crossword' },
    26: { name: 'Puzzle', description: 'Ghép hình', sdk: 'tdv_puzzle' }
};

// Helper: Get valid game type range
function getSenaGameTypeRange() {
    var types = Object.keys(SENA_GAME_TYPES).map(Number);
    return { min: Math.min.apply(null, types), max: Math.max.apply(null, types) };
}

// ========== STUBS FOR LAZY LOADING ==========
window.tdv_sdk = window.tdv_sdk || {
    isStub: true,
    init: function (mode) {
        console.log('⚠️ tdv_sdk.init() called on Stub. Mode saved:', mode);
        this._pendingMode = mode;
    },
    prepareIDs: function () { },
    getItemCount: function () { return 0; },
    loadFromPostMessage: function () { console.warn('Stub loadFromPostMessage called'); },
    isCorrect: function () { return 0; },
    getCorrectCount: function () { return 0; },
    getTimeSpent: function () { return 0; }
};

// Helper: Regex for game code
function getSenaGameCodeRegex(strict) {
    var range = getSenaGameTypeRange();
    var typePattern = '[' + range.min + '-' + range.max + ']';
    var qoPattern = strict ? '[0-2]' : '[0-9]';
    return new RegExp('^G(' + typePattern + ')([2-9])(' + qoPattern + ')(' + qoPattern + ')(?:S([0-1]))?(?:T(\\d+))?$');
}

/**
 * Sena SDK Constructor
 */
function SenaSDK(gid = 'G2510S1T30') {
    // Core data
    this.data = null;
    this.correctAnswer = null;
    this.gameCode = gid;
    this.timeLimit = 0;
    this.shuffle = true;
    this.uuid = Date.now() + '_' + Math.floor(Math.random() * 100000);
    // Time tracking
    this.startTime = 0;
    this.endTime = 0;

    // TTS (Web Speech API)
    this.speechSynthesis = window.speechSynthesis;
    this.currentUtterance = null;
    this.voiceSettings = {
        lang: 'en-US',
        rate: 1.0,
        pitch: 1.0,
        volume: 1.0
    };

    // Multi-question support
    this.list = [];
    this.currentQuestion = null;
    this.level = 0;
    this.totalQuestions = 0;
    this.userResults = [];
    this.gameID = null;
    this.userId = null;
    this.postMessageDataLoaded = false;

    // Game type flags
    this.isMatchingGame = false;
    this.isOddOneOutGame = false;
    this.isWordSearchGame = false;
    this.isGroupSortGame = false;

    // PostMessage tracking
    this._postMessageListenerRegistered = false;
    this._waitingForPostMessage = false;
    this._postMessageTimeout = null;
    this._loadCallback = null;

    // Interaction tracking
    this._gameStartedByUser = false;
    this._dataLoadedFromServer = false;

    // G5 specific
    this.masterList = [];
    this.currentLevel = 0;
    this.totalLevels = 1;
    this.timePerCard = 0;

    // Mode: 'live' | 'preview' | 'dev'
    this.mode = 'preview';
}

/**
 * Shuffle array using Fisher-Yates algorithm
 */
SenaSDK.prototype.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]];
    }
};

/**
 * Load data from postMessage (SERVER_PUSH_DATA)
 */
SenaSDK.prototype.loadFromPostMessage = function (inputJson, callback) {
    let self = this;

    if (!inputJson) {
        console.error('🎮 Sena SDK: No data in postMessage');
        if (callback) callback(false);
        return false;
    }

    console.log('📦 Sena SDK: Loading from PostMessage:', inputJson);

    // Update gameCode if provided
    if (inputJson.gameCode) {
        self.gameCode = inputJson.gameCode;
    }

    let gameCode = self.gameCode;
    let gameCategory = gameCode.charAt(1);

    console.log('🎮 Sena SDK: GameCode:', gameCode, '| Category:', gameCategory);

    // ========== FORWARD TO SPECIALIZED SDKs ==========
    
    // Matching (G3xxx)
    if (gameCategory === '3') {
        console.log('🎯 Sena SDK: Detected MATCHING GAME (G3xxx), forwarding to tdv_sdk...');
        if (window.tdv_sdk && typeof window.tdv_sdk.loadFromPostMessage === 'function') {
            self.isMatchingGame = true;
            return window.tdv_sdk.loadFromPostMessage(inputJson, callback);
        } else {
            console.error('❌ tdv_sdk not loaded!');
            if (callback) callback(false);
            return false;
        }
    }

    // WordSearch (G7xxx)
    if (gameCategory === '7') {
        console.log('🎯 Sena SDK: Detected WORDSEARCH GAME (G7xxx), forwarding to tdv_wordsearch...');
        if (window.tdv_wordsearch && typeof window.tdv_wordsearch.loadFromPostMessage === 'function') {
            self.isWordSearchGame = true;
            return window.tdv_wordsearch.loadFromPostMessage(inputJson, callback);
        } else {
            console.error('❌ tdv_wordsearch not loaded!');
            if (callback) callback(false);
            return false;
        }
    }

    // GroupSort (G8xxx)
    if (gameCategory === '8') {
        console.log('🎯 Sena SDK: Detected GROUPSORT GAME (G8xxx), forwarding to tdv_groupsort...');
        if (window.tdv_groupsort && typeof window.tdv_groupsort.loadFromPostMessage === 'function') {
            self.isGroupSortGame = true;
            return window.tdv_groupsort.loadFromPostMessage(inputJson, callback);
        } else {
            console.error('❌ tdv_groupsort not loaded!');
            if (callback) callback(false);
            return false;
        }
    }

    // Crossword (G9xxx)
    if (gameCategory === '9') {
        console.log('🎯 Sena SDK: Detected CROSSWORD GAME (G9xxx), forwarding to tdv_crossword...');
        if (window.tdv_crossword && typeof window.tdv_crossword.loadFromPostMessage === 'function') {
            return window.tdv_crossword.loadFromPostMessage(inputJson, callback);
        } else {
            console.error('❌ tdv_crossword not loaded!');
            if (callback) callback(false);
            return false;
        }
    }

    // Puzzle (G26xxx)
    if (gameCategory === '2' && gameCode.charAt(2) === '6') {
        console.log('🎯 Sena SDK: Detected PUZZLE GAME (G26xxx), forwarding to tdv_puzzle...');
        if (window.tdv_puzzle && typeof window.tdv_puzzle.loadFromPostMessage === 'function') {
            return window.tdv_puzzle.loadFromPostMessage(inputJson, callback);
        } else {
            console.error('❌ tdv_puzzle not loaded!');
            if (callback) callback(false);
            return false;
        }
    }

    // ========== BASIC GAMES (Quiz, Sort, OddOneOut, Fill, Custom) ==========
    let items = inputJson.list || [inputJson];

    // Cancel timeout if waiting
    if (self._postMessageTimeout) {
        clearTimeout(self._postMessageTimeout);
        self._postMessageTimeout = null;
    }
    self._waitingForPostMessage = false;

    // Parse game code
    self._parseGameCode();

    if (items.length === 1) {
        // Single question
        let item = items[0];
        self.data = {
            question: item.question || item.data?.question || '',
            request: item.request || item.data?.request || '',
            options: item.options || item.data?.options || [],
            image: item.image || item.data?.image || '',
            audio: item.audio || item.data?.audio || '',
            hint: item.hint || item.data?.hint || null,
            reason: item.reason || item.data?.reason || ''
        };
        self.correctAnswer = item.answer;
        self.gameID = item.id || null;

        // G5 specific: Initialize master list
        if (self.gameType === 5 && self.data?.options) {
            self.masterList = [...self.data.options];
            self.totalLevels = Math.ceil(self.masterList.length / self.itemCount);
            self.currentLevel = 0;
            self.loadLevelG5(1);
        }

        // G4 specific: Process data
        if (self.gameType === 4) {
            self._processG4Data();
        }
    } else {
        // Multi-question
        self.list = items.map((item, idx) => ({
            id: item.id || idx,
            question: item.question || '',
            request: item.request || '',
            options: item.options || [],
            answer: item.answer,
            image: item.image || '',
            audio: item.audio || '',
            reason: item.reason || ''
        }));
        self.totalQuestions = items.length;
        self.level = 0;
        self._loadCurrentQuestionToData();
    }

    self.postMessageDataLoaded = true;
    console.log('✅ Sena SDK: Data processed -', items.length, 'item(s)');

    if (self._loadCallback) {
        self._loadCallback(true);
        self._loadCallback = null;
    }

    if (callback) callback(true);
    return true;
};

/**
 * Parse game code to get settings
 */
SenaSDK.prototype._parseGameCode = function () {
    let self = this;
    const gameCode = self.gameCode || 'G2510S1T30';
    const regex = getSenaGameCodeRegex(true);
    let match = gameCode.match(regex);

    if (match) {
        self.gameType = parseInt(match[1], 10);
        self.itemCount = parseInt(match[2], 10);
        self.questionType = parseInt(match[3], 10);
        self.optionType = parseInt(match[4], 10);
        const shuffleFlag = match[5] !== undefined ? match[5] : '1';
        const timeStr = match[6] !== undefined ? match[6] : '0';
        self.shuffle = (shuffleFlag === '1');
        
        // G5 uses T for time per card
        if (self.gameType === 5) {
            self.timePerCard = parseInt(timeStr, 10);
            self.timeLimit = 0;
        } else {
            self.timeLimit = parseInt(timeStr, 10);
            self.timePerCard = 0;
        }
    }
};

/**
 * Load current question to this.data
 */
SenaSDK.prototype._loadCurrentQuestionToData = function () {
    let self = this;

    if (self.list.length > 0 && self.level < self.list.length) {
        self.currentQuestion = self.list[self.level];
        self.data = {
            question: self.currentQuestion.question || '',
            request: self.currentQuestion.request || '',
            options: self.currentQuestion.options || [],
            image: self.currentQuestion.image || '',
            audio: self.currentQuestion.audio || '',
            reason: self.currentQuestion.reason || ''
        };
        self.correctAnswer = self.currentQuestion.answer;
    }
};

/**
 * Move to next question
 */
SenaSDK.prototype.nextQuestion = function () {
    let self = this;

    if (self.level < self.totalQuestions - 1) {
        self.level++;
        self._loadCurrentQuestionToData();
        console.log('🎮 Sena SDK: Next Question:', self.level + 1, '/', self.totalQuestions);
        return true;
    }

    console.log('🎮 Sena SDK: No more questions');
    return false;
};

/**
 * Get current question number (1-indexed)
 */
SenaSDK.prototype.getCurrentNumber = function () {
    return this.level + 1;
};

/**
 * Get total questions
 */
SenaSDK.prototype.getTotalQuestions = function () {
    return this.totalQuestions || 1;
};

// PostMessage timeout setting
SenaSDK.prototype.POSTMESSAGE_TIMEOUT_MS = 5000; // 5 seconds

/**
 * Load data (with mode support)
 */
SenaSDK.prototype.load = function (callback, template = 'G2510S1T30') {
    let self = this;

    // Auto-register postMessage listener
    if (!self._postMessageListenerRegistered) {
        self.registerPostMessageListener();
        self._postMessageListenerRegistered = true;
    }

    // Already loaded from postMessage
    if (self.postMessageDataLoaded && self.list.length > 0) {
        console.log('🎮 Sena SDK: Data already loaded from postMessage');
        if (callback) callback(true);
        return;
    }

    // Already have data
    if (self.data && self.data.options) {
        console.log('🎮 Sena SDK: Data already available');
        if (callback) callback(true);
        return;
    }

    // Get URL parameters
    const urlParams = new URLSearchParams(window.location.search);
    const LID = urlParams.get('LID');
    if (LID) {
        self.gameCode = LID;
    }

    const urlMode = urlParams.get('mode');
    if (urlMode && ['live', 'preview', 'dev'].includes(urlMode.toLowerCase())) {
        self.mode = urlMode.toLowerCase();
    }

    console.log('🎮 Sena SDK: Mode =', self.mode.toUpperCase(), '| GameCode =', self.gameCode);

    self._loadCallback = callback;

    // Mode-based loading
    switch (self.mode) {
        case 'live':
            self._waitingForPostMessage = true;
            console.log('⏳ Sena SDK: [LIVE MODE] Waiting for server data (no timeout)...');
            self._sendGameReady();
            break;

        case 'dev':
            console.log('🔧 Sena SDK: [DEV MODE] Loading sample data immediately...');
            self._waitingForPostMessage = false;
            self._loadFromServer(callback, template);
            break;

        case 'preview':
        default:
            self._waitingForPostMessage = true;
            console.log('⏳ Sena SDK: [PREVIEW MODE] Waiting for postMessage (5s timeout)...');
            
            self._postMessageTimeout = setTimeout(function () {
                if (self._waitingForPostMessage && !self.postMessageDataLoaded) {
                    console.warn('⚠️ Sena SDK: No postMessage received, fallback to sample data...');
                    self._loadFromServer(self._loadCallback, template);
                }
            }, self.POSTMESSAGE_TIMEOUT_MS);
            break;
    }
};

/**
 * Send GAME_READY message
 */
SenaSDK.prototype._sendGameReady = function () {
    let self = this;
    window.parent.postMessage({
        type: "GAME_READY",
        uuid: self.uuid,
        payload: {
            game_id: self.gameID || self.gameCode,
            game_code: self.gameCode,
            mode: self.mode
        }
    }, "*");
    console.log('📤 Sena SDK: Sent GAME_READY to parent');
    console.log('🔑 UUID:', self.uuid);
};

/**
 * Load from server (fallback)
 */
SenaSDK.prototype._loadFromServer = function (callback, template = 'G2510S1T30') {
    let self = this;
    self._waitingForPostMessage = false;

    let url = `https://senaai.tech/sample/${self.gameCode}.json`;
    console.log('📡 Sena SDK: Fetching sample from:', url);

    fetch(url)
        .then(response => {
            if (!response.ok) throw new Error("HTTP " + response.status);
            return response.json();
        })
        .then(jsonData => {
            console.log('✅ Sena SDK: Fetched data success');

            self.loadFromPostMessage(jsonData);
            self._dataLoadedFromServer = true;
        })
        .catch(error => {
            console.error('❌ Sena SDK: Error loading data:', error);
            if (self.mode === 'dev') {
                self._loadHardcodedFallback(callback);
            } else {
                if (callback) callback(false);
            }
        });
};

/**
 * Hardcoded fallback (for dev mode when fetch fails)
 */
SenaSDK.prototype._loadHardcodedFallback = function (callback) {
    let self = this;
    console.warn('⚠️ Sena SDK: Using HARDCODED fallback data');

    let fallbackJson = {
        gameCode: self.gameCode,
        data: {
            question: "What is 2 + 2?",
            options: ["3", "4", "5", "6"]
        },
        answer: "4"
    };

    self.loadFromPostMessage(fallbackJson, callback);
};

/**
 * Validate game code
 */
SenaSDK.prototype.validateGameCode = function (code) {
    code = code || this.gameCode;
    const regex = getSenaGameCodeRegex(true);
    const match = code.match(regex);
    const range = getSenaGameTypeRange();

    if (!match) {
        return { valid: false, error: 'Invalid game code format', code: code };
    }

    return {
        valid: true,
        code: code,
        type: parseInt(match[1], 10),
        count: parseInt(match[2], 10),
        qType: parseInt(match[3], 10),
        oType: parseInt(match[4], 10),
        shuffle: match[5] !== '0',
        time: match[6] ? parseInt(match[6], 10) : 0,
        description: this.getGameCodeDescription(match)
    };
};

/**
 * Get game code description
 */
SenaSDK.prototype.getGameCodeDescription = function (match) {
    if (!match) return '';
    
    const gameType = SENA_GAME_TYPES[match[1]]?.name || 'Unknown';
    const contentTypes = ['Text', 'Image', 'Audio'];
    const qType = contentTypes[parseInt(match[3])] || 'Unknown';
    const oType = contentTypes[parseInt(match[4])] || 'Unknown';

    return `${gameType}: ${match[2]} items, ${qType} → ${oType}`;
};

/**
 * Generate developer guide
 */
SenaSDK.prototype.guide = function () {
    let self = this;
    const gameCode = self.gameCode || 'G2510S1T30';
    
    return `╔════════════════════════════════════════════════════════════════════════════╗
║              SENA SDK - DEVELOPER GUIDE: ${gameCode.padEnd(37)}║
╚════════════════════════════════════════════════════════════════════════════╝

📚 MERGED VERSION
This SDK combines all game types (G1-G9, G26) with full postMessage support.

🎮 SUPPORTED GAME TYPES:
${Object.entries(SENA_GAME_TYPES).map(([key, val]) => `  G${key}: ${val.name} - ${val.description}`).join('\n')}

📖 For detailed documentation, visit: https://senaai.tech/docs
`;
};

// ========== GETTERS ==========

SenaSDK.prototype.getQuestionValue = function () {
    var q = String(this.data?.question || '').trim();
    if (q.toLowerCase().startsWith('http')) return '';
    return q;
};

SenaSDK.prototype.getQuestionType = function () {
    let self = this;
    const gameCode = self.gameCode || 'G2510S1T30';
    const regex = getSenaGameCodeRegex(true);
    const match = gameCode.match(regex);
    if (match) {
        const qIdx = match[3];
        const types = { '0': 'text', '1': 'image', '2': 'audio' };
        return types[qIdx] || 'text';
    }
    return 'text';
};

SenaSDK.prototype.getQuestionImage = function () {
    return String(this.data?.question || '').trim();
};

SenaSDK.prototype.getRequestValue = function () {
    return String(this.data?.request || '').trim();
};

SenaSDK.prototype.getRequestType = function () {
    return this.getQuestionType();
};

SenaSDK.prototype.getOptionsCount = function () {
    return this.data?.options?.length || 0;
};

SenaSDK.prototype.getOptionsType = function () {
    let self = this;
    const gameCode = self.gameCode || 'G2510S1T30';
    const regex = getSenaGameCodeRegex(true);
    const match = gameCode.match(regex);
    if (match) {
        const oIdx = match[4];
        const types = { '0': 'text', '1': 'image', '2': 'audio' };
        return types[oIdx] || 'text';
    }
    return 'text';
};

SenaSDK.prototype.getOptionsValue = function (index) {
    return this.data?.options?.[index];
};

SenaSDK.prototype.getHintType = function () {
    return this.data?.hint?.type || '';
};

SenaSDK.prototype.getHintCount = function () {
    const hintValue = this.getHintValue();
    if (hintValue === null) return 0;
    if (Array.isArray(hintValue)) return hintValue.length;
    return 1;
};

SenaSDK.prototype.getHintValue = function (index) {
    if (this.data?.hint?.value !== undefined) {
        const hintValue = this.data.hint.value;
        const hintType = this.getHintType();
        
        if (hintType === 'display' && Array.isArray(hintValue)) {
            if (index !== undefined && index >= 0 && index < hintValue.length) {
                return hintValue[index];
            }
            return hintValue;
        }
        
        return hintValue;
    }
    return null;
};

SenaSDK.prototype.getReason = function () {
    return this.data?.reason || this.currentQuestion?.reason || '';
};

SenaSDK.prototype.hasReason = function () {
    let reason = this.getReason();
    return (reason && reason.length > 0) ? 1 : 0;
};

// ========== G9 MEMORY FUNCTIONS ==========

SenaSDK.prototype.getTargetName = function () {
    if (this.correctAnswer) {
        if (typeof this.correctAnswer === 'object' && this.correctAnswer.text) {
            return this.correctAnswer.text;
        }
        return String(this.correctAnswer);
    }
    return '';
};

SenaSDK.prototype.getCardName = function (index) {
    if (this.data?.options?.[index]) {
        let opt = this.data.options[index];
        return opt.name || opt.text || '';
    }
    return '';
};

SenaSDK.prototype.getCardImage = function (index) {
    return this.data?.options?.[index]?.image || '';
};

SenaSDK.prototype.getCardAudio = function (index) {
    return this.data?.options?.[index]?.audio || '';
};

SenaSDK.prototype.getCardID = function (index) {
    return this.data?.options?.[index]?.id || '';
};

SenaSDK.prototype.getCardType = function (index) {
    if (this.data?.options?.[index]) {
        return this.data.options[index].type || 'text';
    }
    if (this.masterList?.[index]) {
        return this.masterList[index].type || 'text';
    }
    return 'text';
};

// ========== G5 VOICE RUSH FUNCTIONS ==========

SenaSDK.prototype.loadLevelG5 = function (levelIndex) {
    let self = this;
    if (self.gameType !== 5 || !self.masterList) return false;

    self.currentLevel = levelIndex;
    let count = self.itemCount;
    window.Sena_TotalLevels = Math.ceil(self.masterList.length / count);

    let startIndex = (levelIndex - 1) * count;
    let endIndex = Math.min(startIndex + count, self.masterList.length);
    let levelOptions = self.masterList.slice(startIndex, endIndex);

    self.data.options = levelOptions;

    console.log(`🎮 Sena SDK: Loaded G5 Level ${levelIndex} with ${levelOptions.length} cards`);
    return true;
};

SenaSDK.prototype.getTotalLevels = function () {
    return this.totalLevels || 1;
};

SenaSDK.prototype.getTimePerCard = function () {
    if (this.timePerCard === undefined) {
        this._parseGameCode();
    }
    return this.timePerCard > 0 ? this.timePerCard : 5;
};

// ========== G4 MEMORY CARD FUNCTIONS ==========

SenaSDK.prototype._processG4Data = function () {
    let self = this;
    if (!self.data.options) self.data.options = [];

    // Count occurrences
    let counts = {};
    self.data.options.forEach(item => {
        if (item.type !== 'blank' && item.name) {
            counts[item.name] = (counts[item.name] || 0) + 1;
        }
    });

    // Remove orphans (items that appear less than 2 times)
    self.data.options.forEach(item => {
        if (item.type !== 'blank' && item.name && counts[item.name] < 2) {
            console.log('🎮 Sena SDK: Orphan card detected:', item.name);
            item.type = 'blank';
            item.name = 'blank';
            item.image = '';
            item.id = 'blank_sanitized';
        }
    });

    // Fill with blank cards to make 9 total
    while (self.data.options.length < 9) {
        self.data.options.push({
            id: 'blank_' + self.data.options.length,
            type: 'blank',
            name: 'blank',
            value: -1,
            image: ''
        });
    }

    // Shuffle
    if (self.shuffle) {
        self.shuffleArray(self.data.options);
    }
};

SenaSDK.prototype.checkPair = function (idx1, idx2, callback) {
    let self = this;

    let card1 = self.data?.options?.[idx1];
    let card2 = self.data?.options?.[idx2];

    if (!card1 || !card2) {
        if (callback) callback(false);
        return;
    }

    let isMatch = false;

    if (card1.type !== 'blank' && card2.type !== 'blank') {
        if (card1.id !== card2.id) {
            if (card1.name && card2.name && card1.name.toLowerCase() === card2.name.toLowerCase()) {
                isMatch = true;
            }
        }
    }

    console.log(`🎮 Sena SDK: Check Pair [${idx1}] vs [${idx2}] -> ${isMatch ? 'MATCH' : 'WRONG'}`);
    
    if (callback) callback(isMatch);
};

// ========== GAME ACTIONS ==========

SenaSDK.prototype.start = function () {
    let self = this;

    // Forward to specialized SDKs
    if (self.isMatchingGame && window.tdv_sdk?.start) {
        console.log('🎮 Sena SDK: Forwarding start() to tdv_sdk');
        window.tdv_sdk.start();
        return;
    }

    // Standard games
    self.curIndex = 0;
    if (self.shuffle && self.data?.options) {
        self.shuffleArray(self.data.options);
    }
    // self.startTime = Date.now();
};

SenaSDK.prototype.markUserInteraction = function () {
    if (!this._gameStartedByUser) {
        this._gameStartedByUser = true;
        console.log('🎮 Sena SDK: User interaction detected');
        
        if (this.isMatchingGame && window.tdv_sdk) {
            window.tdv_sdk._gameStartedByUser = true;
        }
    }
};

SenaSDK.prototype.canReloadData = function () {
    return !this._gameStartedByUser;
};

SenaSDK.prototype.end = function (answer, callback) {
    let self = this;
    const category = self.gameCode ? self.gameCode.charAt(1) : '';

    // ========== FORWARD TO SPECIALIZED SDKs ==========
    
    // Crossword (G9)
    if (category === '9' && window.tdv_crossword) {
        let isCorrect = (window.tdv_crossword.placedCount >= window.tdv_crossword.totalCells);
        let duration = window.tdv_crossword.getTimeSpent?.() || 0;
        
        console.log(`🎮 Sena SDK: Crossword Result: ${isCorrect ? 'WIN' : 'LOSE'}`);
        
        if (callback) callback(isCorrect);
        return { isCorrect, duration };
    }

    // Matching/GroupSort (G3/G8)
    if ((category === '8' || category === '3' || self.isMatchingGame) && window.tdv_sdk) {
        console.log('🎮 Sena SDK: Forwarding end() to tdv_sdk');
        
        let isCorrect = false;
        let duration = 0;
        
        if (String(answer || '').includes(':') && category === '8') {
            isCorrect = self.validateCheck(answer);
        } else {
            isCorrect = window.tdv_sdk.isCorrect?.() === 1;
        }
        
        duration = window.tdv_sdk.getTimeSpent?.() || 0;
        
        if (callback) callback(isCorrect);
        return { isCorrect, duration };
    }

    // ========== STANDARD GAMES (Quiz/Sort/Fill) ==========
    
    // self.endTime = Date.now();
    // const duration = (self.endTime - self.startTime) / 1000;

    const answerStr = String(answer || '');
    const userAnswers = answerStr.includes('|') 
        ? answerStr.split('|').map(a => a.trim().toLowerCase()).filter(a => a)
        : [answerStr.trim().toLowerCase()].filter(a => a);

    let correctAnswers = [];
    if (self.correctAnswer) {
        if (Array.isArray(self.correctAnswer)) {
            correctAnswers = self.correctAnswer.map(a => {
                if (typeof a === 'string') return a.toLowerCase();
                if (a.text) return a.text.toLowerCase();
                return '';
            });
        } else if (typeof self.correctAnswer === 'string') {
            correctAnswers = self.correctAnswer.includes('|')
                ? self.correctAnswer.split('|').map(a => a.trim().toLowerCase())
                : [self.correctAnswer.toLowerCase()];
        } else if (self.correctAnswer.text) {
            correctAnswers = [self.correctAnswer.text.toLowerCase()];
        }
    }

    // Compare answers
    const isStrictOrder = self.gameType === 2; // Sort game
    const finalUser = isStrictOrder ? [...userAnswers] : [...userAnswers].sort();
    const finalCorrect = isStrictOrder ? [...correctAnswers] : [...correctAnswers].sort();

    let isCorrect = false;
    
    const getFileName = (url) => {
        if (!url.startsWith('http')) return url;
        return url.split('/').pop().split('?')[0];
    };

    if (finalUser.length === finalCorrect.length) {
        isCorrect = finalUser.every((uVal, index) => {
            let cVal = finalCorrect[index];
            if (uVal === cVal) return true;
            if (uVal.startsWith('http') || cVal.startsWith('http')) {
                return getFileName(uVal) === getFileName(cVal);
            }
            return false;
        });
    }

    // // Check time limit
    // if (self.timeLimit > 0 && duration > self.timeLimit) {
    //     isCorrect = false;
    //     console.log('🎮 Sena SDK: Time limit exceeded');
    // }

    const result = {
    isCorrect: isCorrect,
    correctAnswer: correctAnswers.join(' | '),
    userAnswer: userAnswers.join(' | ')
};

    console.log(`🎮 Sena SDK: Result: ${isCorrect ? 'CORRECT' : 'INCORRECT'}`);    
    if (callback) callback(result.isCorrect);
    return result;
};

SenaSDK.prototype.validateCheck = function (answer) {
    let self = this;
    const answerStr = String(answer || '');
    const userAnswers = answerStr.includes('|')
        ? answerStr.split('|').map(a => a.trim().toLowerCase())
        : [answerStr.trim().toLowerCase()];

    let correctAnswers = [];
    if (self.correctAnswer) {
        if (Array.isArray(self.correctAnswer)) {
            correctAnswers = self.correctAnswer.map(a => {
                if (typeof a === 'string') return a.toLowerCase();
                if (a.hasOwnProperty('left') && a.hasOwnProperty('right')) {
                    return (String(a.left) + ':' + String(a.right)).toLowerCase();
                }
                return '';
            });
        }
    }

    // Partial check for GroupSort
    if (userAnswers.length === 1 && correctAnswers.length > 1) {
        return correctAnswers.includes(userAnswers[0]);
    }

    // Full check
    if (userAnswers.length === correctAnswers.length) {
        return userAnswers.every((ans, index) => ans === correctAnswers[index]);
    }

    return false;
};

// ========== AUDIO ==========

SenaSDK.prototype.playVoice = function (type) {
    let self = this;
    let textToSpeak = '';
    
    if (type.startsWith('option')) {
        const optionIndex = parseInt(type.slice(6)) - 1;
        textToSpeak = self.getOptionsValue(optionIndex);
    } else if (type === 'question') {
        textToSpeak = self.getQuestionValue();
    } else if (type === 'request') {
        textToSpeak = self.getRequestValue();
    } else if (type === 'hint') {
        const hintValue = self.getHintValue();
        if (typeof hintValue === 'string') {
            textToSpeak = hintValue;
        }
    }
    
    if (textToSpeak === '') return;
    
    if (window['audioPlayer']) {
        window['audioPlayer'].pause();
        window['audioPlayer'].src = textToSpeak;
        window['audioPlayer'].play();
    } else {
        window['audioPlayer'] = new Audio(textToSpeak);
        window['audioPlayer'].play();
    }
};

// ========== POSTMESSAGE ==========

SenaSDK.prototype.registerPostMessageListener = function () {
    let self = this;

    window.addEventListener("message", function (event) {
        if (!event.data || !event.data.type) return;

        switch (event.data.type) {
            case "SERVER_PUSH_DATA":
                console.log('📥 Sena SDK: Received SERVER_PUSH_DATA');
                
                if (self._postMessageTimeout) {
                    clearTimeout(self._postMessageTimeout);
                    self._postMessageTimeout = null;
                }
                self._waitingForPostMessage = false;

                // Nếu trước đó load bằng server rồi
                if (self._dataLoadedFromServer && !self._gameStartedByUser) {
                    console.log('🔄 PostMessage late, reloading data');
                    self.postMessageDataLoaded = false;
                    self._dataLoadedFromServer = false;
                }

                if (self._gameStartedByUser) {
                    console.log('⚠️ Sena SDK: PostMessage ignored (user already playing)');
                    return;
                }

                self.loadFromPostMessage(event.data.jsonData);

                if (self._loadCallback) {
                    let cb = self._loadCallback;
                    self._loadCallback = null;
                    cb(true);
                }
                break;

            case "SYNC_TIME":
                if (event.data.end_time_iso) {
                    let endTimeDate = new Date(event.data.end_time_iso);
                    let now = new Date();
                    self.timeLimit = Math.max(0, Math.floor((endTimeDate - now) / 1000));
                    console.log('🎮 Sena SDK: Time synced:', self.timeLimit, 's');
                }
                break;

            case "SDK_DATA_READY":
                console.log('📥 Sena SDK: Received SDK_DATA_READY');
                self._handleSdkDataReady(event.data.payload);
                break;

            case "SDK_PUSH_DATA":
                console.log('📥 Sena SDK: Received SDK_PUSH_DATA');
                if (event.data.payload?.items) {
                    self._handleSdkPushData(event.data.payload.items);
                }
                break;

            case "SEQUENCE_SYNC": // Đổi ở đây
                console.log("📥 Sena SDK: Received SEQUENCE_SYNC", event.data);
                if (event.data.uuid === self.uuid) {
                console.log("🔄 Sena SDK: Own message echoed back, processing...");
                }
                
                if (typeof self.onCustomMessage === "function") {
                self.onCustomMessage(event.data.data, event.data.uuid);
                }
                break;

            case "SDK_ERROR":
                console.error('❌ Sena SDK: Received SDK_ERROR', event.data.payload);
                break;
        }
    });

    console.log('🎮 Sena SDK: PostMessage listener registered');
};

/**
 * Send custom message to parent window with UUID
 * @param {Object} data - Custom JSON data to send
 */
SenaSDK.prototype.sendMessageToParent = function (data) {
    let self = this;
    
    if (!data || typeof data !== 'object') {
        console.error('❌ Sena SDK: sendMessageToParent requires data object');
        return false;
    }

    let payload = {
        type: "Sequence_Sync",
        uuid: self.uuid,
        data: data,
        timestamp: Date.now()
    };

    window.parent.postMessage(payload, "*");

    console.log('📤 Sena SDK: Sent Sequence_Sync to parent');
    console.log('🔑 UUID:', self.uuid);
    console.log('📦 Data:', data);

    return true;
};

SenaSDK.prototype._handleSdkDataReady = function (payload) {
    let self = this;
    
    if (!payload?.items) {
        console.error('🎮 Sena SDK: SDK_DATA_READY missing items');
        return;
    }

    if (self._postMessageTimeout) {
        clearTimeout(self._postMessageTimeout);
        self._postMessageTimeout = null;
    }
    self._waitingForPostMessage = false;

    let items = payload.items;

    if (items.length === 1) {
        let item = items[0];
        self.data = {
            question: item.question || '',
            request: item.question || '',
            options: item.options?.map(o => o.text || o.audio || o) || []
        };
        self.gameID = item.id;
    } else {
        self.list = items.map((item, idx) => ({
            id: item.id || idx,
            question: item.question || '',
            options: item.options?.map(o => o.text || o) || [],
            answer: null
        }));
        self.totalQuestions = items.length;
        self.level = payload.completed_count || 0;
        self._loadCurrentQuestionToData();
    }

    self.postMessageDataLoaded = true;
    console.log('✅ Sena SDK: SDK_DATA_READY processed');

    if (self._loadCallback) {
        self._loadCallback(true);
        self._loadCallback = null;
    }
};

SenaSDK.prototype._handleSdkPushData = function (items) {
    let self = this;
    
    if (!items || items.length === 0) {
        console.error('🎮 Sena SDK: SDK_PUSH_DATA missing items');
        return;
    }

    if (self._postMessageTimeout) {
        clearTimeout(self._postMessageTimeout);
        self._postMessageTimeout = null;
    }
    self._waitingForPostMessage = false;

    if (items.length === 1) {
        let item = items[0];
        self.data = {
            question: item.question || '',
            options: item.options || []
        };
        self.correctAnswer = item.answer;
        self.gameID = item.id;
    } else {
        self.list = items.map((item, idx) => ({
            id: item.id || idx,
            question: item.question || '',
            options: item.options || [],
            answer: item.answer
        }));
        self.totalQuestions = items.length;
        self.level = 0;
        self._loadCurrentQuestionToData();
    }

    self.postMessageDataLoaded = true;
    console.log('✅ Sena SDK: SDK_PUSH_DATA processed');

    if (self._loadCallback) {
        self._loadCallback(true);
        self._loadCallback = null;
    }
};

SenaSDK.prototype.getTimeSpent = function () {
    if (!this.startTime) return 0;
    return Math.floor((Date.now() - this.startTime) / 1000);
};

// ========== MULTI-QUESTION SUPPORT ==========

SenaSDK.prototype.play = function (selectedText, isTimeout) {
    let self = this;

    if (!self.currentQuestion && self.data) {
        let result = { isCorrect: false, result: 0 };
        self.end(selectedText, function (isCorrect) {
            result.isCorrect = isCorrect;
            result.result = isCorrect ? 1 : 0;
        });
        return result.result;
    }

    if (!self.currentQuestion) return 0;

    let alreadyAnswered = self.userResults.find(r => r.id === self.currentQuestion.id);
    if (alreadyAnswered) return alreadyAnswered.result;

    let isCorrect = false;
    let userChoice = null;

    if (isTimeout === true || String(isTimeout) === 'true') {
        isCorrect = false;
        userChoice = null;
    } else {
        userChoice = String(selectedText).trim();
        let correctAnswer = String(self.currentQuestion.answer).trim();
        isCorrect = (userChoice.toLowerCase() === correctAnswer.toLowerCase());
    }

    let resultValue = isCorrect ? 1 : 0;

    self.userResults.push({ id: self.currentQuestion.id, result: resultValue });

    console.log('🎮 Sena SDK: Answer Result:', resultValue);

    return resultValue;
};

SenaSDK.prototype.submitResults = function () {
    let self = this;

    let uniqueResults = [];
    let seenIds = {};
    for (let i = self.userResults.length - 1; i >= 0; i--) {
        if (!seenIds[self.userResults[i].id]) {
            uniqueResults.unshift(self.userResults[i]);
            seenIds[self.userResults[i].id] = true;
        }
    }

    let correctCount = uniqueResults.filter(r => r.result === 1).length;
    let totalScore = self.totalQuestions > 0 
        ? Math.round((correctCount / self.totalQuestions) * 100) / 10 
        : 0;
    let timeSpent = Math.floor((Date.now() - self.startTime) / 1000);

    let finalData = {
        game_id: self.gameID,
        score: totalScore,
        time_spent: timeSpent,
        correct_count: correctCount,
        total_questions: self.totalQuestions,
        details: uniqueResults
    };

    console.log('🎮 Sena SDK: Final Score:', totalScore);

    window.parent.postMessage({ 
        type: "FINAL_RESULT", 
        uuid: self.uuid,
        data: finalData 
    }, "*");

    return finalData;
};

// ========== HELPER ==========

SenaSDK.prototype.helper = {};

SenaSDK.prototype.helper.CalcObjectPositions = function (n, objectWidth, margin, maxWidth) {
    let self = this;
    self.positions = [];
    const totalWidth = n * objectWidth + (n - 1) * margin;
    const startX = (maxWidth - totalWidth) / 2;
    
    for (let i = 0; i < n; i++) {
        self.positions.push(startX + i * (objectWidth + margin) + objectWidth / 2);
    }
};

SenaSDK.prototype.helper.getPosXbyIndex = function (index) {
    if (index < 0 || index >= this.positions.length) return null;
    return this.positions[index];
};

// ========== EXPORT ==========

if (typeof module !== 'undefined' && module.exports) {
    module.exports = SenaSDK;
} else if (typeof define === 'function' && define.amd) {
    define([], function () { return SenaSDK; });
} else {
    window.SenaSDK = SenaSDK;
}
