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

    const state = {
        root: null,
        panel: null,
        title: null,
        message: null,
        field: null,
        input: null,
        cancel: null,
        confirm: null,
        lastFocused: null,
        queue: Promise.resolve()
    };

    function ensureRoot() {
        if (state.root) return;

        const root = document.createElement('div');
        root.className = 'tm-dialog-root';
        root.hidden = true;
        root.innerHTML = [
            '<div class="tm-dialog-backdrop" data-dialog-close="cancel"></div>',
            '<div class="tm-dialog-panel" role="dialog" aria-modal="true" aria-labelledby="tmDialogTitle">',
            '  <div class="tm-dialog-kicker">FSE RAILWAY</div>',
            '  <h3 class="tm-dialog-title" id="tmDialogTitle">系统提示</h3>',
            '  <div class="tm-dialog-message"></div>',
            '  <label class="tm-dialog-field" hidden>',
            '    <span class="tm-dialog-field-label">输入内容</span>',
            '    <input class="tm-dialog-input" type="text" />',
            '  </label>',
            '  <div class="tm-dialog-actions">',
            '    <button type="button" class="btn tm-dialog-cancel">取消</button>',
            '    <button type="button" class="btn primary tm-dialog-confirm">确定</button>',
            '  </div>',
            '</div>'
        ].join('');

        document.body.appendChild(root);

        state.root = root;
        state.panel = root.querySelector('.tm-dialog-panel');
        state.title = root.querySelector('.tm-dialog-title');
        state.message = root.querySelector('.tm-dialog-message');
        state.field = root.querySelector('.tm-dialog-field');
        state.input = root.querySelector('.tm-dialog-input');
        state.cancel = root.querySelector('.tm-dialog-cancel');
        state.confirm = root.querySelector('.tm-dialog-confirm');
    }

    function whenReady() {
        if (document.body) return Promise.resolve();
        return new Promise((resolve) => {
            document.addEventListener('DOMContentLoaded', resolve, { once: true });
        });
    }

    function normalizeOptions(type, value, fallbackValue) {
        if (value && typeof value === 'object' && !Array.isArray(value)) {
            return {
                type,
                title: value.title || (type === 'confirm' ? '请确认' : type === 'prompt' ? '请输入内容' : '系统提示'),
                message: value.message || '',
                confirmText: value.confirmText || (type === 'alert' ? '知道了' : '确定'),
                cancelText: value.cancelText || '取消',
                defaultValue: value.defaultValue == null ? '' : String(value.defaultValue),
                placeholder: value.placeholder || ''
            };
        }

        return {
            type,
            title: type === 'confirm' ? '请确认' : type === 'prompt' ? '请输入内容' : '系统提示',
            message: value == null ? '' : String(value),
            confirmText: type === 'alert' ? '知道了' : '确定',
            cancelText: '取消',
            defaultValue: fallbackValue == null ? '' : String(fallbackValue),
            placeholder: ''
        };
    }

    function setOpen(open) {
        ensureRoot();
        state.root.hidden = !open;
        state.root.classList.toggle('is-open', open);
    }

    async function showDialog(options) {
        await whenReady();
        ensureRoot();

        return new Promise((resolve) => {
            setOpen(true);

            state.lastFocused = document.activeElement instanceof HTMLElement ? document.activeElement : null;
            state.title.textContent = options.title;
            state.message.textContent = options.message;
            state.confirm.textContent = options.confirmText;
            state.cancel.textContent = options.cancelText;

            const isPrompt = options.type === 'prompt';
            const showCancel = options.type !== 'alert';

            state.field.hidden = !isPrompt;
            state.input.value = options.defaultValue || '';
            state.input.placeholder = options.placeholder || '';
            state.cancel.hidden = !showCancel;

            let settled = false;

            const close = (result, shouldRestoreFocus = true) => {
                if (settled) return;
                settled = true;
                document.removeEventListener('keydown', onKeydown, true);
                state.root.removeEventListener('click', onRootClick, true);
                setOpen(false);
                if (shouldRestoreFocus && state.lastFocused && typeof state.lastFocused.focus === 'function') {
                    window.setTimeout(() => state.lastFocused.focus(), 0);
                }
                resolve(result);
            };

            const onKeydown = (event) => {
                if (event.key === 'Escape') {
                    event.preventDefault();
                    if (options.type === 'alert') close(undefined);
                    else close(null);
                    return;
                }
                if (event.key === 'Enter') {
                    const target = event.target;
                    if (target === state.cancel) return;
                    event.preventDefault();
                    if (isPrompt) close(state.input.value);
                    else if (options.type === 'confirm') close(true);
                    else close(undefined);
                }
            };

            const onRootClick = (event) => {
                const action = event.target && event.target.getAttribute && event.target.getAttribute('data-dialog-close');
                if (action === 'cancel') {
                    if (options.type === 'alert') close(undefined);
                    else close(null);
                    return;
                }
                if (event.target === state.cancel) {
                    close(null);
                    return;
                }
                if (event.target === state.confirm) {
                    if (isPrompt) close(state.input.value);
                    else if (options.type === 'confirm') close(true);
                    else close(undefined);
                }
            };

            document.addEventListener('keydown', onKeydown, true);
            state.root.addEventListener('click', onRootClick, true);

            window.setTimeout(() => {
                if (isPrompt) state.input.focus();
                else state.confirm.focus();
            }, 0);
        }).then((result) => {
            if (options.type === 'confirm') return result === true;
            if (options.type === 'prompt') return result == null ? null : String(result);
            return undefined;
        });
    }

    function enqueue(task) {
        state.queue = state.queue.then(task, task);
        return state.queue;
    }

    const api = {
        alert(message) {
            return enqueue(() => showDialog(normalizeOptions('alert', message)));
        },
        confirm(message) {
            return enqueue(() => showDialog(normalizeOptions('confirm', message)));
        },
        prompt(message, defaultValue) {
            return enqueue(() => showDialog(normalizeOptions('prompt', message, defaultValue)));
        }
    };

    window.appDialog = api;
    window.alert = function (message) {
        return api.alert(message);
    };
    window.confirm = function (message) {
        return api.confirm(message);
    };
    window.prompt = function (message, defaultValue) {
        return api.prompt(message, defaultValue);
    };
})();
