<template>
  <div class="ele-body">
    <el-button type="primary" @click="addHtml('customText')" v-if="edit"
      >插入自定义文本</el-button
    >
    <el-button type="primary" @click="addHtml('customTable')" v-if="edit"
      >插入表格</el-button
    >
    <!-- <el-button type="primary" @click="save()">保存</el-button> -->
    <div
      style="
        display: flex;
        width: 100%;
        padding: 10px;
        border: solid 1px #f1f1f1;
        margin-top: 10px;
      "
    >
      <vue-draggable
        v-model="list"
        group="project1"
        :animation="300"
        handle=".sort-handle"
        style="flex: 1"
      >
        <div
          class="demo-drag-list-item ele-cell"
          v-for="item in list"
          :key="item.id"
        >
          <div class="listItem">
            <i
              class="sort-handle el-icon-_nav move"
              style="display: none"
              v-if="edit"
            ></i>
            <i
              class="sort-handle el-icon-delete delete"
              v-if="edit"
              style="display: none"
              @click="del(item.id)"
            ></i>
            <customText
              :ref="'customTextRef' + item.id"
              style="flex: 1"
              v-if="item.type == 'customText'"
              :id="item.id"
              :form="item.value"
              :valueObj="item.valueObj"
              @editShow="editShowFn"
              @calculation="calculation"
              :edit="edit"
            ></customText>
            <customTable
              :ref="'customTextRef' + item.id"
              style="flex: 1"
              v-if="item.type == 'customTable'"
              :id="item.id"
              :form="item.value"
              :valueObj="item.valueObj"
              @calculation="calculation"
              @editShow="editShowFn"
              :edit="edit"
            ></customTable>
          </div>
        </div>
      </vue-draggable>

      <el-card class="box-card" v-show="editShow" style="width: 320px">
        <div slot="header" class="clearfix">
          <span>配置</span>
          <el-button
            style="float: right; padding: 3px 0"
            type="text"
            @click="editShow = false"
            >关闭</el-button
          >
        </div>
        <el-form label-width="80px">
          <el-form-item label="字段标识:" prop="id">
            <el-input
              v-model="domObj.id"
              placeholder=""
              @change="editInputChange"
            ></el-input>
          </el-form-item>
          <el-form-item label="宽度:" prop="width" v-if="!domObj.isNoWidth">
            <el-input
              v-model="domObj.width"
              type="number"
              placeholder=""
              @change="editInputChange"
            ></el-input>
          </el-form-item>
          <el-form-item label="是否只读:" prop="readonly">
            <el-select
              v-model="domObj.readonly"
              placeholder="请选择"
              @change="editInputChange"
            >
              <el-option :key="1" label="否" :value="1"> </el-option>
              <el-option :key="2" label="是" :value="2"> </el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="计算公式:" prop="readonly">
            <el-input
              :value="domObj.equation?.map((item) => item.value).join('')"
              type="textarea"
              placeholder=""
              disabled
            ></el-input>
            <el-button type="primary" @click="setEquation">配置公式</el-button>
            <el-button type="primary" @click="delEquation">重置</el-button>
          </el-form-item>
        </el-form>
      </el-card>
    </div>
    <ele-modal
      title="配置公式"
      :visible.sync="visible"
      :close-on-click-modal="false"
      append-to-body
      width="800px"
      resizable
      maxable
    >
      <div class="formula-builder__selects">
        <!-- 选择参数：从已填的非计算参数内容里取 -->
        <el-select
          v-model="equationUnit.paramSelect"
          placeholder="选择参数"
          size="mini"
          style="width: 100px; margin-right: 8px; flex-shrink: 0"
          @change="paramSelectChange($event, 'id')"
          filterable
        >
          <el-option
            v-for="item in idList"
            :key="item"
            :label="item"
            :value="item"
          />
        </el-select>

        <!-- 选择运算符 -->
        <el-select
          v-model="equationUnit.opSelect"
          placeholder="选择符号"
          size="mini"
          style="width: 100px; flex-shrink: 0; margin-right: 8px"
          @change="paramSelectChange($event, 'symbol')"
        >
          <el-option
            v-for="op in opSelectOptions"
            :key="op"
            :label="op"
            :value="op"
          />
        </el-select>
        <!-- 选择值 -->
        <el-input
          v-model="equationUnit.currentValue"
          placeholder="输入值"
          size="mini"
          style="width: 150px; flex-shrink: 0"
        >
          <template slot="append">
            <span
              style="cursor: pointer"
              @click="paramSelectChange(equationUnit.currentValue, 'value')"
              >确认</span
            >
          </template>
        </el-input>
        <!-- 替换或者追加 -->
        <el-select
          v-if="equationUnit.activeIndex != undefined"
          v-model="equationUnit.replaceOrAppend"
          placeholder="选择"
          size="mini"
          style="width: 80px; margin-left: 8px; flex-shrink: 0"
        >
          <el-option key="append" label="追加" value="append" />
          <el-option key="replace" label="替换" value="replace" />
        </el-select>
        <el-input
          v-model.number="domObj.units.decimalPlace"
          placeholder="小数位"
          size="mini"
          style="width: 120px; margin-left: 8px; flex-shrink: 0"
        >
        </el-input>
        <el-select
          v-model="domObj.units.takeValueMethod"
          placeholder="取值方法"
          size="mini"
          style="width: 100px; margin-left: 8px; flex-shrink: 0"
        >
          <el-option key="1" label="四舍五入" value="1" />
          <el-option key="2" label="去尾" value="2" />
        </el-select>
      </div>

      <!-- 已组装公式标签展示 -->
      <div
        v-if="equationUnit.equation.length"
        style="
          display: inline-flex;
          flex-wrap: wrap;
          max-width: 100%;
          margin-top: 5px;
        "
      >
        <el-tag
          v-for="(p, index) in equationUnit.equation"
          :key="index"
          size="mini"
          closable
          :type="equationUnit.activeIndex === index ? 'primary' : 'info'"
          @click="formulaPartsTagClick(index)"
          @close="tagItemDelete(index)"
        >
          {{ p.value }}
        </el-tag>
      </div>

      <el-input
        style="margin-top: 5px"
        :value="equationUnit.equation?.map((item) => item.value).join('')"
        type="textarea"
        placeholder=""
        disabled
      ></el-input>
      <div slot="footer" class="footer">
        <el-button type="primary" @click="editInputChange('equation')"
          >确认</el-button
        >
        <el-button @click="visible = false">返回</el-button>
      </div>
    </ele-modal>
  </div>
</template>

<script>
  import customText from './templateDiv/customText.vue';
  import customTable from './templateDiv/customTable.vue';
  import VueDraggable from 'vuedraggable';
  import { generateRandomString } from '@/utils/util';

  export default {
    components: {
      customText,
      VueDraggable,
      customTable
    },
    props: {
      edit: {
        default: true,
        type: Boolean
      }
    },
    computed: {},
    data() {
      return {
        list: [],
        editShow: false,
        visible: false,
        templateDivRef: '',
        domObj: { units: {} },
        idList: [],
        opSelectOptions: ['+', '-', '*', '/', '%', '(', ')'],
        equationUnit: {
          equation: [],
          activeIndex: '',
          paramSelect: '',
          opSelect: '',
          currentValue: '',
          replaceOrAppend: 'append'
        }
      };
    },
    mounted() {},
    created() {},
    methods: {
      // 计算
      calculation() {
        this.getValue();
        let equation = [];

        this.list.forEach((item) => {
          equation.push({
            id: item.id,
            equation: item.equation
          });
        });
        equation.forEach((item) => {
          for (const key in item.equation) {
            let { data, units } = this.getObjValue(); //每次计算都获取最新的值
            let value = '';
            if (item.equation[key].length) {
              item.equation[key].forEach((equationItem) => {
                if (
                  equationItem.type == 'symbol' ||
                  equationItem.type == 'value'
                ) {
                  value += equationItem.value;
                } else if (equationItem.type == 'id') {
                  value += Number(data[equationItem.value]) || 0;
                }
              });
              if (units[key]?.decimalPlace) {
                if (units[key]?.takeValueMethod) {
                  value =
                    units[key]?.takeValueMethod == 1
                      ? parseFloat(eval(value).toFixed(units[key].decimalPlace))
                      : this.truncateToFixedManual(
                          eval(value),
                          units[key].decimalPlace
                        );
                } else {
                  value = parseFloat(
                    eval(value).toFixed(units[key].decimalPlace)
                  );
                }
              } else {
                value = parseFloat(eval(value).toFixed(2));
              }
              if (this.$refs['customTextRef' + item.id][0]) {
                this.$refs['customTextRef' + item.id][0].equationValue({
                  domId: key,
                  value
                });
              }
            }
          }
        });
      },

      truncateToFixedManual(num, decimalPlaces) {
        let factor = Math.pow(10, decimalPlaces);
        return Math.floor(num * factor) / factor;
      },
      getObjValue() {
        this.getValue();
        let data = {};
        let units = {};
        this.list.forEach((item) => {
          units = { ...item.units, ...units };

          if (item.type == 'customText') {
            data = { ...item.valueObj, ...data };
          } else {
            item.valueObj.columns.forEach((row) => {
              row.forEach((cell) => {
                data[cell.id] = cell.value;
              });
            });
          }
        });
        return { data: data || {}, units: units || {} };
      },

      setEquation() {
        this.getValue();
        this.idList = [];
        if (this.domObj.equation) {
          this.equationUnit.equation = JSON.parse(
            JSON.stringify(this.domObj.equation)
          );
          this.equationUnit.activeIndex = this.domObj.equation.length;
        } else {
          this.equationUnit.equation = [];
        }
        this.list.forEach((item) => {
          if (item.type == 'customText') {
            for (let key in item.valueObj) {
              this.idList.push(key);
            }
          } else {
            item.valueObj.columns.forEach((row) => {
              row.forEach((cell) => {
                this.idList.push(cell.id);
              });
            });
          }
        });
        this.visible = true;
      },
      delEquation() {
        this.equationUnit.equation = [];
        this.editInputChange('equation');
      },
      tagItemDelete(index) {
        this.equationUnit.equation.splice(index, 1);
      },
      formulaPartsTagClick(index, row) {
        if (!this.equationUnit.replaceOrAppend) {
          // 默认追加
          this.equationUnit_replaceOrAppend = 'append';
        }

        if (
          this.equationUnit.activeIndex &&
          this.equationUnit.activeIndex === index
        ) {
          this.$set(this.equationUnit, 'activeIndex', undefined);
        } else {
          this.$set(this.equationUnit, 'activeIndex', index);
        }
      },
      paramSelectChange(val, type) {
        if (!val) {
          return;
        }
        if (type == 'id') {
          this.setValue({ type: 'id', value: val });
          this.equationUnit.paramSelect = null;
        } else if (type == 'symbol') {
          this.setValue({ type: 'symbol', value: val });

          this.equationUnit.opSelect = null;
        } else if (type == 'value') {
          this.setValue({ type: 'value', value: val });
        }
      },
      setValue(val) {
        if (this.equationUnit.activeIndex != undefined) {
          if (
            !this.equationUnit.replaceOrAppend ||
            this.equationUnit.replaceOrAppend === 'replace'
          ) {
            this.equationUnit.equation.splice(
              this.equationUnit.activeIndex,
              1,
              val
            );
          } else if (this.equationUnit.replaceOrAppend === 'append') {
            this.equationUnit.equation.splice(
              this.equationUnit.activeIndex + 1,
              0,
              val
            );
            // 追加后activeIndex后移一位
            this.$set(
              this.equationUnit,
              'activeIndex',
              this.equationUnit.activeIndex + 1
            );
          }
        } else {
          this.equationUnit.equation.push(val);
        }
      },

      init(list) {
        this.list = JSON.parse(list);
        if (this.list.length) {
          this.$nextTick(() => {
            this.list.forEach((item) => {
              this.$refs['customTextRef' + item.id][0].init({
                form: item.value,
                valueObj: item.valueObj,
                equation: item.equation,
                units: item.units
              });
            });
          });
        }
      },
      editShowFn({ templateDivRef, domObj }) {
        this.templateDivRef = templateDivRef;
        this.$set(this, 'domObj', domObj);
        this.editShow = true;
      },
      editInputChange(type) {
        if (type == 'equation') {
          this.visible = false;
          this.domObj.equation = JSON.parse(
            JSON.stringify(this.equationUnit.equation)
          );
        }
        this.$nextTick(() => {
          this.$refs[this.templateDivRef][0].editInputChange(this.domObj);
        });
      },
      del(id) {
        this.list = this.list.filter((item) => item.id != id);
      },
      addHtml(type) {
        this.list.push({
          id: generateRandomString(6),
          type: type,
          value: '',
          valueObj: {}
        });
      },
      getValue() {
        this.list.forEach((item, index) => {
          let { form, valueObj, equation, units } =
            this.$refs['customTextRef' + item.id][0].getValue();
          this.$set(this.list[index], 'value', form);
          this.$set(this.list[index], 'valueObj', valueObj);
          this.$set(this.list[index], 'equation', equation);
          this.$set(this.list[index], 'units', units);
        });
        return this.list;
      }
    }
  };
</script>

<style scoped lang="scss">
  .listItem {
    padding: 5px;
    padding-top: 15px;
    border: solid 1px #f1f1f1;
    display: flex;
    width: 100%;
    align-items: center;
    margin-top: 3px;
    position: relative;
  }
  .sort-handle {
    font-size: 16px;
    position: absolute;
    left: 0;
    top: 0;
  }
  .move {
    cursor: move;
  }
  .delete {
    cursor: pointer;
    left: 20px;
    color: #f56c6c;
  }
  .listItem:hover {
    .sort-handle {
      display: block !important;
    }
  }
</style>
