<template>
  <en-dialog
    v-if="value"
    :visible="value"
    class="en-calculation-formula"
    :class="{'dialog': type === 'dialog'}"
    :en-fullscreen="type === 'full'"
    @close="closeDialog"
  >
    <div slot="title">
      <div class="dialog-header">
        <div class="label">
          计算公式
        </div>
        <el-tooltip content="请在英文输入法模式下进行公式编辑">
          <en-icon
            name="tishi"
          >
          </en-icon>
        </el-tooltip>
      </div>
    </div>
    <div class="dialog-body">
      <div class="formula-header">
        <div class="formula-title">
          {{ title + "=" }}
        </div>
        <div class="clear-label" @click="clearFormula">
          清空
        </div>
      </div>
      <en-text-config
        ref="formula"
        mode="calculator"
      >
      </en-text-config>
    </div>
    <div class="dialog-toolbar">
      <en-tabs
        v-model="activeTab"
        :list="tabList"
        type="white"
      >
      </en-tabs>
      <div class="toolbar-container">
        <div class="toolbar-main">
          <el-input v-model="filterWords" placeholder="请输入内容" class="input-with-select">
            <el-button slot="append" icon="el-icon-search"></el-button>
          </el-input>
          <div v-if="showSearchList" class="search-area-list">
            <div
              v-for="(item,index) in filterList"
              :key="index"
              class="search-area-item"
              @click="selectItemData(item)"
            >
              {{ activeTab === "words" ? item[wordLabel] : item.name }}
            </div>
            <div v-if="filterList.length === 0" class="search-area-item" @click="filterWords = ''">
              无匹配数据
            </div>
          </div>
          <!-- 函数列表 -->
          <div v-if="activeTab === 'function' && !showSearchList" class="tree-list">
            <div
              v-for="item in list"
              :key="item.key"
              class="tree-parent"
            >
              <div class="tree-parent-info" :class="{'open':item.open}" @click="toggleItemData(item)">
                <i :class="item.open ? 'el-icon-minus' : 'el-icon-plus'"></i>
                <div class="label">
                  {{ item.name }}
                </div>
              </div>
              <en-collapse-area>
                <div v-show="item.open" class="tree-children-list">
                  <div
                    v-for="el in item.contains"
                    :key="item.key + el.name"
                    class="tree-children-item"
                    @mouseover="hoverFn(el)"
                    @click="selectFn(el)"
                  >
                    {{ el.name }}
                  </div>
                </div>
              </en-collapse-area>
            </div>
          </div>
          <!-- 字段列表 -->
          <div v-if="activeTab === 'words' && !showSearchList" class="tree-list">
            <div
              v-for="item in wordArr"
              :key="item[wordKey]"
              class="tree-parent"
            >
              <div class="tree-parent-info" :class="{'open': item.open}" @click="toggleItemData(item)">
                <i v-if="item[childrenKey]" :class="item.open ? 'el-icon-minus' : 'el-icon-plus'"></i>
                <div class="label">
                  {{ item[wordLabel] }}
                </div>
              </div>
              <en-collapse-area v-if="item.children">
                <div v-show="item.open">
                  <div
                    v-for="el in item[childrenKey]"
                    :key="el[wordKey]"
                    class="tree-parent tree-parent-item"
                  >
                    <div
                      class="tree-parent-info tree-parent-info-item"
                      :class="{'open':el.open}"
                      @click="toggleItemData(el)"
                    >
                      <i v-if="el[childrenKey]" :class="el.open ? 'el-icon-minus' : 'el-icon-plus'"></i>
                      <div class="label">
                        {{ el[wordLabel] }}
                      </div>
                    </div>
                    <en-collapse-area>
                      <div v-show="el.open" class="tree-children-list">
                        <div
                          v-for="sItem in el[childrenKey]"
                          :key="sItem[wordKey]"
                          class="tree-children-item tree-children-last"
                          @click="selectWordsInfo(sItem)"
                        >
                          {{ sItem[wordLabel] }}
                        </div>
                      </div>
                    </en-collapse-area>
                  </div>
                </div>
              </en-collapse-area>
            </div>
          </div>
        </div>
        <!-- 函数显示描述 -->
        <div v-if="methodInfo && methodInfo.name" class="toolbar-description">
          <div class="import-icon"></div>
          <div class="description">
            {{ methodInfo.name + "：" + methodInfo.explain }}
          </div>
          <div class="use-method">
            {{ methodInfo.usage }}
          </div>
          <div class="exp">
            {{ methodInfo.eg }}
          </div>
        </div>
        <!-- 字段显示描述 -->
        <div v-if="activeTab === 'words'" class="toolbar-description">
          <div class="import-icon words"></div>
          <div class="description">
            默认初始提示：从左侧面板选择字段，点击插入计算公式面板
          </div>
        </div>
      </div>
    </div>
    <!-- 底部按钮及配置 -->
    <div slot="footer">
      <div class="check">
        <el-checkbox v-model="checkStatus">
        </el-checkbox>
        <div class="label">
          计算公式值手工修改后，不再触发公式计算
        </div>
      </div>
      <en-button @click="confirm">
        确定
      </en-button>
    </div>
  </en-dialog>
</template>

<script>
import { formulaUsage } from "../../en-text-config/src/calculator/formulaUsage";

export default {
  name: "EnCalculationFormula",
  props: {
    // 是否显示弹窗
    value: {
      type: Boolean,
      default: false
    },
    // 弹窗的类型，目前只提供两种类型，一种全屏，一种弹窗
    type: {
      type: String,
      default: "dialog",
      validator: function(value) {
        return ["dialog", "full"].indexOf(value) > -1;
      }
    },
    // 计算公式的名称
    title: {
      type: String,
      default: ""
    },
    // 字段承载数组
    wordList: {
      type: String,
      default: () => {
        return [];
      }
    },
    // 字段显示的文本
    wordLabel: {
      type: String,
      default: "name"
    },
    // 字段唯一标识
    wordKey: {
      type: String,
      default: "id"
    },
    // 子级承载字段
    childrenKey: {
      type: String,
      default: "children"
    }
  },
  data() {
    return {
      code: "",
      field: "",
      activeTab: "function",
      tabList: [
        {
          id: "function",
          name: "函数"
        }, {
          id: "words",
          name: "字段"
        }
      ],
      list: [],
      treeProps: {
        children: "contains",
        label: "name"
      },
      filterWords: "",
      methodInfo: {},
      wordArr: [],
      lastSelectedData: {},
      showSearchList: false,
      filterList: [],
      checkStatus: false
    };
  },
  watch: {
    value(nVal) {
      if (nVal) {
        this.list = JSON.parse(JSON.stringify(formulaUsage));
        this.methodInfo = {};
      }
    },
    activeTab(nVal) {
      this.methodInfo = {};
      if (nVal === "function") {
        this.list = JSON.parse(JSON.stringify(formulaUsage));
      } else {
        this.wordArr = JSON.parse(JSON.stringify(this.wordList));
      }
    },
    wordList(nVal) {
      this.wordArr = JSON.parse(JSON.stringify(nVal));
    },
    filterWords(nVal) {
      if (nVal && nVal.trim() !== "") {
        this.showSearchList = true;
        this.filterSearch();
      } else if (nVal.length === 0 || nVal.trim() === "") {
        this.showSearchList = false;
      }
    },
    showSearchList(nVal) {
      if (!nVal) {
        this.filterList = [];
      }
    }
  },
  methods: {
    /**
     * @description 关闭弹窗
     */
    closeDialog() {
      this.$emit("input", false);
    },
    /**
     * @description 展开或收起指定的函数层级
     */
    toggleItemData(itemData) {
      // 只能同时展开一个节点,但是要避开两次点的都是同一个
      if (this.lastSelectedData.open && this.lastSelectedData.key !== itemData.key) {
        this.lastSelectedData.open = false;
      }
      if (itemData.open) {
        itemData.open = !itemData.open;
      } else {
        this.$set(itemData, "open", true);
      }
      this.lastSelectedData = itemData;
    },
    /**
     * @description 清空计算公式内容
     */
    clearFormula() {
      this.$refs.formula.clear();
    },
    hoverFn(fnData) {
      this.methodInfo = fnData;
    },
    /**
     * @description 选择某方法并进行回塞到窗口
     * @param fnData
     */
    selectFn(fnData) {
      this.methodInfo = fnData;
      this.$refs.formula.addMethod(fnData.name);
    },
    /**
     * @description 选择字段节点
     * @param res
     */
    selectWordsInfo(res) {
      this.$refs.formula.addField({
        id: res[this.wordKey] ? res[this.wordKey] : "",
        name: res[this.wordLabel]
      });
    },
    /**
     * @description 搜索选择
     * @param itemData
     */
    selectItemData(itemData) {
      if (this.activeTab === "function") {
        this.$refs.formula.addMethod(itemData.name);
      } else {
        this.$refs.formula.addField({
          id: itemData[this.wordKey] ? itemData[this.wordKey] : "",
          name: itemData[this.wordLabel]
        });
      }
      this.filterWords = "";
    },
    /**
     * @description 数据搜索
     */
    filterSearch() {
      const arr = this.activeTab === "function" ? JSON.parse(JSON.stringify(this.list)) : JSON.parse(JSON.stringify(this.wordList));
      this.filterList = [];
      if (this.activeTab === "function") {
        arr.map(item => {
          item.contains.map(cItem => {
            if (cItem.name.indexOf(this.filterWords.toUpperCase()) !== -1) {
              this.filterList.push({ name: cItem.name });
            }
          });
        });
      } else {
        arr.map(item => {
          if (item[this.childrenKey]) {
            item[this.childrenKey].map(cItem => {
              if (cItem[this.childrenKey]) {
                cItem[this.childrenKey].map(sItem => {
                  if (sItem[this.wordLabel].indexOf(this.filterWords.toUpperCase()) !== -1) {
                    this.filterList.push(sItem);
                  }
                });
              } else {
                if (cItem[this.wordLabel].indexOf(this.filterWords.toUpperCase()) !== -1) {
                  this.filterList.push(cItem);
                }
              }
            });
          } else {
            if (item[this.wordLabel].indexOf(this.filterWords.toUpperCase()) !== -1) {
              this.filterList.push(item);
            }
          }
        });
      }
    },
    /**
     * @description 点击确定按钮，回调数据信息
     */
    confirm() {
      this.$emit("change", {
        check: this.checkStatus,
        fields: this.$refs.formula.parsingEditor()
      });
    }
  }
};
</script>

<style lang="scss" scoped>
  .en-calculation-formula {
    .el-dialog__header {
      .dialog-header {
        display: flex;
        justify-content: flex-start;

        .en-icon {
          width: 14px;
          height: 14px;
          color: #F7BF27;
        }
      }
    }

    .dialog-body {
      border: 1px solid #E8ECF2;
      -webkit-border-radius: 4px 4px 4px;
      -moz-border-radius: 4px 4px 4px;
      border-radius: 4px 4px 4px;
      min-height: 200px;

      .formula-header {
        display: flex;
        justify-content: space-between;
        background-color: #F5F7FA;
        line-height: 40px;
        padding: 0 20px;
        font-size: 12px;
        font-weight: 400;

        .formula-title {
          color: #333333;
        }

        .clear-label {
          cursor: pointer;
          color: #4694DF;
        }
      }

      .en-text-config {
        padding: 20px 20px 20px;
      }
    }

    .dialog-toolbar {
      margin-top: 10px;
      height: calc(100% - 210px);
      width: 100%;
      border: 1px solid #E8ECF2;
      -webkit-border-radius: 4px 4px 4px;
      -moz-border-radius: 4px 4px 4px;
      border-radius: 4px 4px 4px;

      .toolbar-container {
        display: flex;
        justify-content: space-between;
        height: calc(100% - 51px);

        .toolbar-main {
          border-right: 1px solid #E8ECF2;
          width: calc(100% - 560px);
          display: flex;
          justify-content: flex-start;
          flex-wrap: wrap;
          height: 100%;
          position: relative;

          .search-area-list {
            background-color: #ffffff;
            position: absolute;
            left: 10px;
            top: 42px;
            border: 1px solid #DCDFE6;
            box-shadow: 0 0 2px #DCDFE6;
            width: calc(100% - 20px);

            .search-area-item {
              cursor: pointer;
              color: #636C78;
              line-height: 36px;
              font-size: 12px;
              padding: 0 20px;

              &:hover {
                background-color: #F5F8FC;
              }
            }
          }

          .tree-list {
            width: 100%;
            height: calc(100% - 52px);
            overflow-y: auto;

            .tree-parent {
              width: 100%;

              .tree-parent-info {
                width: 100%;
                display: flex;
                justify-content: flex-start;
                padding: 12px 20px;
                font-size: 12px;
                line-height: 12px;
                color: #636C78;
                cursor: pointer;

                &.tree-parent-info-item {
                  padding: 12px 40px;
                }

                .label {
                  margin-left: 12px;
                }

                &:hover {
                  background-color: #F5F8FC;
                }
              }

              .tree-children-list {
                .tree-children-item {
                  padding: 12px 20px 12px 50px;
                  font-size: 12px;
                  line-height: 12px;
                  color: #636C78;
                  cursor: pointer;

                  &.tree-children-last {
                    padding: 12px 20px 12px 80px;
                  }

                  &:hover {
                    background-color: #F5F8FC;
                  }
                }
              }
            }

            // 树节点处理
            /deep/ .el-tree {
              .el-tree-node {
                padding: 0 14px;
              }

              .el-tree-node__content {
                height: 36px;
                line-height: 36px;

                .el-tree-node__expand-icon {
                  color: #636C78;

                  &:before {
                    content: "\e6d9"
                  }

                  &.expanded {
                    transform: none;

                    &:before {
                      content: "\e6d8"
                    }
                  }

                  &.is-leaf {
                    color: transparent;
                  }

                }

                .el-tree-node__label {
                  font-size: 12px;
                }
              }
            }
          }

          .input-with-select {
            width: 100%;
            padding: 10px 10px 10px;
          }
        }

        .toolbar-description {
          padding: 20px 20px 20px;
          width: 560px;
          position: relative;
          color: #91A1B7;
          font-size: 12px;
          line-height: 22px;

          .import-icon {
            width: 4px;
            height: 4px;
            -webkit-border-radius: 100%;
            -moz-border-radius: 100%;
            border-radius: 100%;
            background-color: #F78528;
            position: absolute;
            left: 12px;
            top: 30px;

            &.words {
              background-color: #4694DF;
            }
          }

          .description {
            margin-bottom: 20px;
          }

          .use-method {
            margin-bottom: 20px;
          }
        }
      }
    }

    &.dialog {
      .dialog-toolbar {
        .toolbar-description {
          width: 300px;
        }

        .toolbar-main {
          width: calc(100% - 300px);
        }
      }
    }

    /deep/ .el-dialog__footer {
      border-top: 1px solid #E8ECF2;

      div {
        display: flex;
        justify-content: space-between;

        .check {
          line-height: 32px;

          .label {
            color: #91A1B7;
            font-size: 12px;
            margin-left: 6px;
          }
        }
      }
    }
  }
</style>
