(function(){
    const KEY = 'studio_theme';
    const LEGACY_KEY = 'canvas_theme';
    const SCALE_KEY = 'studio_ui_scale_mode';
    const SCALE_OPTIONS = ['auto', '100', '115', '125', '140'];
    const ALERT_MESSAGE_TYPE = 'studio-ui-alert';
    const alertQueue = [];
    let alertVisible = false;

    function nestedErrorText(value){
        if(!value) return '';
        if(typeof value === 'string') return value;
        if(typeof value !== 'object') return String(value);
        return nestedErrorText(
            value.detail ||
            value.error?.message ||
            value.error ||
            value.message ||
            value.msg
        );
    }

    function parseEmbeddedError(text){
        const start = text.indexOf('{');
        if(start < 0) return '';
        const candidate = text.slice(start).trim();
        try {
            return nestedErrorText(JSON.parse(candidate));
        } catch(e) {
            return '';
        }
    }

    function normalizeAlertMessage(value){
        let text = value instanceof Error ? value.message : nestedErrorText(value);
        text = String(text || '操作失败，请稍后重试').trim();
        const embedded = parseEmbeddedError(text);
        if(embedded) text = embedded;
        const nested = parseEmbeddedError(text);
        if(nested) text = nested;

        const quota = text.match(/user quota:\s*\$?\s*([0-9.]+).*?need quota:\s*\$?\s*([0-9.]+)/i);
        if(/pre-consumed quota failed|insufficient_quota/i.test(text)){
            text = quota
                ? `账户余额不足。当前余额：$${quota[1]}，本次需要：$${quota[2]}。`
                : '账户余额不足，请充值或更换可用的 API Key 后重试。';
        }

        return text
            .replace(/https?:\/\/(?:127\.0\.0\.1|localhost)(?::\d+)?/gi, '')
            .replace(/\s*\(request id:[^)]+\)/gi, '')
            .replace(/\s*request id:\s*[^\s,，。]+/gi, '')
            .replace(/^\s*(上游[^：:]{0,24}(?:错误|失败)|接口错误)\s*[：:]\s*/i, '')
            .trim()
            .slice(0, 1200) || '操作失败，请稍后重试';
    }

    function alertTitle(message){
        return /失败|错误|异常|不足|无效|error|failed|invalid|denied/i.test(message)
            ? '操作失败'
            : '提示';
    }

    function ensureAlertDialog(){
        if(document.getElementById('studio-alert-overlay')) return;
        const style = document.createElement('style');
        style.id = 'studio-alert-style';
        style.textContent = `
            .studio-alert-overlay {
                position: fixed;
                inset: 0;
                z-index: 2147483647;
                display: flex;
                align-items: center;
                justify-content: center;
                padding: 28px;
                background: rgba(15, 23, 42, .28);
                backdrop-filter: blur(5px);
                opacity: 0;
                visibility: hidden;
                transition: opacity .18s ease, visibility .18s ease;
            }
            .studio-alert-overlay.open {
                opacity: 1;
                visibility: visible;
            }
            .studio-alert-dialog {
                width: min(480px, calc(100vw - 40px));
                overflow: hidden;
                border: 1px solid rgba(226, 232, 240, .95);
                border-radius: 22px;
                background: rgba(255, 255, 255, .98);
                color: #111827;
                box-shadow: 0 28px 80px rgba(15, 23, 42, .22);
                transform: translateY(12px) scale(.98);
                transition: transform .18s ease;
            }
            .studio-alert-overlay.open .studio-alert-dialog {
                transform: translateY(0) scale(1);
            }
            .studio-alert-head {
                display: flex;
                align-items: center;
                gap: 12px;
                padding: 22px 24px 12px;
                font-size: 18px;
                font-weight: 750;
            }
            .studio-alert-icon {
                display: grid;
                place-items: center;
                width: 34px;
                height: 34px;
                flex: 0 0 auto;
                border-radius: 11px;
                color: #b45309;
                background: #fff7ed;
                font-size: 20px;
                font-weight: 800;
            }
            .studio-alert-message {
                min-height: 76px;
                max-height: min(42vh, 320px);
                overflow: auto;
                padding: 8px 24px 24px;
                color: #4b5563;
                font-size: 14px;
                line-height: 1.75;
                white-space: pre-wrap;
                overflow-wrap: anywhere;
                user-select: text;
            }
            .studio-alert-actions {
                display: flex;
                justify-content: flex-end;
                padding: 16px 20px 20px;
                border-top: 1px solid #eef1f5;
                background: #fafbfc;
            }
            .studio-alert-confirm {
                min-width: 92px;
                height: 42px;
                padding: 0 22px;
                border: 0;
                border-radius: 12px;
                color: #fff;
                background: #111827;
                font: inherit;
                font-size: 14px;
                font-weight: 700;
                cursor: pointer;
                box-shadow: 0 8px 18px rgba(17, 24, 39, .16);
            }
            .studio-alert-confirm:hover { background: #1f2937; }
            .studio-alert-confirm:focus-visible {
                outline: 3px solid rgba(59, 130, 246, .3);
                outline-offset: 2px;
            }
            html.studio-theme-dark .studio-alert-overlay {
                background: rgba(0, 0, 0, .54);
            }
            html.studio-theme-dark .studio-alert-dialog {
                border-color: #303744;
                background: #171b22;
                color: #f8fafc;
                box-shadow: 0 28px 90px rgba(0, 0, 0, .5);
            }
            html.studio-theme-dark .studio-alert-icon {
                color: #fbbf24;
                background: rgba(245, 158, 11, .12);
            }
            html.studio-theme-dark .studio-alert-message { color: #b8c0cc; }
            html.studio-theme-dark .studio-alert-actions {
                border-color: #2a303b;
                background: #14181e;
            }
            html.studio-theme-dark .studio-alert-confirm {
                color: #111827;
                background: #f8fafc;
            }
        `;
        document.head.appendChild(style);

        const overlay = document.createElement('div');
        overlay.id = 'studio-alert-overlay';
        overlay.className = 'studio-alert-overlay';
        overlay.setAttribute('role', 'presentation');
        overlay.innerHTML = `
            <section class="studio-alert-dialog" role="alertdialog" aria-modal="true" aria-labelledby="studio-alert-title" aria-describedby="studio-alert-message">
                <div class="studio-alert-head">
                    <span class="studio-alert-icon" aria-hidden="true">!</span>
                    <span id="studio-alert-title"></span>
                </div>
                <div id="studio-alert-message" class="studio-alert-message"></div>
                <div class="studio-alert-actions">
                    <button type="button" class="studio-alert-confirm">确认</button>
                </div>
            </section>
        `;
        document.body.appendChild(overlay);
        overlay.querySelector('.studio-alert-confirm').addEventListener('click', closeAlertDialog);
        overlay.addEventListener('click', event => {
            if(event.target === overlay) closeAlertDialog();
        });
        document.addEventListener('keydown', event => {
            if(alertVisible && (event.key === 'Escape' || event.key === 'Enter')){
                event.preventDefault();
                closeAlertDialog();
            }
        });
    }

    function showNextAlert(){
        if(alertVisible || !alertQueue.length || !document.body) return;
        ensureAlertDialog();
        const message = alertQueue.shift();
        const overlay = document.getElementById('studio-alert-overlay');
        document.getElementById('studio-alert-title').textContent = alertTitle(message);
        document.getElementById('studio-alert-message').textContent = message;
        alertVisible = true;
        overlay.classList.add('open');
        setTimeout(() => overlay.querySelector('.studio-alert-confirm')?.focus(), 30);
    }

    function closeAlertDialog(){
        const overlay = document.getElementById('studio-alert-overlay');
        if(overlay) overlay.classList.remove('open');
        alertVisible = false;
        setTimeout(showNextAlert, 190);
    }

    function showStudioAlert(value){
        const message = normalizeAlertMessage(value);
        if(isFramed()){
            try {
                window.top.postMessage({type: ALERT_MESSAGE_TYPE, message}, window.location.origin);
                return;
            } catch(e) {}
        }
        alertQueue.push(message);
        showNextAlert();
    }

    window.alert = showStudioAlert;
    window.StudioDialog = {
        alert: showStudioAlert,
        normalizeError: normalizeAlertMessage
    };

    function currentTheme(){
        return localStorage.getItem(KEY) || localStorage.getItem(LEGACY_KEY) || 'light';
    }

    function applyTheme(theme){
        const next = theme === 'dark' ? 'dark' : 'light';
        const dark = next === 'dark';
        document.documentElement.classList.toggle('studio-theme-dark', dark);
        document.documentElement.classList.toggle('theme-dark', dark);
        if(document.body){
            document.body.classList.toggle('studio-theme-dark', dark);
            document.body.classList.toggle('theme-dark', dark);
        }
        window.dispatchEvent(new CustomEvent('studio-theme-change', { detail: { theme: next } }));
    }

    function ensureScaleStyle(){
        if(document.getElementById('studio-scale-style')) return;
        const style = document.createElement('style');
        style.id = 'studio-scale-style';
        style.textContent = `
            html.studio-scale-managed {
                --studio-ui-scale: 1;
            }
            html.studio-ui-scaled body:not(.studio-scale-host) {
                width: calc(100% / var(--studio-ui-scale)) !important;
                min-height: calc(100vh / var(--studio-ui-scale)) !important;
                zoom: var(--studio-ui-scale);
            }
            html.studio-ui-scaled body.studio-scale-viewport:not(.studio-scale-host) {
                height: calc(100vh / var(--studio-ui-scale)) !important;
            }
            html.studio-ui-scaled body:not(.studio-scale-host) > .app-shell,
            html.studio-ui-scaled body:not(.studio-scale-host) > .shell,
            html.studio-ui-scaled body:not(.studio-scale-host) > .asset-page {
                width: calc(100% / var(--studio-ui-scale)) !important;
            }
            html.studio-ui-scaled body:not(.studio-scale-host) > .app-shell,
            html.studio-ui-scaled body:not(.studio-scale-host) > .shell {
                height: calc(100vh / var(--studio-ui-scale)) !important;
            }
            html.studio-ui-scaled body:not(.studio-scale-host) > .asset-page {
                min-height: calc(100vh / var(--studio-ui-scale)) !important;
            }
            @supports not (zoom: 1) {
                html.studio-ui-scaled body:not(.studio-scale-host) {
                    zoom: 1;
                    transform: scale(var(--studio-ui-scale));
                    transform-origin: 0 0;
                }
            }
        `;
        document.head.appendChild(style);
    }

    function isFramed(){
        try {
            return window.self !== window.top;
        } catch(e) {
            return true;
        }
    }

    function normalizeScaleMode(mode){
        return SCALE_OPTIONS.includes(mode) ? mode : 'auto';
    }

    function currentScaleMode(){
        try {
            return normalizeScaleMode(localStorage.getItem(SCALE_KEY) || 'auto');
        } catch(e) {
            return 'auto';
        }
    }

    function autoScale(){
        const dpr = Math.max(1, Number(window.devicePixelRatio || 1));
        const screenLong = Math.max(window.screen?.width || 0, window.screen?.height || 0);
        const viewportLong = Math.max(window.innerWidth || 0, window.innerHeight || 0);
        const longEdge = Math.max(screenLong, viewportLong);
        if(dpr >= 1.35) return 1;
        if(longEdge >= 3600) return 1.22;
        if(longEdge >= 3000) return 1.16;
        if(longEdge >= 2500 && dpr <= 1.15) return 1.1;
        return 1;
    }

    function scaleForMode(mode){
        const next = normalizeScaleMode(mode);
        if(next === 'auto') return autoScale();
        return Math.max(1, Math.min(1.4, Number(next) / 100));
    }

    function updateScaleBodyClasses(){
        if(!document.body) return;
        const hasFrameHost = !!document.querySelector('.app-shell iframe, iframe.active');
        document.body.classList.toggle('studio-scale-host', hasFrameHost && !isFramed());
        const computed = window.getComputedStyle(document.body);
        const viewportLocked = computed.overflow === 'hidden' || computed.overflowY === 'hidden' || !!document.querySelector('.app-shell, .shell');
        document.body.classList.toggle('studio-scale-viewport', viewportLocked);
    }

    function scaleOptedOut(){
        return document.documentElement.dataset.studioScale === 'off';
    }

    function applyScale(mode){
        ensureScaleStyle();
        const next = normalizeScaleMode(mode);
        const optedOut = scaleOptedOut();
        const value = optedOut ? 1 : scaleForMode(next);
        const scaled = !optedOut && Math.abs(value - 1) > 0.01;
        document.documentElement.classList.add('studio-scale-managed');
        document.documentElement.classList.toggle('studio-ui-scaled', scaled);
        document.documentElement.style.setProperty('--studio-ui-scale', value.toFixed(3));
        updateScaleBodyClasses();
        window.dispatchEvent(new CustomEvent('studio-ui-scale-change', { detail: { mode: next, scale: value } }));
    }

    function broadcastScale(mode){
        document.querySelectorAll('iframe').forEach(frame => {
            try {
                frame.contentWindow?.postMessage({ type: 'studio-ui-scale', mode }, '*');
            } catch(e) {}
        });
    }

    function setScaleMode(mode, shouldBroadcast = true){
        const next = normalizeScaleMode(mode);
        try {
            localStorage.setItem(SCALE_KEY, next);
        } catch(e) {}
        applyScale(next);
        if(shouldBroadcast) broadcastScale(next);
    }

    let resizeTimer = null;
    function scheduleAutoScaleRefresh(){
        clearTimeout(resizeTimer);
        resizeTimer = setTimeout(() => {
            if(currentScaleMode() === 'auto') {
                applyScale('auto');
                broadcastScale('auto');
            }
        }, 160);
    }

    window.StudioTheme = {
        key: KEY,
        get: currentTheme,
        apply: applyTheme,
        set(theme){
            const next = theme === 'dark' ? 'dark' : 'light';
            localStorage.setItem(KEY, next);
            localStorage.setItem(LEGACY_KEY, next);
            applyTheme(next);
        }
    };

    window.StudioScale = {
        key: SCALE_KEY,
        options: SCALE_OPTIONS.slice(),
        getMode: currentScaleMode,
        getScale: () => scaleForMode(currentScaleMode()),
        apply: applyScale,
        set: setScaleMode
    };

    applyTheme(currentTheme());
    applyScale(currentScaleMode());

    document.addEventListener('DOMContentLoaded', () => {
        applyTheme(currentTheme());
        applyScale(currentScaleMode());
        showNextAlert();
    });
    window.addEventListener('message', event => {
        if(event.origin === window.location.origin && event.data?.type === ALERT_MESSAGE_TYPE){
            alertQueue.push(normalizeAlertMessage(event.data.message));
            showNextAlert();
            return;
        }
        if(event.data?.type === 'studio-theme') applyTheme(event.data.theme);
        if(event.data?.type === 'studio-ui-scale') setScaleMode(event.data.mode, false);
    });
    window.addEventListener('storage', event => {
        if(event.key === KEY || event.key === LEGACY_KEY) applyTheme(currentTheme());
        if(event.key === SCALE_KEY) applyScale(currentScaleMode());
    });
    window.addEventListener('resize', scheduleAutoScaleRefresh);
})();
