// src/utils/DialogPropertyGrid.js
import { createApp, h, ref, watch } from 'vue';
import * as Cesium from 'cesium';

// 导入修改后的 PropertyGrid 组件 (现在作为 DialogPropertyGrid 的内容)
import PropertyGridContent from './PropertyGrid.vue'; // 假设文件名为 PropertyGrid.vue
import { getPropertyData } from './property';

// 用于存储当前弹窗的应用实例、容器和根组件实例，实现单例
let currentApp = null;
let currentContainer = null;
let currentWrapperInstance = null; // 存储 wrapperComponent 实例的引用

/**
 * 显示 DialogPropertyGrid 弹窗
 * @param {Cesium.Entity} entity - 获取属性的实体对象
 * @param {Function} [onSave] - 点击保存按钮后调用的回调函数，接收所有属性数据作为参数
 */
const show = (entity = null, onSave = null) => {
  // 0. 解析 data
  const data = getPropertyData(entity);

  // 如果已经有弹窗实例存在
  if (currentApp && currentWrapperInstance) {
    console.log('DialogPropertyGrid instance already exists. Updating content.');
    // 更新现有实例的数据和保存回调
    currentWrapperInstance.updateContent(data, onSave);
    return; // 退出，不再创建新实例
  }

  // 1. 创建一个临时的 DOM 容器
  currentContainer = document.createElement('div');
  // 将容器添加到 body
  document.body.appendChild(currentContainer);

  // 2. 定义清理函数
  const cleanup = () => {
    if (currentApp) {
      currentApp.unmount(); // 卸载 Vue 应用
      currentApp = null;
    }
    if (currentContainer) {
      currentContainer.remove(); // 移除 DOM 元素
      currentContainer = null;
    }
    currentWrapperInstance = null; // 清理 wrapperComponent 实例引用
    console.log('DialogPropertyGrid cleaned up.');
  };

  // 3. 创建 Vue 应用实例的根组件 (一个简单的 wrapper)
  const wrapperComponent = {
    setup() {
      // 使用 ref 来存储和响应式更新传递给 PropertyGridContent 的 props
      const componentData = ref(data);
      const onSaveCallback = ref(onSave); // 默认回调为一个空函数

      // 方法：更新数据和回调 (供外部 show 方法调用)
      const updateContent = (data, cb) => {
        componentData.value = data;
        onSaveCallback.value = cb;
        // 当数据更新时，如果弹窗之前被关闭了，这里不需要显式“显示”
        // 因为组件本身是 fixed 定位，只要 mounted 就在那里
        // 如果需要控制显隐，可以在 PropertyGridContent 内部加一个 v-show 或 v-if
        // 但为了单例和替换内容的需求，mounted/unmounted 更符合生命周期管理
      };

      // 监听 PropertyGridContent 的 save 事件
      const handlePropertyGridSave = (allPropertyData) => {
        // 调用外部传入的保存回调
        if (typeof onSaveCallback.value === 'function') {
          onSaveCallback.value(allPropertyData);
        }
        // 保存后执行清理 (关闭弹窗)
        cleanup();
      };

      // 监听 PropertyGridContent 的 close 事件
      const handlePropertyGridClose = () => {
        // 直接执行清理 (关闭弹窗)
        cleanup();
      };

       // 监听 PropertyGridContent 的 property-change 事件 (可选，如果需要在外部实时响应)
      const handlePropertyChange = (key, newValue, property) => {
          // console.log(`实时属性变更: ${property.name} = ${newValue}`);
          // 如果需要，可以在这里添加额外的实时处理逻辑
          // 注意：这个事件是 PropertyGridContent 内部实时触发的，与 save 事件不同
      };


      // 暴露 updateContent 方法给外部 show 方法调用
      return {
        updateContent, // 暴露更新方法
        componentData, // 暴露给 render 函数使用
        handlePropertyGridSave, // 暴露给 render 函数使用
        handlePropertyGridClose, // 暴露给 render 函数使用
        handlePropertyChange, // 暴露给 render 函数使用
      };
    },
    render() {
      // 渲染 PropertyGridContent 组件
      // 将响应式的 ref 作为 props 传递
      return h(PropertyGridContent, {
        data: this.componentData, // 绑定数据
        // 将回调函数作为 prop 传递
        onSaveCallback: this.handlePropertyGridSave,
        // 监听 PropertyGridContent 内部触发的 close 事件
        onClose: this.handlePropertyGridClose,
        // 监听 PropertyGridContent 内部触发的 property-change 事件 (可选)
        onPropertyChange: this.handlePropertyChange,
        // 注意：PropertyGridContent 内部的 save 事件现在直接调用了 onSaveCallback prop，
        // 所以这里不再需要监听 @save 事件。
      });
    }
  };

  // 4. 创建 Vue 应用实例并挂载
  currentApp = createApp(wrapperComponent);

  // 5. 将应用挂载到临时容器
  // 挂载后，获取根组件实例，以便后续更新数据
  currentWrapperInstance = currentApp.mount(currentContainer);

  // 6. 立即调用 updateContent 初始化并显示弹窗
  currentWrapperInstance.updateContent(data, onSave);
};

// 导出 show 方法
export default {
  show
};
