<template>
  <div>
    <process-return-toolbar @addTag="addTag"></process-return-toolbar>
    <div
      contenteditable="true"
      :id="editorName + suffix"
      class="editor"
      @blur="saveResult"
    ></div>
    <el-dialog v-model="editDialog" width="70%" :destroy-on-close="true">
      <process-container
        :id="editId"
        v-if="editType == returnToolType.process"
      ></process-container>
      <calc-container
        :id="editId"
        v-else-if="editType == returnToolType.calc"
      ></calc-container>
    </el-dialog>
  </div>
</template>
<script lang="ts">
import { Options, Vue } from "vue-class-component";
import { Prop } from "vue-property-decorator";
import { returnToolType } from "@/enums/process";
import { assemble } from "@/model/Process";
@Options({})
export default class container extends Vue {
  @Prop({
    default: new assemble(),
    type: assemble,
  })
  public html!: IAssemble;
  @Prop({
    default: "",
    type: String,
  })
  public id!: string;
  @Prop({
    default: 0,
    type: Number,
  })
  public index!: number;
  public suffix = new Date().getTime().toString();
  @Prop({
    default: false,
    type: Boolean,
  })
  public isDialog!: boolean;
  public editorName = "editor";
  public editDialog = false;
  public editType = returnToolType.attribute;
  public returnToolType = returnToolType;
  public editId = "";
  public range: any = null;
  // @Watch("html.result", { immediate: true, deep: true })
  // onChanged() {
  //   this.initTag();
  // }
  mounted() {
    this.editId = this.id;
    this.initTag();
    // return edit.innerHTML;
  }
  initTag(html?: string) {
    let _this = this;
    html = html !== null && html !== undefined ? html : this.html.return;
    const edit = document.querySelector(
      "#" + _this.editorName + _this.suffix
    ) as HTMLElement;
    if (edit) {
      //   var frag = document.createDocumentFragment();
      //   frag.append(_this.node);
      edit.innerHTML = html;
      //   = this.node;
      for (let i = 0; i < edit.children.length; i++) {
        for (let j = 0; j < edit.children[i].children.length; j++) {
          edit.children[i].children[j].addEventListener("click", function (e) {
            const parent = (e.target as HTMLElement).parentNode;
            parent?.parentNode?.removeChild(parent);
            edit.blur();
          });
        }
        edit.children[i].addEventListener("dblclick", function (e) {
          let type = (e.target as HTMLElement).getAttribute("type");
          if (type) {
            switch (type) {
              case returnToolType[returnToolType.calc]:
                _this.showEditDialog(
                  (e.target as HTMLElement).id,
                  returnToolType.calc
                );
                break;
              case returnToolType[returnToolType.process]:
                _this.showEditDialog(
                  (e.target as HTMLElement).id,
                  returnToolType.process
                );
                break;
              default:
                break;
            }
          }
        });
      }
    }
  }
  // public closeDialog() {
  //   this.editDialog = false;
  // }
  public saveResult() {
    const edit = document.querySelector(
      "#" + this.editorName + this.suffix
    ) as HTMLElement;
    if (edit) {
      this.$emit("save", edit.innerHTML, this.index);

      // this.node.result = edit.innerHTML;
    }
    //console.log(edit.children);
    var selection = window.getSelection();
    // IE9 and non-IE

    if (selection) {
      if (selection.rangeCount) {
        this.range = selection.getRangeAt(0);
      }
    }
  }
  public showEditDialog(id: string, type: returnToolType) {
    this.editType = type;
    switch (type) {
      case returnToolType.attribute:
        break;
      case returnToolType.process:
      case returnToolType.calc:
        this.editId = id;
        this.editDialog = true;
        break;
    }
  }
  public getData(): string {
    const _this = this;
    const edit = document.querySelector(
      "#" + _this.editorName + _this.suffix
    ) as HTMLElement;
    if (edit) {
      return edit.innerHTML;
    }
    return "";
  }
  public addTag(data: IProcess | IAttributeValue, type: returnToolType) {
    const _this = this;
    const edit = document.querySelector(
      "#" + _this.editorName + _this.suffix
    ) as HTMLElement;
    if (edit) {
      edit.focus();
      var selection;
      selection = window.getSelection();
      // IE9 and non-IE

      if (selection) {
        if (selection.rangeCount) {
          if (!_this.range) {
            _this.range = selection.getRangeAt(0);
          }
          _this.range.deleteContents();
          var el = document.createElement("button");
          el.innerText = data.name;
          el.setAttribute("class", returnToolType[type]);
          el.setAttribute("type", returnToolType[type]);
          el.setAttribute("contenteditable", "false");
          el.setAttribute("id", data.id);
          el.addEventListener("dblclick", function () {
            _this.showEditDialog(data.id, type);
          });
          var delBtn = document.createElement("span");
          delBtn.innerText = (this as any).$lang.delete;
          delBtn.addEventListener("click", function (e) {
            const parent = this.parentNode;
            parent?.parentNode?.removeChild(parent);
            edit.blur();
          });
          el.appendChild(delBtn);
          var frag = document.createDocumentFragment(),
            laseNode;
          laseNode = frag.appendChild(el);
          _this.range.insertNode(frag);
          if (laseNode) {
            _this.range = _this.range.cloneRange();
            _this.range.setStartAfter(laseNode);
            _this.range.collapse(true);
            selection.removeAllRanges();
            selection.addRange(_this.range);
          }
        }
      }
    }
  }
}
</script>
<style lang="scss">
.editor {
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  height: 300px;
  button {
    display: inline;
    padding: 3px 5px;
    margin: 0px 2px;
    border-radius: 5px;
    border: 0px;
    color: #fff;
    cursor: default;
    &.process {
      background: blue;
      &:before {
        content: "流程：";
      }
    }
    &.attribute {
      background: green;
      &:before {
        content: "属性：";
      }
    }
    &.calc {
      background: red;
      &:before {
        content: "公式：";
      }
    }
    span {
      color: #333;
      background: white;
      border: 0px;
      padding: 2px 3px;
      border-radius: 5px;
    }
  }
}
</style>
