<!--
 * @Description: 添加/编辑展现标签弹出框组件
 * @Author: liusheng
 * @Date: 2024-11-12 13:30:56
-->
<template>
  <div>
    <el-form :ref="formName" :model="renderTagForm" :rules="renderTagRules" label-width="130px">
      <!-- 标签名称行 -->
      <div style="display:flex;">
        <el-form-item label="标签名称：" prop="tag">
          <el-input v-model="renderTagForm.tag" style="width:180px" size="small" clearable
            placeholder="请输入标签名称" @input="handleInputTagName" />
        </el-form-item>
        <el-form-item label-width="80px">
          <el-checkbox v-model="tagTextInvisible" @change="handlerChgTextVisible">不显示标签文本</el-checkbox>
        </el-form-item>
      </div>
      <!-- 标签文本行 -->
      <div style="display:flex;">
        <el-form-item label="文本位置(X)：" prop="pos.2" :rules="renderTagRules.pos">
          <el-input v-model.number="renderTagForm.pos[2]" style="width:180px" size="small"
            minlength="1" maxlength="4" clearable placeholder="请输入">
            <template slot="append">px</template>
          </el-input>
        </el-form-item>
        <el-form-item label="(Y)：" prop="pos.3" :rules="renderTagRules.pos" label-width="80px">
          <el-input v-model.number="renderTagForm.pos[3]" style="width:180px" size="small"
            minlength="1" maxlength="4" clearable placeholder="请输入">
            <template slot="append">px</template>
          </el-input>
        </el-form-item>
      </div>
      <!-- 状态图标行 -->
      <div style="display:flex;">
        <el-form-item v-for="(icon, index) in imgStrings" :key="index" 
          :label-width="labelWidth(index)" :label="index == 0 ? '状态图标：' : ''"
          :rules="renderTagRules.statusIcon" :prop="'statusIconList.' + index">
          <!-- v-if="statusSelected"> -->
          <el-upload class="img-uploader" action="" accept="image/jpeg,image/png" :auto-upload="false" 
            :show-file-list="false" :on-change="(file) => { handleChangeImg(file, index)}">
            <img v-if="renderTagForm.statusIconList[index]" class="image" :src="icon" />
            <i v-else class="el-icon-plus img-uploader-icon">{{ index + 1 }}</i>
          </el-upload>
        </el-form-item>
      </div>
      <!-- 图标位置行 -->
      <div style="display:flex;">
        <el-form-item label="图标位置(X)：" prop="pos.0" :rules="renderTagRules.pos">
          <el-input v-model.number="renderTagForm.pos[0]" style="width:180px" size="small" 
            minlength="1" maxlength="4" clearable placeholder="请输入">
            <template slot="append">px</template>
          </el-input>
        </el-form-item>
        <el-form-item label="(Y)：" prop="pos.1" :rules="renderTagRules.pos" label-width="80px">
          <el-input v-model.number="renderTagForm.pos[1]" style="width:180px" size="small"
            minlength="1" maxlength="4" clearable placeholder="请输入">
            <template slot="append">px</template>
          </el-input>
        </el-form-item>
      </div>
      <!-- 图标宽高行 -->
      <div style="display:flex;">
        <el-form-item label="图标宽：" prop="iconWidth">
          <el-input v-model.number="renderTagForm.iconWidth" style="width:180px" size="small"
            minlength="1" maxlength="4" clearable placeholder="请输入">
            <template slot="append">px</template>
          </el-input>
        </el-form-item>
        <el-form-item label="高：" prop="iconHeight" label-width="80px">
          <el-input v-model.number="renderTagForm.iconHeight" style="width:180px" size="small" 
            minlength="1" maxlength="4" clearable placeholder="请输入">
            <template slot="append">px</template>
          </el-input>
        </el-form-item>
      </div>
      <el-form-item label="标签值：" prop="value">
        <el-input style="width:440px" v-model="renderTagForm.value" type="textarea"
          :autosize="{minRows: 2}" size="small" clearable :placeholder="'支持RQL语句，'
          + '数据格式为：<值>|<状态>，状态为以下之一：_NORMAL_、_LEVEL2_、_LEVEL3_、_LEVEL4_'" />
      </el-form-item>
    </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 './AupUtil.js';

export default {
  name: 'RenderTagForm',
  props: {
    mode: {
      type: String,
      default: ''
    },
    visible: {
      type: Boolean,
      default: false
    },
    tagSetIndex: {
      type: Number,
      default: -1
    },
    tagSet: {
      type: Object,
      default: null
    },
    tagIndex: {
      type: Number,
      default: -1
    },
  },
  
  data() {
    return {
      formName: 'renderTagForm',

      renderTagForm: { 
        tag: '', 
        pos: ['','','',''], 
        statusIconList: ['','','',''] 
      },
      tagTextInvisible: false,
      imgStrings: ['', '', '', ''],              //存放4个状态画标图片路径或Base64串
      
			renderTagRules: {
				tag: [
          { required: true, message: '请输入标签名称', trigger: 'blur' },
          { type: 'string', pattern: aupUtil.tagNamePattern, message: aupUtil.tagNameErrMsg, trigger: 'blur' },
					{ min: 2, max: 20, message: '长度应为2-20个字符', trigger: 'blur' },
				],
        pos: [
          { required: true, message: '请输入坐标', trigger: 'blur' },
          { type: 'number', min: 0, max: 1000, message: '宽度必须在0-1000之间', trigger: 'blur' },
        ],
        statusIcon: [
          { required: true, message: '请上传图标', trigger: 'blur' },
				],
        iconWidth: [
          { required: true, message: '请输入图标宽度', trigger: 'blur' },
          { type: 'number', min: 10, max: 200, message: '宽度必须在10-200之间', trigger: 'blur' },
				],
        iconHeight: [
          { required: true, message: '请输入图标高度', trigger: 'blur' },
          { type: 'number', min: 10, max: 200, message: '宽度必须在10-200之间', trigger: 'blur' },
				],
        value: [
          { required: true, message: '请输入标签值', trigger: 'blur' },
				]
			}
    }
  },

  computed: {
    labelWidth() {
      return function(index) {
        const width = ['130px', '35px', '61px', '35px']
        return width[index];
      }
    },
  },
  
  methods: {
    handleInputTagName() {
      this.tagTextInvisible = (this.renderTagForm.tag && this.renderTagForm.tag[0] === '_');
    },

    handlerChgTextVisible() {
      if (!this.tagTextInvisible) { 
        // 显示标签文本，标签名不能以下划线开头
        while (this.renderTagForm.tag && this.renderTagForm.tag[0] === '_') {
          this.renderTagForm.tag = this.renderTagForm.tag.substring(1);
        } 
      } else {
        // 不显示标签文本，标签名以下划线开头
        if (!this.renderTagForm.tag) {
          this.renderTagForm.tag = '_';
          return;
        }
        if (this.renderTagForm.tag[0] !== '_') {
          this.renderTagForm.tag = '_' +  this.renderTagForm.tag;
        }
      }
      this.$refs[this.formName].clearValidate();
    },

    async handleChangeImg(file, index) {
      let result = this.imgUtil.validateFileAttrs(file, 100);
      if (result) {
        this.$message.error(result);
        return;
      } 

      this.$set(this.imgStrings, index, await this.imgUtil.blobToBase64(file.raw));
      this.$set(this.renderTagForm.statusIconList, index, file);

      if (!this.renderTagForm.iconWidth || !this.renderTagForm.iconHeight) {
        const img = new Image();
        img.src = this.imgStrings[index];
        img.onload = () => {
          this.renderTagForm.iconWidth = img.width;
          this.renderTagForm.iconHeight = img.height;
        };
      }
    },

    handleConfirm() {
      this.$refs[this.formName].validate((valid) => {
        if (!valid) return false;

        let url = (this.mode === 'add') ? this.commonUrl.URL_ADD_RENDER_TAG
          : this.commonUrl.URL_UPDATE_RENDER_TAG;
        const [tagVo, fileMap] = this.buildRequestParam();
        let requestData = {
          url: url,
          method: (this.mode === 'add') ? 'POST' : 'PUT',
          contentType: this.commonConst.CNTYPE_JSON,
          param: { name: 'tagVo', value: tagVo },
          files: fileMap
        };
        this.vueRequest(requestData).then(result => {
          if (result == null) return;
          this.$emit("confirm", result.data, this.tagSetIndex);
        })
      });
    },
    
    buildRequestParam() {
      let tagVo = {
        tagSetKey: this.tagSet.key,
        tag: JSON.parse(JSON.stringify(this.renderTagForm)),
        tagIndex: this.tagIndex
      };

      let iconFileList = new Array(this.tagSet.maxStatus);
      // 当新增标签集，或在修改标签集时改变了图片时，tag.statusIconList[n]为file对象，否则(编辑时未改变图片)为'string'
      for (let index = 0; index < this.tagSet.maxStatus; index++) {
        if (typeof(this.renderTagForm.statusIconList[index]) === 'object') {
          iconFileList[index] = this.renderTagForm.statusIconList[index].raw;
          tagVo.tag.statusIconList[index] = '';
        }
      }
      let fileMap = new Map();
      fileMap.set("iconFileList", iconFileList);
      return [tagVo, fileMap];
    },
    
    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();

      if (this.mode === 'add') {
        this.renderTagForm = { 
          tag: '', 
          pos: ['','','',''], 
          statusIconList: ['','','','']
        };
        this.imgStrings = new Array(this.tagSet.maxStatus).fill('');
      } else {
        this.renderTagForm = JSON.parse(JSON.stringify(this.tagSet.tagList[this.tagIndex]));
        this.imgStrings = new Array(this.tagSet.maxStatus);
        for (let index = 0; index < this.tagSet.maxStatus; index++) {
          this.imgStrings[index] = this.commonUtil.fillUrlArgments(this.commonUrl.URL_DOWNLOAD_AUP_IMAGE,
            this.tagSet.key, this.renderTagForm.statusIconList[index]);
        }
      }
      this.tagTextInvisible = (this.renderTagForm.tag && this.renderTagForm.tag[0] === '_');
    }
  },

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

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

<style scoped>
.img-uploader {
  margin-right: 20px;
  width: 60px;
  height: 60px;
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
}
.img-uploader:hover {
  border-color: #409EFF;
}
.image {
  width: 60px;
  height: 60px;
  display: block;
}
.img-uploader-icon {
  font-size: 20px;
  color: #8c939d;
  width: 60px;
  height: 60px;
  line-height: 60px;
  text-align: center;
}
</style>
