`<!--
 * @Description: 添加/编辑计算型标签的子标签弹出框组件
 * @Author: liusheng
 * @Date: 2024-10-17 16:30:56
-->
<template>
  <div>
    <el-form :ref="formName" :model="compSubTagForm" :rules="compTagRules">
      <el-form-item label="名称：" prop="name" label-width="100px">
        <el-input style="width:200px" v-model="compSubTagForm.name" size="small" clearable placeholder="请输入子标签名称" />
      </el-form-item>
      <el-form-item label="表达式：" label-width="100px">
        <el-input style="width:592px" v-model="exprText" type="textarea"
          :autosize="{minRows: 2}" size="small" clearable readonly placeholder="自动生成表达式"/>
      </el-form-item>
      <div class="expr-block">
        <div class="expr-form-block">
          <span v-for="(expr, exprIndex) in compSubTagForm.exprList" :key="exprIndex">
            <el-row class="expr-line">
              <el-col :span="3">
                <el-checkbox v-model="expr.composite" style="padding-top:10px"
                  @change="handlerChangeLeaf($event, exprIndex)">复合式</el-checkbox>
              </el-col>
              <el-col :span="3">
                <el-form-item v-if="exprIndex > 0" style="padding-left:10px;"
                  :prop="'exprList.' + exprIndex + '.logic2Prev'" :rules="compTagRules.exprSel" >
                  <el-select v-model="expr.logic2Prev" clearable size="mini" placeholder="逻辑" @change="refreshExprText">
                    <el-option v-for="(item, index) in compTagSetDo.expLogicList" :key="index" :label="item.label" :value="item.value" />
                  </el-select>
                </el-form-item>
              </el-col>
              <template v-if="!expr.composite">
                <el-col :span="5">
                  <el-form-item style="padding-left:10px;" :prop="'exprList.' + exprIndex + '.gatherTag'" :rules="compTagRules.exprSel">
                    <el-select v-model="expr.gatherTag" clearable size="mini" placeholder="采集字段" @change="refreshExprText">
                      <el-option v-for="(item, index) in tagSet.gatherTagList" :key="index" :label="item" :value="item" />
                    </el-select>
                  </el-form-item>
                </el-col>
                <el-col :span="4">
                  <el-form-item style="padding-left:10px;" :prop="'exprList.' + exprIndex + '.opr'" :rules="compTagRules.exprSel">
                    <el-select v-model="expr.opr" clearable size="mini" placeholder="运算符" @change="refreshExprText">
                      <el-option v-for="(item, index) in compTagSetDo.expOperatorList" 
                        :key="index" :label="item.label" :value="item.value" />
                    </el-select>
                  </el-form-item>
                </el-col>
                <el-col :span="4">
                  <el-form-item style="padding-left:10px;" :prop="'exprList.' + exprIndex + '.tarVal'" :rules="compTagRules.exprInput">
                    <el-input v-model="expr.tarVal" clearable size="mini" placeholder="比较值" @input="refreshExprText" />
                  </el-form-item>
                </el-col>
                <el-col :span="4">
                  <el-form-item v-if="expr.opr == 'BETWEEN'" style="padding-left:10px;"
                    :prop="'exprList.' + exprIndex + '.tarVal2'" :rules="compTagRules.exprInput">
                    <el-input v-model="expr.tarVal2" clearable size="mini" placeholder="比较值2" @input="refreshExprText" />
                  </el-form-item>
                </el-col>
              </template>
              <template v-else>
                <el-col :span="1">  <!-- 添加子表达式按钮 -->
                  <el-button :disabled="expr.exprList && expr.exprList.length >= 4" style="padding:15px 0 0 15px;"
                    type="text" size="mini" icon="el-icon-plus" @click.stop="handleAddSubExpr(exprIndex)" />
                </el-col>
              </template>
              <el-col :span="1">    <!-- 删除按钮 -->
                <el-button v-if="exprIndex > 0" type="text" size="mini" style="padding:15px 0 0 10px;"
                  icon="el-icon-close" @click.stop="handleDelExpr(exprIndex)" />
              </el-col>
            </el-row>
            <!-- 复合表达式部分 -->
            <span v-if="expr.composite">
              <el-row class="sub-expr-line" v-for="(subExpr, subExprIndex) in expr.exprList" :key="subExprIndex">
                <el-col :span="3">
                  <el-form-item v-if="subExprIndex > 0" style="padding-left:10px;" :rules="compTagRules.exprSel"
                    :prop="'exprList.' + exprIndex + '.exprList.' + subExprIndex + '.logic2Prev'">
                    <el-select v-model="subExpr.logic2Prev" clearable size="mini" placeholder="逻辑" @change="refreshExprText">
                      <el-option v-for="(item, index) in compTagSetDo.expLogicList" 
                        :key="index" :label="item.label" :value="item.value" />
                    </el-select>
                  </el-form-item>
                </el-col>
                <el-col :span="5">
                  <el-form-item style="padding-left:10px;" :rules="compTagRules.exprSel"
                    :prop="'exprList.' + exprIndex + '.exprList.' + subExprIndex + '.gatherTag'" >
                    <el-select v-model="subExpr.gatherTag" clearable size="mini" placeholder="采集字段" @change="refreshExprText">
                      <el-option v-for="(item, index) in tagSet.gatherTagList" :key="index" :label="item" :value="item" />
                    </el-select>
                  </el-form-item>
                </el-col>
                <el-col :span="4">
                  <el-form-item style="padding-left:10px;" :rules="compTagRules.exprSel"
                    :prop="'exprList.' + exprIndex + '.exprList.' + subExprIndex + '.opr'">
                    <el-select v-model="subExpr.opr" clearable size="mini" placeholder="运算符" @change="refreshExprText">
                      <el-option v-for="(item, index) in compTagSetDo.expOperatorList" 
                        :key="index" :label="item.label" :value="item.value" />
                    </el-select>
                  </el-form-item>
                </el-col>
                <el-col :span="4">
                  <el-form-item style="padding-left:10px;" :rules="compTagRules.exprSel"
                    :prop="'exprList.' + exprIndex + '.exprList.' + subExprIndex + '.tarVal'">
                    <el-input v-model="subExpr.tarVal" clearable size="mini" placeholder="比较值" @input="refreshExprText" />
                  </el-form-item>
                </el-col>
                <el-col :span="4">
                  <el-form-item v-if="subExpr.opr == 'BETWEEN'" style="padding-left:10px;" :rules="compTagRules.exprInput"
                    :prop="'exprList.' + exprIndex + '.exprList.' + subExprIndex + '.tarVal2'" >
                    <el-input v-model="subExpr.tarVal2" clearable size="mini" placeholder="比较值2" @input="refreshExprText" />
                  </el-form-item>
                </el-col>
                <el-col :span="4">
                  <el-button v-if="subExprIndex > 0" style="padding:15px 0 0 10px;" type="text" 
                    size="mini" icon="el-icon-close" @click.stop="handleDelSubExpr(exprIndex, subExprIndex)" />
                </el-col>
              </el-row>
            </span>
          </span>
        </div>
        <el-button style="margin:10px 0 0 15px;" type="text" size="mini" icon="el-icon-plus"
          :disabled="this.compSubTagForm.exprList.length >= 4" @click.stop="handleAddExpr" />
      </div>
    </el-form>
    <div style="text-align:center; margin:0">
      <el-button type="text" size="mini" @click="handleCancel">取消</el-button>
      <el-button type="primary" size="mini" @click="handleConfirm">确定</el-button>
    </div>
  </div>
</template>

<script>
import aupUtil from '../../common/AupUtil.js';

export default {
  name: 'CompSubTagForm',
  props: ['mode', 'visible', 'tagSet', 'tagIndex', 'subTagIndex'],

  data() {
    return {
      formName: 'compSubTagForm',
      compSubTagForm: {
        exprList: [{}]
      },
      compTagSetDo: {},
      exprText : '',

			compTagRules: {
				name: [
          { required: true, message: '请输入标签名称', trigger: 'blur' },
          { type: 'string', pattern: aupUtil.tagNamePattern, message: aupUtil.tagNameErrMsg, trigger: 'blur' },
					{ min: 1, max: 20, message: '最大长度不超过20个字符', trigger: 'blur' },
				],
        exprSel: [
          { required: true, message: '请选择', trigger: 'blur' },
        ],
        exprInput: [
          { required: true, message: '请输入', trigger: 'blur' },
        ]
			},
    }
  },
  
  computed: {
  },

  methods: {
    getComputationTagSetDO() {
      let url = (this.mode === 'add') ? this.commonUrl.URL_GET_COMPUTATION_TAG_SET_DO4_ADD
        : this.commonUtil.fillUrlArgments(this.commonUrl.URL_GET_COMPUTATION_TAG_SET_DO4_UPDATE, this.tagSet.key)
      this.appAxios("GET", url).then(result => {
        if (result == null) return;
        this.compTagSetDo = result.data;

        if (this.mode === 'add') {
          this.compSubTagForm = {name: '', exprList: [this.newExprObj()]};
        } else {
          let subTag = this.compTagSetDo.tagSet.tagList[this.tagIndex].subTags[this.subTagIndex];
          this.compSubTagForm = JSON.parse(JSON.stringify(subTag));
          this.refreshExprText();
        }
      })
    },
    
    newExprObj() {
      return { gatherTag: '', logic2Prev: null, opr: null, tarVal: '', tarVal2: '', composite: false, exprList: [{}] };
    },

    refreshExprText() {
      let exprList = this.compSubTagForm.exprList;
      this.exprText = this.parseExpression(exprList);
    },
    
		parseExpression(exprList) {
      if (!exprList) return '';

			let text = "( ";
			for (let expr of exprList) {
				if (expr.logic2Prev) {
					text += ' ' + this.translateOpr(expr.logic2Prev) + ' ';
				}
				
				if (expr.composite) {
					text += this.parseExpression(expr.exprList);
				} else {
					text += (expr.gatherTag ? expr.gatherTag : '') + ' '
          text += (expr.opr ? this.translateOpr(expr.opr) : '') + ' ';
          text += (expr.tarVal ? expr.tarVal : '');
          text += (expr.tarVal2) ? ('~' + expr.tarVal2) : "";
				}
			}
			return text + " )";
		},

    translateOpr(opr) {
      const oprMap = new Map([
        ['AND', '&&'], ['OR', '||'],
        ['EQ', '=='], ['NEQ', '!='],
        ['GTE', '>='], ['GT', '>'],
        ['LTE', '<='], ['LT', '<'],
        ['LIKE', 'like'], ['BETWEEN', 'between']
      ]);
      return oprMap.has(opr) ? oprMap.get(opr): '?';
    },
    
    handleAddExpr() {
      this.compSubTagForm.exprList.push(this.newExprObj())
    },

    handleDelExpr(exprIndex) {
      this.compSubTagForm.exprList.splice(exprIndex, 1);
    },
    
    handlerChangeLeaf(event, exprIndex) {
      if (event) {
        let expr = this.compSubTagForm.exprList[exprIndex];
        if (!expr.exprList || expr.exprList.length === 0) {
          expr.exprList = [this.newExprObj()];
        }
      }
      this.refreshExprText();
    },

    handleAddSubExpr(exprIndex) {
      let subExpr = this.compSubTagForm.exprList[exprIndex];
      subExpr.exprList.push(this.newExprObj());
      this.$set(this.compSubTagForm.exprList, exprIndex, subExpr)
    },
    
    handleDelSubExpr(exprIndex, subExprIndex) {
      let subExpr = this.compSubTagForm.exprList[exprIndex];
      subExpr.exprList.splice(subExprIndex, 1);
      this.$set(this.compSubTagForm.exprList, exprIndex, subExpr)
    },

    handleConfirm() {
      this.$refs[this.formName].validate((valid) => {
        if (!valid) return false;
        this.$emit("confirm", this.compSubTagForm);
      });
    },
    
    handleCancel() {
      this.$emit("close", this.tagSetIndex);
    },

    handleKeyDown(event) {
      if (event.key === 'Escape') {
        this.handleCancel();
      }
    },
  },

  watch: {
    visible(newVal) {
      if (!newVal) return;
      this.$refs[this.formName].clearValidate();
      this.getComputationTagSetDO();
    }
  },

  mounted() {
    // 添加全局键盘监听事件
    window.addEventListener('keydown', this.handleKeyDown);
  },

  beforeDestroy() {
    // 移除全局键盘监听事件
    window.removeEventListener('keydown', this.handleKeyDown);
  },
}
</script>

<style scoped>
.expr-block {
  display: flex;
  margin: 0 20px 25px 100px;
  align-items: flex-start; /* 将内容对齐到容器的顶部 */
  border: orange solid 0px;
}
.expr-form-block {
  width: 640px;
  height: 260px;
  overflow-y: auto;
  border: lightgray solid 1px;
}
.expr-line {
  width: 570px;
  padding: 0 10px;
  align-items: center;
  border: blue solid 0px;
}
.sub-expr-line {
  width: 570px;
  padding-left: 25px;
  align-items: center;
  border: blue solid 0px;
}
</style>
