using CycleGUI;

namespace StandardScene.Utils
{
    /// <summary>
    /// CycleGUI 通用 UI 小工具：把多个界面都会用到的轻量对话框收敛到一处，避免各处各写一套（不造重复轮子）。
    /// <para>注意：同一 <c>Panel.Define</c> 内所有控件的 label 文本必须唯一（含 <c>pb.Table</c> 列头），
    /// 否则 ImGui 会抛 <c>Duplicated id</c>。编辑区 label 建议加 ASCII 序号前缀（如 <c>1. IP</c>），
    /// 且勿与表格列头同名。</para>
    /// </summary>
    public static class CycleUiHelper
    {
        /// <summary>
        /// 非阻塞二次确认对话框：用户点「确认」后，在<b>当前(渲染)线程</b>同步执行 <paramref name="onConfirm"/>。
        /// 若 <paramref name="onConfirm"/> 含文件 IO / 锁等耗时操作，调用方应自行用 <c>Task.Run</c> 包裹，
        /// 避免阻塞渲染线程导致界面卡死。
        /// </summary>
        public static void ConfirmThen(string message, System.Action onConfirm)
        {
            // 不用 Modal：CycleGUI 原生「模态弹窗 + 标题栏关闭X」存在 BeginPopupModal/EndPopup 配对 bug
            //（X 关闭时 BeginPopupModal 返回 false 仍调用 EndPopup → ImGui 断言 "Calling End() too many times!" 崩溃）。
            // 改为置顶非模态：用 Begin/End 路径，X 关闭干净，效果等同点「取消」。
            var dlg = GUI.DeclarePanel()
                .ShowTitle("确认")
                .TopMost(true)
                .InitSize(380, 150)
                .InitPos(false, 0, 0, 0.5f, 0.5f, 0.5f, 0.5f);
            dlg.Define(pb =>
            {
                if (pb.Closing())
                {
                    dlg.Exit();
                    return;
                }

                pb.Label(message);
                pb.Separator();
                if (pb.Button("确认", distinct: "cycleui-confirm-ok"))
                {
                    dlg.Exit();
                    onConfirm();
                }
                pb.SameLine(8);
                if (pb.Button("取消", distinct: "cycleui-confirm-cancel"))
                    dlg.Exit();
            });
        }

        /// <summary>非阻塞文件选择对话框，替代 WinForms <c>OpenFileDialog</c>。</summary>
        public static void PickOpenFile(string label, string filter, System.Action<string> onPicked)
        {
            var dlg = GUI.DeclarePanel()
                .ShowTitle("选择文件")
                .TopMost(true)
                .InitSize(420, 120)
                .InitPos(false, 0, 0, 0.5f, 0.5f, 0.5f, 0.5f);
            dlg.Define(pb =>
            {
                if (pb.Closing()) { dlg.Exit(); return; }
                if (pb.OpenFile(label, filter, out var path))
                {
                    dlg.Exit();
                    onPicked?.Invoke(path);
                }
            });
        }

        /// <summary>非阻塞提示对话框。</summary>
        public static void Alert(string title, string message)
        {
            var dlg = GUI.DeclarePanel()
                .ShowTitle(title)
                .TopMost(true)
                .InitSize(380, 150)
                .InitPos(false, 0, 0, 0.5f, 0.5f, 0.5f, 0.5f);
            dlg.Define(pb =>
            {
                if (pb.Closing())
                {
                    dlg.Exit();
                    return;
                }

                pb.Label(message);
                pb.Separator();
                if (pb.Button("确定", distinct: "cycleui-alert-ok"))
                    dlg.Exit();
            });
        }
    }
}
