class UiDialog {
    constructor(rootId = "uiDialog") {
        this.root = document.getElementById(rootId);
        if (!this.root) return;

        // ✅ stacking context 문제 방지: 무조건 body 직속으로 이동
        try {
            if (this.root.parentElement !== document.body) {
                document.body.appendChild(this.root);
            }
        } catch (e) {}

        this.titleEl = this.root.querySelector("#uiDialogTitle");
        this.msgEl = this.root.querySelector("#uiDialogMessage");
        this.okBtn = this.root.querySelector("#uiDialogOk");
        this.cancelBtn = this.root.querySelector("#uiDialogCancel");

        this._resolver = null;
        this._type = "alert";
        this._lastFocus = null;
        this._closePolicy = { backdrop: false, x: false, esc: false, enter: true };

        // close triggers
        this.root.addEventListener("click", (e) => {
            if (!e.target?.dataset?.uidialogClose) return;

            const isBackdrop = !!e.target.closest(".ui-dialog__backdrop");
            const isX = !!e.target.closest(".ui-dialog__x");

            if (isBackdrop && !this._closePolicy?.backdrop) return;
            if (isX && !this._closePolicy?.x) return;

            this._resolve(false);
        });

        // keyboard
        document.addEventListener("keydown", (e) => {
            if (!this.isOpen()) return;

            if (e.key === "Escape") {
                if (this._closePolicy?.esc) this._resolve(false);
                return;
            }
            if (e.key === "Enter") {
                if (this._closePolicy?.enter !== false) this._resolve(true);
                return;
            }
        });

        // 버튼 이벤트(존재할 때만)
        this.okBtn?.addEventListener("click", () => this._resolve(true));
        this.cancelBtn?.addEventListener("click", () => this._resolve(false));
    }

    // ✅ 현재 페이지 최상단 z-index 탐색 (모달 겹침 대응)
    static getTopZIndex() {
        let maxZ = 0;
        const nodes = document.querySelectorAll("body *");
        for (const el of nodes) {
            const cs = getComputedStyle(el);
            if (cs.position === "fixed" || cs.position === "absolute" || cs.position === "sticky") {
                const z = parseInt(cs.zIndex, 10);
                if (!Number.isNaN(z)) maxZ = Math.max(maxZ, z);
            }
        }
        return maxZ;
    }

    isOpen() {
        return !!this.root && this.root.classList.contains("is-open");
    }

    alert(message, options = {}) {
        return this._open("alert", message, options);
    }

    confirm(message, options = {}) {
        return this._open("confirm", message, options);
    }

    _open(type, message, options) {
        if (!this.root) return Promise.resolve(false);

        const {
            title = type === "confirm" ? "확인" : "알림",
            okText = "확인",
            cancelText = "취소",
            dangerous = false,

            // ✅ 기본: 밖 클릭/닫기(X)/ESC로 닫기 금지
            closeOnBackdrop = false,
            closeOnX = false,
            closeOnEsc = false,
            closeOnEnter = true,
        } = options;

        // ✅ 항상 최상단: DOM 마지막 + z-index 최상단
        try {
            document.body.appendChild(this.root);
            const topZ = UiDialog.getTopZIndex();
            this.root.style.zIndex = String(Math.max(300000, topZ + 10)); // 300000 안전 마진
        } catch (e) {}

        this._closePolicy = {
            backdrop: !!closeOnBackdrop,
            x: !!closeOnX,
            esc: !!closeOnEsc,
            enter: closeOnEnter !== false,
        };

        this._type = type;
        this._lastFocus = document.activeElement;

        // 요소가 없으면 조용히 실패(페이지별 차이 방어)
        if (this.titleEl) this.titleEl.textContent = title;
        if (this.msgEl) this.msgEl.textContent = message ?? "";

        if (this.okBtn) this.okBtn.textContent = okText;
        if (this.cancelBtn) this.cancelBtn.textContent = cancelText;

        // alert면 cancel 숨김
        if (this.cancelBtn) {
            this.cancelBtn.style.display = (type === "alert") ? "none" : "";
        }

        // danger 스타일
        if (this.okBtn) {
            this.okBtn.classList.toggle("ui-dialog__btn--danger", !!dangerous);
        }

        // open
        this.root.classList.add("is-open");
        this.root.setAttribute("aria-hidden", "false");
        document.documentElement.style.overflow = "hidden";

        // focus
        setTimeout(() => {
            try { this.okBtn?.focus?.(); } catch (e) {}
        }, 0);

        return new Promise((resolve) => {
            this._resolver = resolve;
        });
    }

    _resolve(ok) {
        if (!this.isOpen()) return;

        // close
        this.root.classList.remove("is-open");
        this.root.setAttribute("aria-hidden", "true");
        document.documentElement.style.overflow = "";

        const r = this._resolver;
        this._resolver = null;

        // focus restore
        try { this._lastFocus?.focus?.(); } catch (e) {}

        if (typeof r === "function") r(!!ok);
    }
}

// 전역으로 노출 (모든 페이지에서 바로 호출)
window.uiDialog = new UiDialog();


// ======================================================
// ✅ Global showMsg / clearMsg (공통 사용)
// ======================================================
(function () {
    let cachedHelpEl = null;

    function getHelpEl(opt = {}) {
        if (opt.helpId) {
            const el = document.getElementById(opt.helpId);
            if (el) return el;
        }
        if (cachedHelpEl && document.contains(cachedHelpEl)) return cachedHelpEl;
        cachedHelpEl = document.getElementById("reg_phone_help");
        return cachedHelpEl;
    }

    window.showMsg = async function (msg, opt = {}) {
        const d = Object.assign({
            type: "alert",
            title: "알림",
            okText: "확인",
            cancelText: "취소",
            dangerous: false,
            redirect: "",
            helpId: "",
            // ✅ 닫기 정책 기본값(너가 말한 “다른 공간 클릭해도 닫히지 않게”와 일치)
            closeOnBackdrop: false,
            closeOnX: false,
            closeOnEsc: false,
            closeOnEnter: true,
        }, opt || {});

        if (window.uiDialog && typeof window.uiDialog[d.type] === "function") {
            const ok = await window.uiDialog[d.type](msg || "", d);

            if (d.redirect && ok) {
                window.location.href = d.redirect;
            }

            return d.type === "confirm" ? !!ok : true;
        }

        const helpEl = getHelpEl(d);
        if (helpEl) {
            helpEl.style.display = "block";
            helpEl.textContent = msg || "";
            return true;
        }

        alert(msg || "");
        return true;
    };

    window.clearMsg = function (helpId = "") {
        const el = helpId ? document.getElementById(helpId) : getHelpEl({});
        if (!el) return;
        el.style.display = "none";
        el.textContent = "";
    };
})();


// ======================================================
// 서버 flash 자동 실행 (기존 유지)
// ======================================================
document.addEventListener("DOMContentLoaded", async () => {
    const flashEl = document.getElementById("uiDialogFlash");
    if (!flashEl || !window.uiDialog) return;

    let payload = null;
    try { payload = JSON.parse(flashEl.textContent || "{}"); } catch (e) {}
    if (!payload) return;

    const type = payload.type || "alert";
    const ok = await window.uiDialog[type](payload.message || "", payload);

    if (type === "confirm") {
        if (ok && payload.redirect) window.location.href = payload.redirect;
    } else {
        if (payload.redirect) window.location.href = payload.redirect;
    }
});
