<template>
  <div class="editor">
    <draggable
      v-model="comList"
      @add="onAdd"
      @update="onDragEnd"
      @end="onDragComplete"
      group="itxst"
      animation="300"
      :style="draggableStyle"
      handle=".drag-handle"
      :scroll="true"
      :scrollSensitivity="100"
      :scrollSpeed="20"
    >
      <transition-group style="display: block; min-height: 100vh">
        <template v-for="(it, index) in comList">
          <div
            :key="index"
            class="layers"
            :class="comIndex == index ? 'active-layer' : ''"
          >
           <!--  <div class="drag-handle" draggable>
              <img src="@/icons/svg/drag.svg" style="width: 20px;" icon-class="drag" />
            </div> -->
            <!-- :options="categoryList":props="props" -->
           <!--  <div style="padding: 10px 0">
              <el-form label-position="left" class="inline-form">
                <el-row :gutter="24" style="margin-left: 0; margin-right: 0">
                  <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
                    <el-form-item
                      >
                      <div class="btn-save">
                        <el-tooltip
                          v-if="type !== 'document'"
                          class="item"
                          effect="dark"
                          content="保存模块"
                          placement="top"
                        >
                          <el-button
                            @click="onSaveTemplate(it)"
                            icon="el-icon-document-add"
                            circle
                          >
                          </el-button>
                        </el-tooltip>
                        <el-button
                          circle
                          v-if="it.isEdit !== 1"
                          @click="onEdit(index, 1)"
                          icon="el-icon-edit"
                        >
                        </el-button>
                        <el-button
                          circle
                          @click="onEdit(index, 2)"
                          icon="el-icon-view"
                          v-else
                        >
                        </el-button>
                        <el-tooltip
                          class="item"
                          effect="dark"
                          content="删除"
                          placement="top"
                        >
                          <el-button
                            circle
                            @click="onRemove(index)"
                            icon="el-icon-delete"
                          ></el-button
                          >
                        </el-tooltip>
                      </div>
                    </el-form-item>
                  </el-col>
                </el-row>
              </el-form>
            </div> -->
            <div class="main" @click="onSetActive(index)">
              <component
                :is="it.type"
                :ref="`component_${index}`"
                :com="it"
                :coms="comList"
                :currentIndex="index"
                :isAdmin="isAdmin"
                :insertCmd="insertCmd"
                @onUpdate="onUpdate"
                @onUpdateAttr="onUpdateAttr"
                @onUpdata="onUpdata"
                @onUpdateProdAttr="onUpdateProdAttr"
                @updateComContent="handleComContentUpdate"
                :isEdit="it.isEdit"
              />
            </div>
            <!--  <div class="label">
              {{ it.name }}
              <div class="del">
                <svg-icon
                  @click="onEdit(index, 1)"
                  v-if="it.isEdit !== 1"
                  icon-class="edit"
                  style="color: #fff; margin-right: 10px"
                />
                <svg-icon
                  @click="onEdit(index, 2)"
                  v-else
                  icon-class="view"
                  style="color: #fff; margin-right: 10px"
                />
                <svg-icon
                  @click="onRemove(index)"
                  icon-class="delete"
                  style="color: #fff; margin-left: 10px"
                />
              </div>
            </div> -->
          </div>
        </template>
        <template v-if="comList.length <= 0">
          <div class="editor-empty" :key="-1">
            <el-empty description="请拖放组件至当前页面" />
          </div>
        </template>
      </transition-group>
    </draggable>
  </div>
</template>

<script>
import draggable from "vuedraggable";
import Table from "./components/Table";
import TextArea from "./components/TextArea";
import Empty from "./components/Empty";
import {
  getAllList,
  createTemplate,
  updateTemplate,
  treeCategory,
} from "@/api/template";
export default {
  name: "editor",
  emits: [
    "onSetActiveIndex",
    "onDelete",
    "onInsert",
    "onLoadArticle",
    "onRebuild",
    "onSetComs",
  ],
  components: {
    Table,
    TextArea,
    draggable,
    Empty,
  },
  props: {
    coms: {
      type: Array,
      default: null,
    },
    comIndex: {
      type: Number,
      default: 0,
    },
    templateCate: {
      type: Array,
      default: () => {
        return [];
      },
    },
    insertCmd: {
      type: Object,
      default: null,
    },
    isAdmin: {
      type: Number,
      default: 2,
    },
  },
  watch: {
    coms: {
      async handler(val) {
        // 如果正在保存，则跳过处理
        if (this.isSaving || !val) return;

        try {
          // 处理拖拽数据，确保属性正确转换
          const processedComs = val.map((item) => {
            // 首先创建基础对象
            const processedItem = {
              ...item,
              // 确保 attrs 是数组
              dcb_attrs: Array.isArray(item.attrs)
                ? item.attrs
                : JSON.parse(item.attrs || "[]"),
              // 同步最新内容，优先使用当前显示的内容
              content: item.content || item.dcb_nr || "",
              dcb_nr: item.content || item.dcb_nr || "",
              // 确保 type 使用 dcb_type
              type: item.dcb_type || item.type,
              // 确保 name 使用 dcb_name
              name: item.dcb_name || item.name,
            };

            // 确保 content 和 dcb_nr 同步
            if (processedItem.content !== processedItem.dcb_nr) {
              processedItem.dcb_nr = processedItem.content;
            }

            return processedItem;
          });
          console.log("editor_coms:",processedComs);
          this.comList = processedComs;
          this.$emit("onSetComs:", this.comList);
        } catch (error) {
          console.error('处理组件数据时出错:', error);
        }
      },
      immediate: true,
      deep: true,
    },
    comIndex: {
      handler(val) {
        if (val <= 0) return;
        this.comList = this.comList.map((it) => {
          it.isEdit = 2;
          it.selDisabled = true;
          it.valDisabled = true;
          if (
            typeof it.category_id === "string" &&
            it.category_id.includes(" ")
          ) {
            it.category_id = it.category_id.split(" ");
          } else if (!Array.isArray(it.category_id)) {
            // 如果不是数组，将其转换为包含单个元素的数组
            it.category_id = [it.category_id].filter(Boolean);
          }
          return it;
        });
      },
      immediate: true, //立即执行
      deep: true,
    },
  },
  data() {
    return {
      showEditor: false,
      operation: "",
      id: 0,
      comList: [],
      categoryList: [],
      props: {
        value: "id",
        label: "name",
        children: "children",
        checkStrictly: true,
      },
      saveAs: false,
      draggableStyle: {
        width: "100%",

        overflowY: "auto",
      },
      type: "",
      isSaving: false, // 添加保存状态标志
    };
  },
  mounted() {
    console.log(this.$store.state);
    this.initCategoryList();
    this.type = this.$route.query.type;
    this.templateId = this.$route.query.templateId;
    this.$nextTick(() => {
      this.updateDirectoryNumbers(); // 初始化目录序号
    });
  },
  methods: {
    /* 拖拽 修改目录序号*/
    onDragComplete() {
      console.log("拖动结束");
      this.$nextTick(() => {
        this.updateDirectoryNumbers();
        this.$emit("onRebuild", this.comList);
      });
    },

    updateDirectoryNumbers() {
      let levelCounters = {};
      this.comList.forEach((module, moduleIndex) => {
        if (module.attrs) {
          module.attrs.forEach((attr) => {
            if (attr.type === "Directory") {
              const newNumber = this.generateNumberedContent(
                moduleIndex,
                attr.level,
                levelCounters
              );

              // 只更新 number 属性，完全不触及 content
              if (!attr.hasOwnProperty("number")) {
                this.$set(attr, "number", newNumber);
              } else {
                attr.number = newNumber;
              }
            }
          });
        }
      });
    },

    generateNumberedContent(moduleIndex, level, levelCounters) {
      return this.generateLevelPrefix(moduleIndex, level, levelCounters);
    },

    generateLevelPrefix(moduleIndex, level, levelCounters) {
      let prefix = [];

      for (let i = 1; i <= level; i++) {
        if (i === 1) {
          prefix.push(moduleIndex + 1);
        } else {
          if (!levelCounters[i]) {
            levelCounters[i] = 1;
          } else {
            levelCounters[i]++;
          }
          prefix.push(levelCounters[i]);
        }
      }

      return prefix.join(".");
    },

    carefulCopy(items) {
      return items.map((item) => {
        const newItem = { ...item };

        // 深拷贝 attrs 数组
        if (Array.isArray(newItem.attrs)) {
          newItem.attrs = newItem.attrs.map((attr) => ({ ...attr }));
        }

        // 深拷贝 content，如果它是一个对象或数组
        if (typeof newItem.content === "object" && newItem.content !== null) {
          newItem.content = JSON.parse(JSON.stringify(newItem.content));
        }

        // 处理特殊的 type，如 Table
        if (newItem.type === "Table") {
          newItem.tableHeader = [...newItem.tableHeader];
          newItem.tableData = newItem.tableData.map((row) => ({ ...row }));
        }

        // 保留其他属性的引用
        return newItem;
      });
    },
    handleComContentUpdate(index, updatedCom) {
      // 更新本地的 coms 数组
      this.$set(this.coms, index, updatedCom);

      // 触发父组件的更新
      this.$emit("onRebuild", this.coms);
    },
    showCategoryName(item) {
      return (
        this.type == "module" &&
        /*  this.$store.state.user.roleInfo.id == 1 && */
        !item.valDisabled
      );
    },
    enableName(item) {
      item.valDisabled = false;
      this.$forceUpdate();
    },
    showCategorySelect(item) {
      return (
        this.type === "module" &&
        /*  this.$store.state.user.roleInfo.id === 1 && */
        !item.selDisabled
      );
    },
    /* 选择分类 */
    enableSelect(item) {
      item.selDisabled = true;
      console.log(item);
      this.$forceUpdate();
    },
    /* 获取分类名称 */
    getCategory(item) {
      const findCategory = (list, id) => {
        for (const el of list) {
          if (el.id === id) {
            return el.name;
          }
          if (el.children) {
            const name = findCategory(el.children, id);
            if (name) {
              return name;
            }
          }
        }
        return null;
      };

      return findCategory(this.categoryList, item) || "请选择分类";
      /* return (
        this.categoryList.find((el) => el.id === item)?.name || "请选择分类"
      ); */
    },
    onSaveAs(e) {
      this.saveAs = true;
      this.onSaveTemplate(e);
    },
    /* 保存模块 */
    onSaveTemplate(e) {
      let _this = this;
      // 创建一个新对象来存储过滤后的数据
      let data = {};

      // 遍历原始对象，只保留 dcb_ 开头的属性
      Object.keys(e).forEach((key) => {
        if (key.startsWith("dcb_")) {
          data[key] = e[key];
        }
      });

      // 特殊字段映射
      data.dcb_nr = e.content;
      data.dcb_attrs = JSON.stringify(e.attrs);
      data.dcb_type = e.type;
      data.dcb_name = e.name; // 如果需要保存名称

      // 处理分类ID
      if (Array.isArray(e.category_id)) {
        data.category_id = e.category_id[e.category_id.length - 1];
      } else {
        data.category_id = e.category_id;
      }

      data.status = 5;

      // 根据是否存在 dcb_id 决定创建还是更新
      if (e.dcb_id == undefined || this.saveAs) {
        createTemplate(data).then((res) => {
          if (res.code != 200) return;
          e.id = res.data;
          _this.$alert("模块信息保存成功");
          _this.$emit("onRefresh");
          this.saveAs = false;
          e.selDisabled = false;
          e.valDisabled = false;
          this.$forceUpdate();
        });
      } else {
        updateTemplate(data).then((res) => {
          if (res.code != 200) return;
          _this.$alert("模块信息更新成功");
          _this.$emit("onRefresh");
          e.selDisabled = false;
          e.valDisabled = false;
          this.$forceUpdate();
        });
      }
    },
    /* 获取模块分类 */
    //获取模板分类信息
    async initCategoryList() {
      let _this = this;
      let res = await treeCategory(); //await getAllList();
      console.log(res);
      this.categoryList =
        res.data; /* //this.processDataForCascader(res.data); */
    },
    processDataForCascader(data) {
      console.log("Raw data:", data); // 调试原始数据
      const idMap = new Map();
      const rootItems = [];

      // First pass: create a map of all items
      data.forEach((item) => {
        const processedItem = { ...item, children: [] };
        idMap.set(item.id, processedItem);
      });

      // Second pass: build the tree structure
      data.forEach((item) => {
        if (item.parent_id === "0" || item.parent_id === 0) {
          rootItems.push(idMap.get(item.id));
        } else {
          const parent = idMap.get(parseInt(item.parent_id));
          if (parent) {
            parent.children.push(idMap.get(item.id));
          } else {
            console.warn(
              `Parent with id ${item.parent_id} not found for item:`,
              item
            );
            rootItems.push(idMap.get(item.id)); // 如果找不到父项，作为根项添加
          }
        }
      });

      console.log("Processed data:", rootItems); // 调试处理后的数据
      return rootItems;
    },
    onChangeCategory(item, value) {
      const selectedId = value[value.length - 1];
      item.category_id = selectedId;
      // You can now use the selected ID as needed
    },
    //更新产品属性
    onUpdateProdAttr(comIndex, attrIndex, data) {
      this.comList[comIndex].attrs[attrIndex].content = data;

      let attrName = this.comList[comIndex].attrs[attrIndex].attrs.name;
      let attrType = this.comList[comIndex].attrs[attrIndex].attrs.type;

      for (var i = 0; i < this.comList.length; i++) {
        for (var j = 0; j < this.comList[i].attrs.length; j++) {
          if (this.comList[i].attrs[j].type == "ProductAttr") {
            if (
              this.comList[i].attrs[j].attrs.name == attrName &&
              this.comList[i].attrs[j].attrs.type == attrType
            ) {
              this.comList[i].attrs[j].content = data;
            }
          }
        }
      }
      this.$emit("onRebuild", this.comList);
    },

    onUpdateAttr(comIndex, attrIndex, data) {
      console.log(comIndex, attrIndex, data);
      this.comList[comIndex].attrs[attrIndex].content = data;

      let dataType = this.comList[comIndex].attrs[attrIndex].type;
      let dataId = this.comList[comIndex].attrs[attrIndex].data;

      for (var i = 0; i < this.comList.length; i++) {
        for (var j = 0; j < this.comList[i].attrs.length; j++) {
          if (
            this.comList[i].attrs[j].type == dataType &&
            this.comList[i].attrs[j].id == dataId
          ) {
            this.comList[i].attrs[j].content = data;
          }
        }
      }
      this.$emit("onRebuild", this.comList);
    },
    /* 修改单个值 */
    onUpdata(comIndex, attrIndex, attrId, data, type) {
      let _this = this;
      let com = _this.coms[comIndex];

      if (type === "variableNull") {
        // 只更新特定的 variableNull 属性
        if (
          com &&
          com.attrs &&
          com.attrs[attrIndex] &&
          com.attrs[attrIndex].id === attrId
        ) {
          this.$set(com.attrs[attrIndex], "content", data);
        }
      } else {
        // 原有的逻辑，更新所有相同类型的属性
        let dataType = com.attrs[attrIndex].type;
        for (var i = 0; i < _this.coms.length; i++) {
          for (var j = 0; j < _this.coms[i].attrs.length; j++) {
            if (
              _this.coms[i].attrs[j].type == dataType &&
              _this.coms[i].attrs[j].id == attrId
            ) {
              _this.coms[i].attrs[j].content = data;
            }
          }
        }
      }

      _this.$emit("onRebuild", _this.coms);
    },
    onRemove(index) {
      this.$confirm("此操作将删除该模块, 是否继续?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(() => {
          this.$emit("onDelete", index);
        })
        .catch(() => {
          this.$message({
            type: "info",
            message: "已取消删除",
          });
        });
    },
    async onEdit(e, state) {
      try {
        // 如果是切换到预览模式
        if (state === 2) {
          this.isSaving = true;
          
          // 获取组件引用并添加详细日志
          const componentRef = this.$refs[`component_${e}`];
          console.log("componentRef:", componentRef);
          
          // 检查组件引用是否正确
          if (!componentRef || !componentRef[0]) {
            console.error(`组件引用获取失败: component_${e}`);
            throw new Error('组件引用不存在');
          }

          // 检查 save 方法是否存在
          if (typeof componentRef[0].save !== 'function') {
            console.error('组件没有 save 方法:', componentRef[0]);
            throw new Error('组件 save 方法不存在');
          }

          try {
            // 1. 等待组件内容保存
            console.log('开始保存组件内容...');
            await componentRef[0].save();
            console.log('组件内容保存完成');
            
            // 2. 等待父组件的更新完成
            console.log('开始更新父组件...');
            await new Promise(resolve => {
              this.$nextTick(async () => {
                await this.$emit("onRebuild", this.comList);
                resolve();
              });
            });
            console.log('父组件更新完成');
            
            // 3. 更新编辑状态
            console.log('更新编辑状态...');
            this.$set(this.comList[e], 'isEdit', 2);
            
            // 4. 确保视图更新完成
            await this.$nextTick();
            console.log('视图更新完成');
            
          } catch (error) {
            console.error('保存过程中出错:', error);
            this.$message.error('保存失败：' + error.message);
            throw error;
          }
        } else {
          // 编辑模式的处理...
          console.log('切换到编辑模式...');
          this.comList = this.comList.map((it, index) => {
            it.isEdit = 2;
            if (index === e && state === 1) {
              this.filterAttrs(it);
            }
            return it;
          });

          if (state === 1) {
            this.comList[e].isEdit = 1;
            this.onSetActive(e);
          }
        }

        // 触发重建
        await this.$emit("onRebuild", this.comList);
        console.log('重建完成');

      } catch (error) {
        console.error('切换模式失败:', error);
        this.$message.error('切换模式失败：' + error.message);
      } finally {
        this.isSaving = false;
        console.log('操作完成，isSaving 重置为 false');
      }
    },

    // 新增 filterAttrs 方法
    filterAttrs(item) {
      // 从 content 中提取所有 {{}} 包裹的 ID
      const contentIds = (item.dcb_nr.match(/{{([^}]+)}}/g) || []).map(
        (match) => match.slice(2, -2).trim()
      );

      // 过滤 attrs，只保留在 content 中出现的 ID
      item.attrs = item.attrs.filter((attr) => contentIds.includes(attr.id));
    },
    onAdd(e) {
      e.preventDefault();
      e.stopPropagation();
      this.$emit("onRebuild", this.comList);
    },
    onDragEnd(e) {
      e.preventDefault();
      e.stopPropagation();
      this.$emit("onRebuild", this.comList);
    },
    onUpdate(index, content) {
      let _this = this;
      this.coms[index].content = content;
      // 触发父组件的更新
      this.$emit("onRebuild", this.coms);
    },
    //激活当前层
    onSetActive(e) {
      this.$emit("onSetActiveIndex", e);
    },
    // 添加一个辅助方法来验证组件引用
    validateComponentRef(ref, index) {
      if (!ref) {
        throw new Error(`组件引用为空 (index: ${index})`);
      }
      if (!Array.isArray(ref)) {
        throw new Error(`组件引用不是数组 (index: ${index})`);
      }
      if (!ref[0]) {
        throw new Error(`组件引用数组为空 (index: ${index})`);
      }
      if (!ref[0].save) {
        throw new Error(`组件没有 save 方法 (index: ${index})`);
      }
    }
  },
};
</script>
<style lang="scss">
@import "./editor.scss";
.layers {
 // margin-left: 26px;
  .drag-handle {
    position: absolute;
    top: 0;
    left: -27px;
    cursor: move;
    padding: 0 5px;
    display: flex;
    align-items: center;
    /*  background-color: #f0f0f0; */

    &:hover {
      /*  background-color: #e0e0e0; */
    }
  }

  .content-wrapper {
    flex-grow: 1;
    display: flex;
    flex-direction: column;
  }

  .main {
    flex-grow: 1;
  }
}
.inline-form {
  display: block;
  width: 100%;
  /* flex-wrap: wrap;
  gap: 10px; */
}

.inline-form .el-form-item {
  display: flex;
  align-items: center;
  margin-bottom: 0;
  flex: 1;
  min-width: 300px;
}

.inline-form .el-form-item__label {
  flex-shrink: 0;
  width: auto;
  padding-right: 12px;
}

.inline-form .el-form-item__content {
  flex-grow: 1;
  margin-left: 0 !important;
}
.input-item {
  width: 200px;
}
</style>
