<template>
  <div class="custom-form-design">
    <div class="custom-form-design-inner">
      <!-- 自定义form组件 字段部分-->
      <div class="custom-form-design-fields">
        <div class="design-header fields-header">字段组件</div>
        <div class="design-main fields-main">
          <vuedraggable :list="defaultComOptions" :group="{name: 'customComGroup', pull: 'clone', put: false}" class="design-draggable-fields"
            draggable=".draggable-fields-item" ghostClass="subfield-origin-dragClass" :clone="targetComClone" :sort="false"
            :disabled="!subfieldModuleForm.subfieldModuleList.length" :move="onMove">
            <transition-group name="fade" tag="div" class="draggable-fields-list">
              <div class="draggable-fields-item" :class="{'has-no-subfield-module' : !subfieldModuleForm.subfieldModuleList.length}"
                v-for="(item,index) of defaultComOptions" :key="index" @click="fieldsItemClick">
                <img :src="require(`@/assets/images/consultingAgencyManagement/customForm/${item.comShowIcon}`)" alt="">
                <span>{{item.formAttribute.label}}</span>
              </div>
            </transition-group>
          </vuedraggable>
        </div>
      </div>
      <!-- 配置部分 -->
      <div class="custom-form-design-options">
        <div class="design-header options-header">表单配置</div>
        <div class="design-main options-main">
          <el-form class="custom-design-el-form" ref="customDesignFormRef" :model="subfieldModuleForm" @submit.native.prevent :show-message="false">

            <!-- 最外层dragg容器 拖动模块module .subfield-module-dragg-target-icon -->
            <vuedraggable :list="subfieldModuleForm.subfieldModuleList" group="customSubfieldmodule" class="subfield-module-container"
              draggable=".subfield-module-item-container" handle=".subfield-module-dragg-target-icon" :animation="340" :move="onMove">
              <!-- 添加的分栏模块以及chidren模块 -->
              <transition-group name="fade" tag="div" class="subfield-module-list">
                <vuedraggable v-for="(item,pindex) of subfieldModuleForm.subfieldModuleList" :key="item.uid" draggable=".subfield-item-container"
                  handle=".subfield-module-item-dragg-target-icon" tag="subfield-module" :list="item.children" group="customComGroup"
                  :component-data="createComponentData(item,pindex)" :animation="340" :move="onMove" ghostClass="subfield-item-dragClass" :sort="true"
                  @change="dataChange">
                  <subfield-item v-for="(child,index) of item.children" :key="child.uid" :activeUid="activeUid" :parentUid="item.uid"
                    :childModuleInfo="child" :childModuleIndex="pindex" :childItemIndex="index" @removeModuleItem="removeModuleItem"
                    @activeSubfieldItem="activeSubfieldItem"></subfield-item>
                </vuedraggable>
              </transition-group>
            </vuedraggable>
            <!-- 添加分栏 -->
            <div class="add-field-bar" @click="addSubfieldModule">
              <img src="@/assets/images/consultingAgencyManagement/customForm/icon_add@2x.png" alt="">
              <span>添加分栏</span>
            </div>
          </el-form>
        </div>
      </div>
      <!-- 字段设置 -->
      <div class="custom-form-design-field-options">
        <div class="design-header field-options-header">字段设置</div>
        <div class="design-main field-options-main">
          <set-field-option v-if="showSetOption" :activeFieldData="activeItemData" :activeFieldOrigin="activeItemDataOrigin" :activeUid="activeUid"
            :parentUid="activeModuleId" ref="setFieldOptionRef" @cancelSetOptions="cancelSetOptions" @setOptionsFinish="setOptionsFinish"
            @backfileData="backfileData"></set-field-option>
        </div>
      </div>
    </div>

    <!-- 底部 -->
    <div class="custom-form-design-footer">
      <el-button type="primary" @click="saveOptions">保存设置</el-button>
      <el-button @click="cancelCreate">取消</el-button>
    </div>

    <!-- 删除分栏提示弹窗 -->
    <el-dialog title="提示" :visible.sync="removeSubFiledModuleDialog" width="480px" :close-on-click-modal="false" class="subfield-module-dialog-outer"
      :custom-class="'subfield-module-dialog-inner'" @close="removeDialogClose">
      <div class="subfield-module-dialog-content">
        <img src="@/assets/images/consultingAgencyManagement/customForm/icon_tips@2x.png" alt="">
        <span>{{`确认删除分栏“${removeSubfieldModule.subfieldModuleName ? removeSubfieldModule.subfieldModuleName : removeSubfieldModule.defaultSubfieldModuleName ? removeSubfieldModule.defaultSubfieldModuleName : ""}”吗？`}}</span>
      </div>
      <div class="subfield-module-dialog-footer">
        <el-button size="default" @click="removeSubFiledModuleDialog = false">取消</el-button>
        <el-button type="primary" size="default" @click="removeOk">确定删除</el-button>
      </div>
    </el-dialog>

  </div>
</template>
<script>
import { defaultComOptions, subfieldModuleTemplate } from "@/utils/generator/custom-design-options";
import SubfieldItem from "@/views/consultingOrgManagement/components/CustomForm/components/SubfieldItem";
import SetFieldOption from "@/views/consultingOrgManagement/components/CustomForm/components/SetFieldOption";
import { elementMessageSingleton, jsonStrToObject } from "@/utils";
import vuedraggable from "vuedraggable";
import { v4 } from 'uuid';
import { getCustomFormDetailApi, addCustomFormDataApi } from "@/api/consultingOrgManagement";
import { cloneDeep } from "lodash-es";
import serialize from "serialize-javascript";
import Schema from "async-validator";
export default {
  name: "customFormDesign",
  components: {
    vuedraggable,
    SubfieldItem,
    SetFieldOption
  },
  data() {
    return {
      // 字段组件
      defaultComOptions,
      // 验证表单
      subfieldModuleForm: {
        // 中间编辑的模块
        subfieldModuleList: [],
      },
      olduSbfieldModuleList: [],
      // 删除分栏提示
      removeSubFiledModuleDialog: false,
      // 要删除的分栏信息
      removeSubfieldModule: {},
      // 当前选中正在编辑的组件id
      activeUid: "",
      // 编辑的组件数据
      activeItemData: {},
      // 编辑的组件原始数据
      activeItemDataOrigin: {},
      // active moduleId 当前命中的模块id
      activeModuleId: "",
      // 分栏计数
      moduleCount: 0,
      // 获取到的表单模板
      formTemplate: {}
    };
  },
  watch: {
    subfieldModuleForm: {
      handler(newValue) {
        console.log(newValue);
      },
      deep: true
    }
  },
  //可访问data属性
  created() {
    this.initModule();
  },
  beforeDestroy() {

  },
  //计算集
  computed: {
    showSetOption() {
      return this.activeUid ? true : false;
    }
  },
  //方法集
  methods: {
    async saveOptions() {
      try {
        if (this.activeUid && !this.activeItemData?.checkedAllow) {
          elementMessageSingleton("warning", "请先保存字段设置");
          return false;
        }
        /** 
         * @type {Array<{
         * defaultSubfieldModuleName : string;
         * subfieldModuleName : string;
         * edit : boolean;
         * children : Array<any>
         * }>}
        */
        const _templateTemp = cloneDeep(this.subfieldModuleForm);
        let finllyRules = {
          subfieldModuleList: {
            type: "array",
            defaultField: {
              type: "object",
              fields: {
                edit: { type: "enum", enum: [false], required: true, message: "请先保存分栏名称，当前不能处于编辑状态" },
                subfieldModuleName: { type: "string", required: true, message: "分栏名称不能为空" },
                children: {
                  type: "array",
                  defaultField: {
                    type: "object",
                    fields: {
                      formAttribute: {
                        type: "object",
                        fields: {
                          fieldName: { type: "string", required: true, message: "字段名称不能为空" },
                          label: { type: "string", required: true, message: "字段label不能为空" },
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        };
        const validatorIns = new Schema(finllyRules);
        const flag = await validatorIns.validate(_templateTemp, { first: true });
        const _tempData = cloneDeep(this.subfieldModuleForm.subfieldModuleList);
        const map = new Map();
        const len = _tempData.length;
        for (let index = 0; index < len; index++) {
          const current = _tempData[index];
          const children = current.children;
          if (children?.length) {
            for (let j = 0; j < children.length; j++) {
              const child = children[j];
              if (map.has(child.uid)) return this.$message.error(`第${index + 1}个分栏下的，第${j + 1}个表单元素字段名称重复`);
              map.set(child.uid, child);
              // 不允许默认值
              if (!child.formAttribute.allowDefaultValue) {
                child.componentAttribute.value instanceof Array ? child.componentAttribute.value = [] : child.componentAttribute.value = "";
              }
            }
          }
        }
        console.log(_tempData);
        await this.submitCustomForm({
          subfieldModuleList: _tempData
        });
      } catch (error) {
        if (error?.errors?.length) {
          // console.dir(error);
          const { errors, fields } = error;
          this.errorHandle(errors);
        }
      }
    },
    async submitCustomForm(data) {
      try {
        console.log(data);
        const params = {
          jsonData: serialize(data)
        };
        if (this.formTemplate?.templateId) params["templateId"] = this.formTemplate.templateId;
        const result = await addCustomFormDataApi(params);
        if (result.code == 200) {
          this.$message.success(`${this.formTemplate?.templateId ? "更新" : "创建"}模板成功`);
          // 更新成功重置源数据
          this.olduSbfieldModuleList = cloneDeep(this.subfieldModuleForm.subfieldModuleList);
        }
      } catch (error) {
        console.log(error);
      }
    },
    errorHandle(errors) {
      try {
        const len = errors.length;
        for (let index = 0; index < len; index++) {
          const current = errors[index];
          let keyName = current.field.split(".");
          const isModule = keyName[0] == "subfieldModuleList" ? true : false;
          if (isModule) {
            this.$message.error(`第${parseInt(keyName[1]) + 1}分栏，${current.message}`);
            return;
          }
          this.$message.error(`${current.message}`);
        }
      } catch (error) {

      }
    },
    cancelCreate() {
      this.$set(this.subfieldModuleForm, "subfieldModuleList", cloneDeep(this.olduSbfieldModuleList));
    },
    generateRandomLowerCaseLetter() {
      const alphabet = 'abcdefghijklmnopqrstuvwxyz';
      const randomIndex = Math.floor(Math.random() * alphabet.length);
      return alphabet[randomIndex];
    },
    async getCustomFormDetail() {
      try {
        const result = await getCustomFormDetailApi();
        if (result.code == 200 && result.data) {
          return result.data;
        }
        return null;
      } catch (error) {

      }
    },
    parseTemplate(templateJson) {
      try {
        const data = jsonStrToObject(templateJson);
        if (data) {
          this.$set(this.subfieldModuleForm, "subfieldModuleList", data.subfieldModuleList);
        }
      } catch (error) {
        elementMessageSingleton("error", `解析模板失败,${error.message}`);
      }
    },
    async initModule() {
      try {
        const result = await this.getCustomFormDetail();
        if (result) {
          this.formTemplate = cloneDeep(result);
        }
        if (result?.jsonData) {
          // 有模板数据 进行回显
          this.parseTemplate(result?.jsonData);
          this.olduSbfieldModuleList = cloneDeep(this.subfieldModuleForm.subfieldModuleList);
          return;
        }
        // 模块初始化
        this.addSubfieldModule();
        const component = cloneDeep(defaultComOptions[0]);
        component.uid = v4();
        component.formAttribute.fieldName = this.generateRandomLowerCaseLetter() + component.uid.split("-").join("");
        this.activeItemData = component;
        this.activeItemDataOrigin = cloneDeep(this.activeItemData);
        this.activeModuleId = this.subfieldModuleForm.subfieldModuleList[0].uid;
        this.activeUid = component.uid;
        this.subfieldModuleForm.subfieldModuleList[0].children.push(component);
        this.olduSbfieldModuleList = cloneDeep(this.subfieldModuleForm.subfieldModuleList);
      } catch (error) {

      }
    },
    onMove(e, originalEvent) {
      try {
        if (this.activeUid && !this.activeItemData?.checkedAllow) {
          elementMessageSingleton("warning", "请先保存字段设置");
          return false;
        }
        return true;
      } catch (error) {
        console.log(error);
      }
    },
    resetCurrent() {
      // 重置顺序不能变 (触发监听的顺序)
      this.activeItemData = {};
      this.activeItemDataOrigin = {};
      this.activeUid = "";
      this.activeModuleId = "";
    },
    // 克隆目标组件
    targetComClone(v) {
      const cloneTarget = cloneDeep(v);
      cloneTarget.uid = v4();
      console.log(cloneTarget);
      cloneTarget.formAttribute.fieldName = this.generateRandomLowerCaseLetter() + cloneTarget.uid.split("-").join("");
      return cloneTarget;
    },
    // 字段组件点击事件
    fieldsItemClick() {
      if (!this.subfieldModuleForm.subfieldModuleList?.length) {
        this.$message.warning("请先添加分栏");
      }
    },
    // 模块内部变化处理
    dataChange({ added, removed, moved }) {
      if (added) {
        this.currentActiveByItemId(added.element);
      }
      if (moved) {
        this.currentActiveByItemId(moved.element);
      }
    },
    // 取消当前焦点设置
    cancelSetOptions() {
      this.resetCurrent();
    },
    // 设置表单完成
    setOptionsFinish(current, parentUid) {
      const _temp = cloneDeep(current);
      _temp.checkedAllow = true;
      const index = this.subfieldModuleForm.subfieldModuleList.findIndex(item => item.uid == parentUid);
      if (index > -1) {
        const childIndex = this.subfieldModuleForm.subfieldModuleList[index].children.findIndex(child => child.uid == current.uid);
        if (childIndex > -1) {
          this.subfieldModuleForm.subfieldModuleList[index].children.splice(childIndex, 1, _temp);
          this.resetCurrent();
        }
      }
    },
    // 回档数据
    backfileData(current, parentUid) {
      const _temp = cloneDeep(current);
      const index = this.subfieldModuleForm.subfieldModuleList.findIndex(item => item.uid == parentUid);
      if (index > -1) {
        const childIndex = this.subfieldModuleForm.subfieldModuleList[index].children.findIndex(child => child.uid == current.uid);
        if (childIndex > -1) {
          this.subfieldModuleForm.subfieldModuleList[index].children.splice(childIndex, 1, _temp);
        }
      }
    },
    // 命中变化的表单元素
    currentActiveByItemId(current) {
      const _temp = current;
      _temp.checkedAllow = false;
      // 顺序不能变
      this.activeModuleId = this.subfieldModuleForm.subfieldModuleList.find(item => item?.children?.findIndex(child => child.uid == current.uid) > -1).uid;
      // 关联父级模块uid
      _temp.pid = this.activeModuleId;
      this.activeItemData = _temp;
      this.activeItemDataOrigin = _temp;
      this.activeUid = current.uid;
      console.log(this.activeModuleId, "模块uid");
      console.log(this.activeUid, "表单元素uid");
    },
    // 添加分栏
    addSubfieldModule() {
      const _temp = cloneDeep(subfieldModuleTemplate);
      _temp.uid = v4();
      this.moduleCount += 1;
      _temp.defaultSubfieldModuleName = `分栏${this.moduleCount}`;
      this.subfieldModuleForm.subfieldModuleList.push(_temp);
    },
    // 传递模块事件
    createComponentData(item, index) {
      return {
        props: {
          moduleInfo: item,
          moduleIndex: index
        },
        on: {
          "removeModule": this.removeModule,
          "editFinish": this.editFinish,
          "editModule": this.editModule
        }
      };
    },
    // 编辑模块 更新title
    editModule(module) {
      const _temp = cloneDeep(module);
      const flag = this.onMove();
      if (!flag) return;
      const index = this.subfieldModuleForm.subfieldModuleList.findIndex(item => item.uid == _temp.uid);
      if (index > -1) {
        _temp.edit = true;
        this.subfieldModuleForm.subfieldModuleList.splice(index, 1, _temp);
      }
    },
    // 编辑模块名称结束
    editFinish(module, moduleName) {
      const index = this.subfieldModuleForm.subfieldModuleList.findIndex(item => item.uid == module.uid);
      if (index > -1) {
        this.subfieldModuleForm.subfieldModuleList.splice(index, 1, { ...module, children: [...this.subfieldModuleForm.subfieldModuleList[index].children] });
      }
    },
    // 命中的模块
    activeSubfieldItem(itemModule, parentUid) {
      const flag = this.onMove();
      if (!flag) return;
      const _temp = cloneDeep(itemModule);
      _temp.checkedAllow = false;
      this.activeItemData = _temp;
      this.activeItemDataOrigin = _temp;
      this.activeUid = _temp.uid;
      this.activeModuleId = parentUid;
    },
    // 删除模块表单输入框
    removeModuleItem(itemModule, parentUid) {
      if (itemModule.uid == this.activeUid) {
        this.resetCurrent();
      }
      const parentModule = this.subfieldModuleForm.subfieldModuleList.find(item => item.uid == parentUid);
      if (parentModule) {
        const index = parentModule?.children?.findIndex(item => item.uid == itemModule.uid);
        if (index > -1) {
          parentModule?.children?.splice(index, 1);
        }
      }
    },
    // 删除分栏
    removeModule(module) {
      this.removeSubfieldModule = module;
      this.removeSubFiledModuleDialog = true;
    },
    // 确定删除分栏
    removeOk() {
      if (this.activeModuleId == this.removeSubfieldModule.uid) {
        this.activeModuleId = "";
      }
      // 查看当前命中的表单元素 是否存在于当前分栏下
      if (this.removeSubfieldModule?.children?.length) {
        const index = this.removeSubfieldModule.children.findIndex(item => item.uid == this.activeUid);
        if (index > -1) {
          this.resetCurrent();
        }
      }
      const index = this.subfieldModuleForm.subfieldModuleList.findIndex(item => item.uid == this.removeSubfieldModule.uid);
      if (index > -1) {
        this.subfieldModuleForm.subfieldModuleList.splice(index, 1);
      }
      this.removeSubFiledModuleDialog = false;
    },
    removeDialogClose() {
      this.removeSubfieldModule = {};
    },
  },
}
</script>
<style lang="scss" scoped>
.custom-form-design {
  width: 100%;
  height: 100%;

  .custom-form-design-inner {
    width: 100%;
    height: calc(100% - 48px);
    display: flex;
    /* min-width: 1140px; */

    .subfield-origin-dragClass,
    .subfield-item-dragClass {
      width: 100%;
      display: flex;
      align-items: center;
      background: rgba(0, 129, 255, 0.3);
      height: 56px;
      padding: 0px 16px;
      box-sizing: border-box;
      color: rgba(35, 35, 35, 0.8);
      font-size: 14px;
      font-weight: 400;

      .subfield-item-container {
        background: rgba(0, 129, 255, 0.3);
      }

      & > img {
        width: 16px;
        height: 16px;
        margin-right: 16px;
      }
    }

    .subfield-origin-dragClass {
      height: auto;
    }

    .design-header {
      width: 100%;
      height: 48px;
      display: flex;
      align-items: center;
      background: #f0f3fa;
      border: 1px solid #dcdfe6;
      padding: 0px 16px;
      font-size: 14px;
      font-weight: 400;
      color: rgba(35, 35, 35, 0.8);
      box-sizing: border-box;
      user-select: none;
    }

    .design-main {
      width: 100%;
      height: calc(100% - 48px);
      border: 1px solid #dcdfe6;
      border-top: none;
      padding: 16px;
      box-sizing: border-box;

      &.fields-main,
      &.options-main,
      &.field-options-main {
        overflow-y: auto;
        overflow-x: hidden;
      }

      &.options-main {
        .add-field-bar {
          display: flex;
          align-items: center;
          justify-content: center;
          width: 100%;
          height: 32px;
          border-radius: 4px;
          border: 1px solid #0081ff;
          color: #0081ff;
          box-sizing: border-box;
          font-size: 14px;
          font-weight: 400;
          cursor: pointer;
          & > img {
            width: 16px;
            height: 16px;
            margin-right: 4px;
          }
        }
      }
    }

    .design-draggable-fields {
      .draggable-fields-list {
        & > .draggable-fields-item:first-of-type {
          margin-top: 0px;
        }
        .draggable-fields-item {
          width: 148px;
          height: 46px;
          border-radius: 4px;
          border: 1px solid #dcdfe6;
          padding: 0px 16px;
          box-sizing: border-box;
          margin-top: 12px;
          cursor: move;
          user-select: none;

          &:hover {
            border-color: #0081ff;
          }

          display: flex;
          align-items: center;

          & > img {
            width: 16px;
            height: 16px;
          }

          & > span {
            color: #232323;
            font-size: 14px;
            font-weight: 400;
            line-height: 22px;
            margin-left: 8px;
          }

          &.has-no-subfield-module {
            cursor: not-allowed;
            border-color: #dcdfe6;
          }
        }
      }
    }

    .custom-form-design-fields {
      width: 180px;
      min-width: 180px;
      height: 100%;
    }

    .custom-form-design-options {
      width: calc(100% - 180px - 309px);
      min-width: calc(100% - 180px - 309px);
      height: 100%;

      .options-header,
      .options-main {
        border-left: none;
        .custom-design-el-form {
          width: 100%;
          min-height: 100%;

          /* .subfield-module-draggable-list {
            margin-bottom: 12px;
            width: 100%;
            border: 1px solid #dcdfe6;
            box-sizing: border-box;
            border-radius: 4px;
          } */
        }
      }
    }

    .custom-form-design-field-options {
      width: 309px;
      min-width: 309px;
      height: 100%;

      .field-options-header,
      .field-options-main {
        border-left: none;
      }

      .field-options-main {
        padding: 0px;
      }
    }
  }

  .custom-form-design-footer {
    height: 32px;
    margin-top: 16px;
    box-sizing: border-box;
    display: flex;
    align-items: center;
    justify-content: center;

    button {
      height: 32px;
      padding: 0px 16px;
      display: flex;
      align-items: center;
      justify-content: center;
      border-radius: 4px;
    }
  }

  ::v-deep .subfield-module-dialog-outer {
    .subfield-module-dialog-inner {
      border-radius: 4px;
      margin-top: 0px !important;
      margin: 0px;
      position: absolute;
      left: 50%;
      top: 50%;
      transform: translate(-50%, -50%);

      .el-dialog__header {
        height: 56px;
        padding: 0px 20px;
        box-sizing: border-box;
        display: flex;
        align-items: center;
        justify-content: space-between;
        border-bottom: 1px solid #eeeeee;

        .el-dialog__title {
          color: #232323;
          font-size: 16px;
          font-weight: bold;
        }

        .el-dialog__headerbtn {
          position: static;
          width: 16px;
          height: 16px;
        }
      }

      .el-dialog__body {
        padding: 0px 20px;
        box-sizing: border-box;

        .subfield-module-dialog-content {
          display: flex;
          align-items: center;
          padding: 24px 0px;
          box-sizing: border-box;

          & > img {
            width: 24px;
            height: 24px;
          }

          & > span {
            color: rgba(35, 35, 35, 0.8);
            font-size: 14px;
            font-weight: 400;
            margin-left: 16px;
          }
        }

        .subfield-module-dialog-footer {
          display: flex;
          align-items: center;
          justify-content: flex-end;
          padding: 16px 0px 24px 0px;
          box-sizing: border-box;

          button {
            height: 32px;
            padding: 0px 16px;
            display: flex;
            align-items: center;
            justify-content: center;
            border-radius: 4px;
          }
        }
      }
    }
  }
}
</style>
