<template>
  <div class="function-form-model">
    <el-dialog
      :close-on-click-modal="false"
      :modal="false"
      :title="title"
      :visible="visible"
      class="params-eldialog"
      top="5vh"
      width="800px"
      @close="$emit('update:visible', false)"
    >
      <el-form
        ref="form"
        :model="form"
        :rules="rules"
        label-position="top"
        style="padding: 0 15px"
      >
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="标识:" prop="id">
              <el-input
                v-model="form.id"
                placeholder="请输入标识"
                @input="inputChange"
              />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="功能名称:" prop="name">
              <el-input v-model="form.name" placeholder="请输入功能名称" />
            </el-form-item>
          </el-col>
        </el-row>

        <el-form-item label="输入参数:" prop="inputs">
          <el-table :data="form.inputs" height="300px">
            <el-table-column align="left" label="标识" prop="id" />
            <el-table-column align="left" label="参数名称" prop="name" />
            <el-table-column align="center" label="是否必选" prop="required">
              <template slot-scope="scope">
                <span>{{ scope.row.expands.required ? "是" : "否" }}</span>
              </template>
            </el-table-column>
            <el-table-column align="left" label="数据类型" prop="type">
              <template slot-scope="scope">
                <span>{{ dataTypeOption[scope.row.valueType.type] }}</span>
              </template>
            </el-table-column>
            <el-table-column
              align="center"
              class-name="small-padding fixed-width"
              label="操作"
              width="200px"
            >
              <template slot-scope="scope">
                <el-button
                  :disabled="scope.$index === 0"
                  icon="el-icon-arrow-up"
                  size="mini"
                  type="text"
                  @click="handleInputUp(scope.$index)"
                >上移</el-button>
                <el-button
                  :disabled="scope.$index === form.inputs.length - 1"
                  icon="el-icon-arrow-down"
                  size="mini"
                  type="text"
                  @click="handleInputDown(scope.$index)"
                >下移</el-button>
                <el-button
                  icon="el-icon-edit"
                  size="mini"
                  type="text"
                  @click="handleInputUpdate(scope.row, scope.$index)"
                  >修改</el-button
                >
                <el-button
                  icon="el-icon-delete"
                  size="mini"
                  type="text"
                  @click="handleInputDelete(scope.row, scope.$index)"
                  >删除</el-button
                >
              </template>
            </el-table-column>
          </el-table>
          <el-button
            icon="el-icon-plus"
            plain
            style="width: 100%;margin-top: 10px"
            type="info"
            @click="addInputParam"
            >新增输入参数</el-button
          >
        </el-form-item>

        <el-form-item label="是否异步:" prop="async">
          <el-switch v-model="form.async" />
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitForm">确 定</el-button>
        <el-button @click="$emit('update:visible', false)">取 消</el-button>
      </div>
    </el-dialog>
    <!-- 输入参数弹窗 -->
    <el-dialog
      :close-on-click-modal="false"
      :visible.sync="inputParamOpen"
      append-to-body
      class="params-eldialog"
      title="输入参数"
      width="600px"
      @close="handleInputDialogClose"
    >
      <el-form
        ref="inputForm"
        :model="inputFormObj.form"
        :rules="inputFormRules"
        label-position="top"
        label-width="100px"
      >
        <el-form-item label="标识:" prop="id">
          <el-input v-model="inputFormObj.form.id" placeholder="请输入标识" />
        </el-form-item>
        <el-form-item label="参数名称:" prop="name">
          <el-input
            v-model="inputFormObj.form.name"
            placeholder="请输入参数名称"
          />
        </el-form-item>

        <el-form-item label="数据类型:" prop="type">
          <el-select
            v-model="inputFormObj.form.valueType.type"
            placeholder="请选择数据类型"
            style="width: 100%"
            @change="inputDataTypeChange"
          >
            <el-option
              v-for="(dice, value) in dataTypeOption"
              :key="value"
              :label="dice"
              :value="value"
            />
          </el-select>
        </el-form-item>
        <el-form-item
          v-if="inputFormObj.form.valueType.type === 'enum'"
          label="枚举值:"
        >
          <div class="enum-box">
            <div class="enum-header">
              <el-button size="mini" type="primary" @click="addEnumItem"
                >添加枚举项</el-button
              >
            </div>
            <el-table
              :data="inputFormObj.form.valueType.elements"
              border
              style="width: 100%"
            >
              <el-table-column
                align="center"
                label="序号"
                type="index"
                width="60"
              ></el-table-column>
              <el-table-column label="值" prop="value" width="180">
                <template slot-scope="scope">
                  <el-input
                    v-model="scope.row.value"
                    :class="{ 'is-error': scope.row.value }"
                    placeholder="请输入值"
                  ></el-input>
                  <div
                    v-if="scope.row.value === ''"
                    class="el-form-item__error"
                  >
                    值不能为空
                  </div>
                </template>
              </el-table-column>
              <el-table-column label="描述" prop="text">
                <template slot-scope="scope">
                  <el-input
                    v-model="scope.row.text"
                    :class="{ 'is-error': scope.row.text }"
                    placeholder="请输入描述"
                  ></el-input>
                  <div v-if="scope.row.text === ''" class="el-form-item__error">
                    描述不能为空
                  </div>
                </template>
              </el-table-column>
              <el-table-column align="center" label="操作" width="80">
                <template slot-scope="scope">
                  <el-button
                    icon="el-icon-delete"
                    style="color: red"
                    type="text"
                    @click="removeEnumItem(scope.$index)"
                  ></el-button>
                </template>
              </el-table-column>
            </el-table>
          </div>
        </el-form-item>
        <el-form-item label="是否必选:" prop="required">
          <el-switch v-model="inputFormObj.form.expands.required" />
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitInputForm">确 定</el-button>
        <el-button @click="inputParamOpen = false">取 消</el-button>
      </div>
    </el-dialog>
  </div>
</template>
<script>
import { dataTypeOption } from "@/basedata/physicalModel";

const defaultenumForm = {
  value: "",
  text: ""
};

const defaultInputForm = {
  id: "",
  name: "",
  expands: {
    required: false
  },
  valueType: {
    expands: {},
    type: "int",
    elements: []
  }
};

export default {
  name: "FunctionFormModel",
  props: {
    visible: {
      type: Boolean,
      default: false
    },
    title: {
      type: String,
      default: "新增"
    },
    row: {
      type: Object,
      default: () => {}
    },
    tempType: {
      type: String,
      default: "add"
    },
    paramIdx: {
      type: Number,
      default: -1
    },
    functionList: {
      type: Array,
      default: []
    }
  },
  data() {
    return {
      dataTypeOption,
      inputParamOpen: false,
      form: {
        id: "",
        name: "",
        expands: {},
        async: false,
        inputs: [],
        output: {}
      },
      inputFormObj: {
        isEdit: false,
        index: -1,
        form: JSON.parse(JSON.stringify(defaultInputForm))
      },
      inputFormRules: {
        id: [
          { required: true, message: "标识不能为空", trigger: "blur" },
          {
            pattern: /^[a-zA-Z0-9_\-]+$/,
            message: "标识只能由数字、字母、下划线、中划线组成",
            trigger: "blur"
          },
          { validator: this.validateInputId, trigger: "blur" }
        ],
        name: [{ required: true, message: "参数名称不能为空", trigger: "blur" }]
      },
      // 表单校验
      rules: {
        name: [{ required: true, message: "名称不能为空", trigger: "blur" }],
        cmdKey: [{ required: true, message: "分组不能为空", trigger: "blur" }],
        id: [
          { required: true, message: "标识不能为空", trigger: "blur" },
          {
            pattern: /^[a-zA-Z0-9_\-]+$/,
            message: "标识只能由数字、字母、下划线、中划线组成",
            trigger: "blur"
          },
          { validator: this.validateFunctionId, trigger: "blur" }
        ],
        type: [{ required: true, message: "数据类型不能为空", trigger: "blur" }]
      }
    };
  },
  created() {
    if (this.tempType === "update" && this.paramIdx >= 0) {
      this.form = JSON.parse(JSON.stringify(this.row));
    } else {
      // 新增时初始化表单
      this.form = {
        id: "",
        name: "",
        expands: {},
        async: true,
        inputs: [],
        output: {}
      };
    }
  },
  watch: {
    visible(val) {
      if (val) {
        // 当弹窗打开时
        if (this.tempType === "update" && this.paramIdx >= 0) {
          // 编辑模式，复制传入的数据
          this.form = JSON.parse(JSON.stringify(this.row));
        } else {
          // 新增模式，重置表单数据
          this.form = {
            id: "",
            name: "",
            expands: {},
            async: true,
            inputs: [],
            output: {}
          };
        }

        // 确保输入参数表单也被重置
        this.inputFormObj = {
          isEdit: false,
          index: -1,
          form: JSON.parse(JSON.stringify(defaultInputForm))
        };
      } else {
        // 当弹窗关闭时，重置表单校验状态
        this.$nextTick(() => {
          if (this.$refs.form) {
            this.$refs.form.clearValidate();
          }
          if (this.$refs.inputForm) {
            this.$refs.inputForm.clearValidate();
          }
        });
      }
    }
  },
  methods: {
    // 自定义标识符验证规则
    validateFunctionId(rule, value, callback) {
      if (this.tempType === "update" && value === this.row.id) {
        // 如果是编辑模式且ID没有变化，直接通过验证
        callback();
        return;
      }

      // 检查功能标识符是否重复
      const isDuplicate =
        this.functionList && this.functionList.some(item => item.id === value);
      if (isDuplicate) {
        callback(new Error("标识符已存在，请更换"));
      } else {
        callback();
      }
    },
    // 自定义输入参数标识符验证规则
    validateInputId(rule, value, callback) {
      if (
        this.inputFormObj.isEdit &&
        value === this.form.inputs[this.inputFormObj.index].id
      ) {
        // 如果是编辑模式且ID没有变化，直接通过验证
        callback();
        return;
      }

      // 检查输入参数标识符是否重复
      const isDuplicate = this.form.inputs.some(item => item.id === value);
      if (isDuplicate) {
        callback(new Error("输入参数标识符已存在，请更换"));
      } else {
        callback();
      }
    },
    inputDataTypeChange(val) {
      // 根据选择的数据类型设置valueType的type属性
      if (val === "int") {
        this.inputFormObj.form.valueType.type = "int";
        this.inputFormObj.form.valueType.elements = [];
      } else if (val === "long") {
        this.inputFormObj.form.valueType.type = "long";
        this.inputFormObj.form.valueType.elements = [];
      } else if (val === "float") {
        this.inputFormObj.form.valueType.type = "float";
        this.inputFormObj.form.valueType.elements = [];
      } else if (val === "double") {
        this.inputFormObj.form.valueType.type = "double";
        this.inputFormObj.form.valueType.elements = [];
      } else if (val === "string") {
        this.inputFormObj.form.valueType.type = "string";
        this.inputFormObj.form.valueType.elements = [];
      } else if (val === "boolean") {
        this.inputFormObj.form.valueType.type = "boolean";
        this.inputFormObj.form.valueType.elements = [];
      } else if (val === "date") {
        this.inputFormObj.form.valueType.type = "date";
        this.inputFormObj.form.valueType.elements = [];
      } else if (val === "enum") {
        this.inputFormObj.form.valueType.type = "enum";
        if (
          !this.inputFormObj.form.valueType.elements ||
          this.inputFormObj.form.valueType.elements.length === 0
        ) {
          this.inputFormObj.form.valueType.elements = [];
          // 默认添加一个空的枚举项
          this.addEnumItem();
        }
      } else if (val === "array") {
        this.inputFormObj.form.valueType.type = "array";
        this.inputFormObj.form.valueType.elements = [];
      } else if (val === "object") {
        this.inputFormObj.form.valueType.type = "object";
        this.inputFormObj.form.valueType.elements = [];
      } else if (val === "file") {
        this.inputFormObj.form.valueType.type = "file";
        this.inputFormObj.form.valueType.elements = [];
      } else if (val === "password") {
        this.inputFormObj.form.valueType.type = "password";
        this.inputFormObj.form.valueType.elements = [];
      } else if (val === "geoPoint") {
        this.inputFormObj.form.valueType.type = "geoPoint";
        this.inputFormObj.form.valueType.elements = [];
      }
    },

    addEnumItem() {
      // 确保elements数组已初始化
      if (!this.inputFormObj.form.valueType.elements) {
        this.inputFormObj.form.valueType.elements = [];
      }

      // 添加一个新的枚举项
      const newEnumItem = JSON.parse(JSON.stringify(defaultenumForm));
      newEnumItem.value = "";
      newEnumItem.text = "";
      this.inputFormObj.form.valueType.elements.push(newEnumItem);
    },
    removeEnumItem(index) {
      this.$confirm("是否确认删除该枚举参数?", "警告", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      })
        .then(() => {
          this.inputFormObj.form.valueType.elements.splice(index, 1);
          this.$message({
            type: "success",
            message: "删除成功!"
          });
        })
        .catch(() => {
          this.$message({
            type: "info",
            message: "已取消删除"
          });
        });
    },

    // 修改提交方法，增加枚举项验证
    submitInputForm() {
      // 验证表单
      this.$refs.inputForm.validate(valid => {
        if (valid) {
          // 如果是枚举类型，确保至少有一个枚举项
          if (
            this.inputFormObj.form.valueType.type === "enum" &&
            (!this.inputFormObj.form.valueType.elements ||
              this.inputFormObj.form.valueType.elements.length === 0)
          ) {
            this.$message.warning("枚举类型至少需要一个枚举项");
            return;
          }

          // 验证枚举项的值和描述不能为空
          if (this.inputFormObj.form.valueType.type === "enum") {
            let hasError = false;
            const enumValues = new Set();
            for (
              let i = 0;
              i < this.inputFormObj.form.valueType.elements.length;
              i++
            ) {
              const item = this.inputFormObj.form.valueType.elements[i];
              let value = !item.value;
              let text = !item.text;
              if (value || text) {
                hasError = true;
                break;
              }
              if (enumValues.has(item.value)) {
                this.$message.warning(`枚举值 "${item.value}" 重复，请修改`);
                return;
              }
              enumValues.add(item.value);
            }
            if (hasError) {
              this.$message.warning("请完善枚举项的值和描述");
              return;
            }
          }

          // 如果是编辑模式
          if (this.inputFormObj.isEdit) {
            // 更新现有输入参数
            this.$set(
              this.form.inputs,
              this.inputFormObj.index,
              this.inputFormObj.form
            );
          } else {
            // 添加新的输入参数
            this.form.inputs.push(
              JSON.parse(JSON.stringify(this.inputFormObj.form))
            );
          }

          // 关闭弹窗
          this.inputParamOpen = false;

          // 清除校验状态
          this.$nextTick(() => {
            this.$refs.inputForm.clearValidate();
          });

          // 提示成功
          this.$message.success(
            this.inputFormObj.isEdit ? "修改成功" : "添加成功"
          );
        }
      });
    },
    addInputParam() {
      this.inputFormObj = {
        isEdit: false,
        index: -1,
        form: JSON.parse(JSON.stringify(defaultInputForm))
      };
      this.inputParamOpen = true;
    },
    /**
     * 上移功能
     * @param {Number} index 当前功能索引
     */
    handleInputUp(index) {
      if (index === 0) return; // 已经是第一个，不能再上移

      try  {
        // 交换当前项与上一项的位置
        const temp = this.form.inputs[index];
        this.$set(this.form.inputs, index, this.form.inputs[index - 1]);
        this.$set(this.form.inputs, index - 1, temp);
        this.$message({
          type: 'success',
          message: '上移成功!'
        });
      } catch (error) {
        this.$message.error("操作失败：" + error);
      }
    },

    /**
     * 下移功能
     * @param {Number} index 当前功能索引
     */
    handleInputDown(index) {
      if (index === this.form.inputs.length - 1) return; // 已经是最后一个，不能再下移

      try  {
        // 交换当前项与下一项的位置
        const temp = this.form.inputs[index];
        this.$set(this.form.inputs, index, this.form.inputs[index + 1]);
        this.$set(this.form.inputs, index + 1, temp);
        this.$message({
          type: 'success',
          message: '下移成功!'
        });
      } catch (error) {
        this.$message.error("操作失败：" + error);
      }
    },
    /**
     * 修改输入参数
     * @param {Object} row 行数据
     * @param {Number} index 行索引
     */
    handleInputUpdate(row, index) {
      this.inputFormObj = {
        isEdit: true,
        index: index,
        form: JSON.parse(JSON.stringify(row))
      };
      this.inputParamOpen = true;
    },

    /**
     * 删除输入参数
     * @param {Object} row 行数据
     * @param {Number} index 行索引
     */
    handleInputDelete(row, index) {
      this.$confirm("是否确认删除该输入参数?", "警告", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      })
        .then(() => {
          this.form.inputs.splice(index, 1);
          this.$message({
            type: "success",
            message: "删除成功!"
          });
        })
        .catch(() => {
          this.$message({
            type: "info",
            message: "已取消删除"
          });
        });
    },
    inputChange() {
      this.$forceUpdate();
    },
    /** 提交验证 */
    submitForm: function() {
      this.$refs["form"].validate(valid => {
        if (valid) {
          // 额外校验输入参数
          if (!this.form.inputs || this.form.inputs.length === 0) {
            this.$message.warning("请至少添加一个输入参数");
            return;
          }
          // 新增和修改操作
          if (this.tempType === "add") {
            this.$store
              .dispatch("AddFunction", this.form)
              .then(() => {
                this.$message.success("添加成功");
                this.$emit("ok");
              })
              .catch(err => {
                this.$message.error("添加失败：" + err);
              });
          } else if (this.tempType === "update") {
            this.$store
              .dispatch("EditFunction", {
                item: this.form,
                idx: this.paramIdx
              })
              .then(() => {
                this.$message.success("修改成功");
                this.$emit("ok");
              })
              .catch(err => {
                this.$message.error("修改失败：" + err);
              });
          }
        }
      });
    },
    // 添加一个监听输入参数弹窗关闭的方法
    handleInputDialogClose() {
      this.$nextTick(() => {
        if (this.$refs.inputForm) {
          this.$refs.inputForm.clearValidate();
        }
      });
    }
  }
};
</script>
<style lang="scss">
.function-form-model {
  .enum-box {
    border: 1px solid #d8d7d7;
    padding: 10px;
    margin-bottom: 10px;
    .enumTypeDiv {
      margin-top: 10px;
    }
    .enum-header {
      margin-bottom: 10px;
    }
  }
  .el-select {
    width: 100%;
  }
  .el-input-number {
    width: 100%;
  }
  .enumTypeDiv {
    display: flex;
    justify-content: flex-end;
    max-height: 200px;
    overflow: auto;
    .enum-item {
      width: 90%;
      display: flex;
      justify-content: space-around;
      align-items: center;
    }
  }
}

.is-error input {
  border-color: #f56c6c;
}

.el-form-item__error {
  color: #f56c6c;
  font-size: 12px;
  line-height: 1;
  padding-top: 4px;
  position: absolute;
  top: 100%;
  left: 0;
}
</style>
