/**
 * SenaGame SDK Loader
 *
 * Ready-to-use interface for game developers.
 * Handles SDK iframe creation, communication, and lifecycle.
 *
 * Usage:
 * ```html
 * <script src="sena-game-sdk.js"></script>
 * <script>
 *   const game = new SenaGameSDK({
 *     iframePath: '/path/to/sdk-iframe/index.html',
 *     mode: 'live',
 *     gameCode: 'G001',
 *     onReady: (sdk) => {
 *       sdk.pushData({ items: [...] });
 *     },
 *     onAnswerResult: (result) => {
 *       console.log('Answer:', result);
 *     }
 *   });
 * </script>
 * ```
 *
 * @version 1.0.0
 */
// ========================================
// MESSAGE TYPES (matching SDK)
// ========================================
const MSG = {
    // Outgoing (Game → SDK)
    INIT: 'SDK_INIT',
    PUSH_DATA: 'SDK_PUSH_DATA',
    SUBMIT_ANSWER: 'SDK_CHECK_ANSWER',
    COMPLETE_GAME: 'SDK_COMPLETE_GAME',
    GET_STATUS: 'SDK_GET_STATUS',
    // Incoming (SDK → Game)
    READY: 'SDK_READY',
    DATA_READY: 'SDK_DATA_READY',
    ANSWER_RESULT: 'SDK_ANSWER_RESULT',
    GAME_COMPLETE: 'SDK_GAME_COMPLETE',
    SESSION_STARTED: 'SDK_SESSION_STARTED',
    STATUS: 'SDK_STATUS',
    ERROR: 'SDK_ERROR',
};
// ========================================
// DEFAULT CONFIG
// ========================================
const DEFAULT_CONFIG = {
    iframePath: '../sdk-iframe/index.html',
    mode: 'preview',
    gameCode: '',
    debug: false,
    timeout: 10000,
    iframeStyle: 'position:fixed;width:1px;height:1px;left:-9999px;border:none;',
};
// ========================================
// SENA GAME SDK CLASS
// ========================================
export class SenaGameSDK {
    constructor(config) {
        this.iframe = null;
        this.isReady = false;
        this.isDataReady = false;
        this.pendingMessages = [];
        this.initResolver = null;
        this.timeoutId = null;
        this.config = { ...DEFAULT_CONFIG, ...config };
        // --- CLEANUP OLD LISTENERS ---
        // Tránh trường hợp init SDK nhiều lần bị trùng listener cũ
        const oldSDK = window._sena_game_sdk_instance;
        if (oldSDK && typeof oldSDK.destroy === 'function') {
            oldSDK.destroy();
        }
        window._sena_game_sdk_instance = this;
        // Create promise for ready state
        this.initPromise = new Promise((resolve, reject) => {
            this.initResolver = { resolve, reject };
        });
        // Bind methods
        this._handleMessage = this._handleMessage.bind(this);
        // Auto-initialize
        this._init();
    }
    // ----------------------------------------
    // PUBLIC API
    // ----------------------------------------
    /**
     * Push game data to SDK
     */
    pushData(data) {
        // Safe extraction of the array
        let itemsArray = [];
        if (Array.isArray(data)) {
            itemsArray = data;
        }
        else if (data && Array.isArray(data.items)) {
            itemsArray = data.items;
        }
        else if (data && Array.isArray(data.data)) {
            itemsArray = data.data;
        }
        else if (data && data.items && typeof data.items === 'object') {
            itemsArray = [data.items];
        }
        else if (data && data.data && typeof data.data === 'object') {
            itemsArray = [data.data];
        }
        // Transform to SDK iframe internal format
        const payload = {
            data: itemsArray,
            completed_question_ids: (data && data.completed_question_ids) || []
        };
        this._send(MSG.PUSH_DATA, payload);
    }
    /**
     * Submit an answer
     */
    submitAnswer(answer) {
        // Transform to SDK iframe format
        const payload = {
            question_id: answer.questionId,
            choice: answer.selectedAnswer,
            time_spent: answer.timeSpent ?? 0
        };
        this._send(MSG.SUBMIT_ANSWER, payload);
    }
    /**
     * Complete the game
     */
    completeGame() {
        this._send(MSG.COMPLETE_GAME, {});
    }
    /**
     * Get current status
     */
    getStatus() {
        this._send(MSG.GET_STATUS, {});
    }
    /**
     * Wait for SDK to be ready
     */
    async ready() {
        if (this.isReady)
            return this;
        return this.initPromise;
    }
    /**
     * Check if SDK is ready
     */
    get sdkReady() {
        return this.isReady;
    }
    /**
     * Check if data is ready
     */
    get dataReady() {
        return this.isDataReady;
    }
    /**
     * Destroy the SDK instance
     */
    destroy() {
        window.removeEventListener('message', this._handleMessage);
        if (this.timeoutId) {
            clearTimeout(this.timeoutId);
        }
        if (this.iframe && this.iframe.parentNode) {
            this.iframe.parentNode.removeChild(this.iframe);
        }
        window.removeEventListener('message', this._handleMessage);
        this.isReady = false;
        this._log('SDK destroyed');
    }
    // ----------------------------------------
    // PRIVATE METHODS
    // ----------------------------------------
    _init() {
        this._log('Initializing SenaGameSDK...');
        // Setup message listener
        window.addEventListener('message', this._handleMessage);
        // Create iframe
        this._createIframe();
        // Setup timeout
        this.timeoutId = setTimeout(() => {
            if (!this.isReady) {
                const error = new Error('SDK initialization timeout');
                this._error(error);
                if (this.initResolver) {
                    this.initResolver.reject(error);
                }
            }
        }, this.config.timeout);
    }
    _createIframe() {
        this.iframe = document.createElement('iframe');
        this.iframe.id = 'sena-game-sdk-iframe';
        this.iframe.src = this.config.iframePath;
        this.iframe.style.cssText = this.config.iframeStyle || '';
        this.iframe.onload = () => {
            this._log('Iframe loaded, sending INIT...');
            setTimeout(() => {
                this._send(MSG.INIT, {
                    mode: this.config.mode,
                    game_code: this.config.gameCode,
                });
            }, 100);
        };
        this.iframe.onerror = () => {
            this._error(new Error('Failed to load SDK iframe'));
        };
        document.body.appendChild(this.iframe);
        this._log(`Iframe created: ${this.config.iframePath}`);
    }
    _send(type, payload) {
        if (!this.iframe || !this.iframe.contentWindow) {
            this._log(`Queuing message: ${type}`, 'warn');
            this.pendingMessages.push({ type, payload });
            return;
        }
        const message = { type, payload, timestamp: Date.now() };
        this._log(`→ ${type}`, 'send');
        this.iframe.contentWindow.postMessage(message, '*');
    }
    _handleMessage(event) {
        const data = event.data;
        if (!data || !data.type)
            return;
        // Only process SDK messages
        if (!data.type.startsWith('SDK_'))
            return;
        this._log(`← ${data.type}`, 'recv');
        switch (data.type) {
            case MSG.READY:
                this._onSDKReady();
                break;
            case MSG.DATA_READY:
                this._onDataReady(data.payload);
                break;
            case MSG.ANSWER_RESULT:
                this._onAnswerResult(data.payload);
                break;
            case MSG.GAME_COMPLETE:
                this._onGameComplete(data.payload);
                break;
            case MSG.SESSION_STARTED:
                this._onSessionStart(data.payload);
                break;
            case MSG.ERROR:
                this._error(new Error(data.payload?.message || 'SDK Error'));
                break;
        }
    }
    _onSDKReady() {
        this.isReady = true;
        if (this.timeoutId) {
            clearTimeout(this.timeoutId);
            this.timeoutId = null;
        }
        // Flush pending messages
        while (this.pendingMessages.length > 0) {
            const msg = this.pendingMessages.shift();
            if (msg) {
                this._send(msg.type, msg.payload);
            }
        }
        // Callback
        if (this.config.onReady) {
            this.config.onReady(this);
        }
        // Resolve promise
        if (this.initResolver) {
            this.initResolver.resolve(this);
        }
        this._log('✅ SDK Ready!');
    }
    _onDataReady(payload) {
        this.isDataReady = true;
        // Normalize payload to camelCase
        const normalized = {
            items: payload.items || [],
            totalQuestions: payload.total_questions || payload.totalQuestions || 0,
            completedCount: payload.completed_count || payload.completedCount || 0,
            resumeData: payload.resume_data || payload.resumeData || []
        };
        if (this.config.onDataReady) {
            this.config.onDataReady(normalized);
        }
        this._log(`✅ Data Ready: ${normalized.items.length} items`);
    }
    _onAnswerResult(payload) {
        const normalized = {
            questionId: payload.question_id || payload.questionId,
            isCorrect: payload.correct !== undefined ? payload.correct : payload.isCorrect,
            correctAnswer: payload.correct_answer || payload.correctAnswer || '',
            score: payload.score || 0,
            currentScore: payload.current_score || payload.currentScore || 0,
            totalAnswered: payload.total_answered || payload.totalAnswered || 0
        };
        if (this.config.onAnswerResult) {
            this.config.onAnswerResult(normalized);
        }
    }
    _onGameComplete(payload) {
        const normalized = {
            success: payload.success !== undefined ? payload.success : true,
            finalScore: payload.score !== undefined ? payload.score : (payload.finalScore || 0),
            correctCount: payload.correct !== undefined ? payload.correct : (payload.correctCount || 0),
            totalQuestions: payload.total !== undefined ? payload.total : (payload.totalQuestions || 0),
            wrongCount: payload.wrong !== undefined ? payload.wrong : (payload.wrongCount || 0),
            total: payload.total || 0
        };
        if (this.config.onGameComplete) {
            this.config.onGameComplete(normalized);
        }
    }
    _onSessionStart(payload) {
        const normalized = {
            assignmentId: payload.assignment_id || payload.assignmentId,
            userId: payload.student_id || payload.userId,
            gameId: payload.game_code || payload.gameId,
            startedAt: payload.started_at || payload.startedAt || new Date().toISOString()
        };
        if (this.config.onSessionStart) {
            this.config.onSessionStart(normalized);
        }
    }
    _error(error) {
        this._log(`❌ Error: ${error.message}`, 'error');
        if (this.config.onError) {
            this.config.onError(error);
        }
    }
    _log(message, type = 'info') {
        if (!this.config.debug)
            return;
        const prefix = '[SenaGameSDK]';
        const styles = {
            info: 'color: #888',
            send: 'color: #ff0',
            recv: 'color: #0f0',
            warn: 'color: #fa0',
            error: 'color: #f00',
        };
        console.log(`%c${prefix} ${message}`, styles[type] || styles.info);
    }
}
/** SDK version */
SenaGameSDK.VERSION = '1.0.0';
// ========================================
// EXPORT FOR BROWSER (UMD)
// ========================================
if (typeof window !== 'undefined') {
    window.SenaGameSDK = SenaGameSDK;
}
export default SenaGameSDK;
//# sourceMappingURL=SenaGameSDK.js.map