(function () {
    if (window.MelonLiteApi) return;

    function safeMessage(value) {
        const raw = String(value || '').trim();
        if (!raw) return '요청을 처리할 수 없습니다.';
        if (/(SQLSTATE|PDOException|Stack trace|Fatal error|Warning:|Notice:|Parse error|[A-Z]:[\\\/]|\/(?:Users|laragon|xampp|var|home|srv|www)\/)/i.test(raw)) {
            return '요청을 처리할 수 없습니다.';
        }
        return raw.replace(/\s+/g, ' ').slice(0, 240);
    }

    function codeFromStatus(status) {
        if (status === 401) return 'UNAUTHORIZED';
        if (status === 403) return 'FORBIDDEN';
        if (status === 404) return 'NOT_FOUND';
        if (status === 429) return 'RATE_LIMITED';
        if (status >= 500) return 'SERVER_ERROR';
        return 'INVALID_REQUEST';
    }

    async function parseResponse(response) {
        const text = await response.text();
        let payload = null;
        try {
            payload = text ? JSON.parse(text.replace(/^\uFEFF/, '')) : {};
        } catch (err) {
            payload = {
                success: false,
                error_code: codeFromStatus(response.status || 500),
                message: '서버 응답을 확인할 수 없습니다.'
            };
        }

        if (!payload || typeof payload !== 'object') payload = {};
        if (!Object.prototype.hasOwnProperty.call(payload, 'success')) {
            payload.success = response.ok;
        }
        if (!payload.success) {
            payload.error_code = String(payload.error_code || payload.code || codeFromStatus(response.status || 400)).toUpperCase();
            payload.code = payload.code || payload.error_code;
            payload.message = safeMessage(payload.message);
            if (!Object.prototype.hasOwnProperty.call(payload, 'data')) payload.data = {};
        } else {
            if (!Object.prototype.hasOwnProperty.call(payload, 'data')) payload.data = {};
            payload.message = safeMessage(payload.message || '');
        }
        if (!response.ok && payload.success) {
            payload.success = false;
            payload.error_code = codeFromStatus(response.status || 400);
            payload.code = payload.error_code;
            payload.message = safeMessage(payload.message || '요청을 처리할 수 없습니다.');
        }
        return payload;
    }

    async function request(url, options) {
        const response = await fetch(url, options || {});
        const data = await parseResponse(response);
        if (!response.ok || !data.success) {
            const error = new Error(data.message || '요청을 처리할 수 없습니다.');
            error.code = data.error_code || data.code || codeFromStatus(response.status || 400);
            error.payload = data;
            throw error;
        }
        return data;
    }

    function showApiError(error, fallback) {
        const message = safeMessage(error && error.message ? error.message : fallback);
        if (window.showToast) {
            window.showToast(message, 'error');
        } else {
            console.warn('[MelonLite]', message);
        }
    }

    window.MelonLiteApi = {
        parseResponse,
        request,
        safeMessage,
        showApiError,
        codeFromStatus
    };
})();
