<template>
  <el-dialog v-model="isShow" width="60%" @close="closeDialog" destroy-on-close>
    <el-form
      ref="ruleFormRef"
      :model="form"
      :rules="rules"
      label-position="top"
      label-width="200px"
      class="custom-comp-form"
    >
      <el-row
        type="flex"
        justify="space-between"
        align="middle"
        class="first-row"
        :gutter="10"
      >
        <el-col :span="15" class="first-row-first-col">
          <el-form-item prop="name">
            <el-tag size="small">规则名称</el-tag>
            <el-input v-model="form.name" />
          </el-form-item>
        </el-col>
        <el-col :span="9" class="first-row-second-col">
          <el-form-item prop="category">
            <el-tag size="small">报警类别</el-tag>
            <el-select
              v-model="form.category"
              size="mini"
              @change="categorychanged"
            >
              <el-option
                key="1"
                label="风机报警"
                value="windturbine"
              ></el-option>
              <el-option
                key="2"
                label="升压站报警"
                value="booststation"
              ></el-option>
            </el-select>
          </el-form-item>
          <el-form-item prop="rank">
            <el-tag size="small">报警级别</el-tag>
            <el-select v-model="form.rank" size="mini">
              <el-option
                v-for="item in rankList"
                :key="item.id"
                :value="item.id"
                :label="item.name"
              ></el-option>
            </el-select>
          </el-form-item>
          <el-form-item prop="enable">
            <el-tag size="small">是否启用</el-tag>
            <el-switch
              v-model="form.enable"
              :active-value="true"
              :inactive-value="false"
              active-color="#13ce66"
            />
          </el-form-item>
        </el-col>
      </el-row>
      <el-row :gutter="10" class="second-row">
        <el-col :span="6">
          <el-form-item prop="station">
            <el-tag size="small">{{
              form.category == "windturbine" ? "风场" : "电站"
            }}</el-tag>
            <el-select
              v-model="form.stationId"
              size="mini"
              @change="stationChange"
            >
              <el-option
                v-for="item in stationList"
                :key="item.id"
                :value="item.id"
                :label="item.name"
              />
            </el-select>
          </el-form-item>
          <el-form-item prop="modelId" v-if="form.category == 'windturbine'">
            <el-tag size="small">风机型号</el-tag>
            <el-select
              v-model="form.modelId"
              size="mini"
              @change="modelIdChange"
            >
              <el-option
                v-for="item in state.modelList"
                :key="item"
                :value="item.id"
                :label="item.aname"
              ></el-option>
            </el-select>
          </el-form-item>
          <el-form-item
            prop="relatedParts"
            v-if="form.category == 'windturbine'"
          >
            <el-tag size="small">所属部件</el-tag>
            <el-select v-model="form.relatedParts" style="width: 100%">
              <el-option
                v-for="item in state.relatedPartsList"
                :key="item.nemCode"
                :label="item.name"
                :value="item.nemCode"
              />
            </el-select>
          </el-form-item>
          <el-form-item prop="fault">
            <el-tag size="small">预警类型</el-tag>
            <el-select v-model="form.range" style="width: 100%">
              <el-option
                v-for="i in faultList"
                :key="i.nemCode"
                :value="i.nemCode"
                :label="i.name"
              />
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="9">
          <el-form-item prop="expression">
            <el-tag size="small">表达式</el-tag>
            <el-input
              type="textarea"
              rows="14"
              v-model="form.expression"
              id="expressionInput"
              @keyup.z.stop="handle"
            />
          </el-form-item>
        </el-col>
        <el-col :span="9">
          <el-tabs type="border-card">
            <el-tab-pane label="AI测点">
              <el-input v-model="state.AIPointSearch"> </el-input>
              <el-table
                size="mini"
                fit
                :show-header="false"
                stripe
                height="204"
                :data="filterAIList"
                @row-dblclick="rowDbclick"
              >
                <el-table-column prop="uniformCode" width="120" />
                <el-table-column prop="name" />
              </el-table>
            </el-tab-pane>
            <el-tab-pane label="DI测点">
              <el-input v-model="state.DIPointSearch"> </el-input>
              <el-table
                size="mini"
                fit
                :show-header="false"
                stripe
                height="204"
                :data="filterDIList"
                @row-dblclick="rowDbclick"
              >
                <el-table-column prop="uniformCode" width="120" />
                <el-table-column prop="name" />
              </el-table>
            </el-tab-pane>
            <el-tab-pane label="函数">
              <el-table
                size="mini"
                fit
                :show-header="false"
                stripe
                height="204"
                :data="func"
                @row-dblclick="tabFuncRowClickHandle"
              >
                <el-table-column min-width="60%">
                  <template #default="scope">
                    <el-popover trigger="hover" placement="bottom">
                      <p>描述：{{ scope.row.describe }}</p>
                      <p>参数：{{ scope.row.param }}</p>
                      <template #reference>
                        <span size="medium" transition="fade-in-linear">{{
                          scope.row.lab
                        }}</span>
                      </template>
                    </el-popover>
                  </template>
                </el-table-column>
                <el-table-column min-width="40%">
                  <template #default="scope">
                    <el-popover trigger="hover" placement="bottom">
                      <p>描述：{{ scope.row.describe }}</p>
                      <p>参数：{{ scope.row.param }}</p>
                      <template #reference>
                        <span size="medium" transition="fade-in-linear">{{
                          scope.row.name
                        }}</span>
                      </template>
                    </el-popover>
                  </template>
                </el-table-column>
              </el-table>
            </el-tab-pane>
            <el-tab-pane label="运算符">
              <div class="operator">
                <el-button
                  v-for="item in operator"
                  :key="item"
                  size="mini"
                  class="buttons"
                  @click="elInputSplit(item)"
                >
                  {{ item }}
                </el-button>
              </div>
            </el-tab-pane>
          </el-tabs>
        </el-col>
      </el-row>
      <el-row :gutter="24">
        <el-col :span="24">
          <el-form-item prop="description">
            <el-tag size="small">规则描述</el-tag>
            <el-input
              type="textarea"
              rows="4"
              v-model="form.description"
              id="descriptionInput"
            />
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>
    <template #footer>
      <span class="footerButton">
        <el-button round size="mini" @click="closeDialog">取 消</el-button>
        <el-button round size="mini" @click="submitForm(ruleFormRef)"
          >确 定</el-button
        >
      </span>
    </template>
  </el-dialog>
</template>
<script setup>
import {
  ref,
  onMounted,
  reactive,
  computed,
  watch,
  nextTick,
  defineEmits,
  defineProps,
} from "vue";
import { ElMessageBox, ElMessage } from "element-plus";
import {
  custombj_postSave,
  fetch_electrical_point_ai,
  fetch_electrical_point_di,
  getStationinfo,
  fetchPointList,
  fetchPointListByBootst,
} from "@/api/zhbj/index.js";
import { useStore } from "vuex";
const store = useStore();
const emits = defineEmits(["close"]);
const props = defineProps({
  //是否显示
  isVisible: {
    type: Boolean,
    defaule: false,
  },
  //表单
  dialogOptions: {
    type: Object,
  },
  //型号接口数据
  modelListAll: {
    type: Object,
  },
  //所属部件及预警类型
  fetchListAll: {
    type: Array,
  },
  //报警级别
  rankList: {
    type: Array,
  },
});
watch(
  () => props.isVisible,
  (val, old) => {
    nextTick(() => {
      isShow.value = val;
    });
  },
  {
    deep: true,
  }
);
watch(
  () => props.dialogOptions,
  (val, old) => {
    nextTick(() => {
      form.value = val;
      if (val.id && val.id != "") {
        if (val?.stationId.includes("FDC") || val?.stationId.includes("GDC")) {
          getfetchPointList();
        } else {
          getfetchPointListByBootst();
        }
      }
    });
  },
  {
    deep: true,
  }
);
watch(
  () => props.dialogOptions?.stationId,
  (val, old) => {
    if (val && val != "") {
      nextTick(async () => {
        state.modelList = props.modelListAll[val];
        if (val.includes("FDC")) {
          state.relatedPartsList = props.fetchListAll?.fjbj;
        } else if (val.includes("GDC")) {
          state.relatedPartsList = props.fetchListAll?.gfbj;
        } else {
          state.relatedPartsList = [];
        }
      });
    } else {
      state.relatedPartsList = [];
      state.modelList = [];
    }
  }
);

const isShow = ref(false);

const form = ref({
  id: "",
  category: "windturbine", //报警类别
  description: "", //描述
  name: "", //规则名称
  enable: true, //是否启用
  expression: "", //表达式
  range: "", //预警类型
  rank: "", //报警级别
  relatedParts: "", //所属部件
  stationId: "", //场站id
  deviceId: "",
  electricalId: "",
  lineId: "",
  modelId: "",
  projectId: "",
  tag: "",
  uniformCode: "",
});
const getExtraCharacters = (str1, str2) => {
  let result = "";
  if (str1 && str2) {
    if (str1.length < str2.length) {
      result = str2.slice(str1.length);
    } else if (str1.length > str2.length) {
      result = str1.slice(str2.length);
    }
  }

  return result;
};
const newVal = ref("");
watch(
  () => form.value.expression,
  (val, old) => {
    console.log(val, old);
    let a = getExtraCharacters(val, old);
    newVal.value = a;
  },
  {
    immediate: true,
  }
);
// 场站列表/升压站列表
const stationList = computed(() => {
  if (form.value.category == "windturbine") {
    return store.state.stationListAll;
  } else {
    return store.state.booststationList;
  }
});
const toEmits = () => {
  emits("close"); // 向父组件传递数据
};
const state = reactive({
  modelList: [], //型号列表
  relatedPartsList: [], //部件列表
  AIPointList: [],
  DIPointList: [],
  AIPointSearch: "",
  DIPointSearch: "",
});
const operator = [
  "+",
  "-",
  "*",
  "/",
  "(",
  ")",
  ">",
  ">=",
  "<",
  "<=",
  "==",
  "!=",
  "&&",
  "||",
  "!",
  "%",
  "true",
  "false",
  ".",
];
const func = [
  {
    lab: "MR",
    name: "移动极差",
    param: "测点名，时间（秒）",
    describe: "是指两个或多个连续样本值中最大值与最小值之差",
    scene: "测点的移动极差超限报警",
  },
  {
    lab: "MAR",
    name: "均值极差",
    param: "测点名，时间（秒）",
    describe: "",
    scene: "测点的均值极差计算",
  },
  {
    lab: "RiseExceed",
    name: "上升趋势",
    param: "测点名，时间（秒），阈值",
    describe: "取测点在给定的时间范围内数据上升的量是否超过阈值",
    scene: "测点值的上升速度过快等",
  },
  {
    lab: "Sustain",
    name: "持续时间",
    param: "表达式，时间（秒）",
    describe:
      "判定状态（表达式成立）持续的时间是否超过给定的时间判断状态持续的时间",
    scene: "",
  },
  {
    lab: "LastUpdateTime",
    name: "最近数据时间",
    param: "测点名",
    describe: "",
    scene: "判定离线，状态持续时间等",
  },
  {
    lab: "abs",
    name: "取绝对值",
    param: "double a",
    describe: "",
    scene: "",
  },
  {
    lab: "acos",
    name: "反余弦",
    param: "double a",
    describe: "",
    scene: "",
  },
  {
    lab: "asin",
    name: "反正弦",
    param: "double a",
    describe: "",
    scene: "",
  },
  {
    lab: "atan",
    name: "反正切",
    param: "double a",
    describe: "",
    scene: "",
  },
  {
    lab: "atan2",
    name: "xy坐标转为极坐标",
    param: "x,y",
    describe: "",
    scene: "",
  },
  {
    lab: "ceiling",
    name: "向上取整",
    param: "double a",
    describe: "",
    scene: "",
  },
  {
    lab: "cos",
    name: "余弦",
    param: "double a",
    describe: "",
    scene: "",
  },
  {
    lab: "cosh",
    name: "双曲线余弦",
    param: "double a",
    describe: "",
    scene: "",
  },
  {
    lab: "exp",
    name: "欧拉数 e 的 double 次幂的值",
    param: "double a",
    describe: "",
    scene: "",
  },
  {
    lab: "floor",
    name: "向下取整",
    param: "double a",
    describe: "",
    scene: "",
  },
  {
    lab: "log",
    name: "自然对数",
    param: "double a",
    describe: "",
    scene: "",
  },
  {
    lab: "log10",
    name: "底数为 10 的对数",
    param: "double a",
    describe: "",
    scene: "",
  },
  {
    lab: "max",
    name: "比较最大值",
    param: "double a, double b",
    describe: "",
    scene: "",
  },
  {
    lab: "min",
    name: "比较最小值",
    param: "double a, double b",
    describe: "",
    scene: "",
  },
  {
    lab: "pow",
    name: "返回第一个参数的第二个参数次幂的值",
    param: "double a, double b",
    describe: "",
    scene: "",
  },
  {
    lab: "round",
    name: "返回最接近参数的 long,或int",
    param: "double a",
    describe: "",
    scene: "",
  },
  {
    lab: "sign",
    name: "负数返回-1.0,整数返回1.0,0返回0.0",
    param: "float f/double a",
    describe: "",
    scene: "",
  },
  {
    lab: "sin",
    name: "三角正弦值",
    param: "double a",
    describe: "",
    scene: "",
  },
  {
    lab: "sinh",
    name: "双曲线正弦",
    param: "double x",
    describe: "",
    scene: "",
  },
  {
    lab: "sqrt",
    name: "正平方根",
    param: "double a",
    describe: "",
    scene: "",
  },
  {
    lab: "tan",
    name: "正切",
    param: "double a",
    describe: "",
    scene: "",
  },
  {
    lab: "tanh",
    name: "双曲线正切",
    param: "double x",
    describe: "",
    scene: "",
  },
  { lab: "PI", name: "圆周率", param: "", describe: "", scene: "" },
  { lab: "E", name: "自然对数", param: "", describe: "", scene: "" },
];
const faultList = computed(() => props.fetchListAll.yj); //预警类型列表
const ruleFormRef = ref(null);
const rules = reactive({
  name: [{ required: true, message: "请输入规则名称", trigger: "blur" }],
  category: [{ required: true, message: "请选择报警类别", trigger: "change" }],
  rank: [{ required: true, message: "请选择报警级别", trigger: "change" }],
  stationId: [{ required: true, message: "请选择风场", trigger: "change" }],
  expression: [
    { required: true, message: "表达式不能为空", trigger: ["change"] },
  ],
});

//categorychanged
const categorychanged = async (val) => {
  form.value.stationId = "";
  form.value.modelId = "";
  form.value.expression = "";
  form.value.relatedParts = "";
  state.AIPointList = [];
  state.DIPointList = [];
};
//stationChange
const stationChange = async (val) => {
  if (form.value.category == "windturbine") {
    form.value.modelId = "";
    state.modelList = props.modelListAll[val];
  } else {
    getfetchPointListByBootst();
  }
};
//modelIdChange
const modelIdChange = async () => {
  getfetchPointList();
};
// 根据场站和型号查询测点数据
const getfetchPointList = async () => {
  const { data } = await fetchPointList(
    form.value.stationId,
    form.value.modelId
  );
  if (Object.keys(data).length) {
    state.AIPointList = data.ai.sort(function (a, b) {
      return a.uniformCode - b.uniformCode;
    });
    state.DIPointList = data.di.sort(function (a, b) {
      return a.uniformCode - b.uniformCode;
    });
  }
};

// 根据升压站查询测点数据
const getfetchPointListByBootst = async () => {
  const { data } = await fetchPointListByBootst(form.value.stationId);
  if (Object.keys(data).length) {
    state.AIPointList = data.ai.sort(function (a, b) {
      return a.uniformCode - b.uniformCode;
    });
    state.DIPointList = data.di.sort(function (a, b) {
      return a.uniformCode - b.uniformCode;
    });
  }
};
//筛选AI测点
const filterAIList = computed(() =>
  state.AIPointList?.filter(
    (data) =>
      !state.AIPointSearch ||
      data.uniformCode.includes(state.AIPointSearch) ||
      data.name.includes(state.AIPointSearch)
  )
);
//筛选DI测点
const filterDIList = computed(() =>
  state.DIPointList?.filter(
    (data) =>
      !state.DIPointSearch ||
      data.uniformCode.includes(state.DIPointSearch) ||
      data.name.includes(state.DIPointSearch)
  )
);

// 函数点击事件
const tabFuncRowClickHandle = (row) => {
  let elInput = document.getElementById("expressionInput");
  let startPos = elInput.selectionStart; //第0个字符到选中的字符
  let endPos = elInput.selectionEnd; //选中字符到末尾字符
  if (startPos === undefined || endPos === undefined) return;
  let txt = elInput.value;
  let func;
  if (
    row.lab === "MR" ||
    row.lab === "MAR" ||
    row.lab === "RiseExceed" ||
    row.lab === "Sustain" ||
    row.lab === "LastUpdateTime"
  ) {
    func = row.lab + "()";
  } else if (row.lab === "PI" || row.lab === "E") {
    func = "Math." + row.lab;
  } else {
    func = "Math." + row.lab + "()";
  }
  // 将插值添加到选中光标位置
  let result = txt.substring(0, startPos) + func + txt.substring(endPos);
  elInput.value = result;
  // 重新定义光标位置
  elInput.focus();
  if (row.lab === "PI" || row.lab === "E") {
    elInput.selectionStart = startPos + func.length;
    elInput.selectionEnd = startPos + func.length;
  } else {
    elInput.selectionStart = startPos + func.length - 1;
    elInput.selectionEnd = startPos + func.length - 1;
  }
  form.value.expression = result; // 赋值给表单中的的字段
};
//rowDbclick
const rowDbclick = (row) => {
  elInputSplit(row);
};
// 表达式字符串拼接
const elInputSplit = async (val) => {
  let elInput = document.getElementById("expressionInput");
  let startPos = elInput.selectionStart;
  let endPos = elInput.selectionEnd;
  if (startPos === undefined || endPos === undefined) return;
  let txt = elInput.value;
  let txtSplit = val.uniformCode || val;
  let result = txt.substring(0, startPos) + txtSplit + txt.substring(endPos);
  elInput.value = result;
  elInput.focus();
  elInput.selectionStart = startPos + txtSplit.length;
  elInput.selectionEnd = startPos + txtSplit.length;
  form.value.expression = result;
};
const handle = (e) => {
  if (e.ctrlKey && e.key == "z") {
    form.value.expression = form.value.expression.replace(newVal.value, "");
  }
};
//提交
const submitForm = async (formEl) => {
  if (!formEl) return;
  await formEl.validate((valid, fields) => {
    if (valid) {
      save();
    } else {
      console.log("error submit!", fields);
    }
  });
};
//保存
const save = async () => {
  const res = await custombj_postSave(form.value);
  console.warn(res);
  if (res.code != 200) {
    ElMessage.error(res.msg);
  } else {
    ElMessage.success(`保存成功!`);
    closeDialog();
  }
};
//reset
const resetForm = (formEl) => {
  formEl.resetFields();
};
//confirm关闭
const handleClose = () => {
  ElMessageBox.confirm("确认关闭？")
    .then(() => {
      closeDialog();
    })
    .catch(() => {
      // catch error
    });
};
//关闭触发事件
const closeDialog = () => {
  resetForm(ruleFormRef.value);
  form.value = {};
  state.AIPointList = [];
  state.DIPointList = [];
  toEmits();
};
</script>
<style lang="less" scoped>
.col-box {
  display: flex;
  flex-direction: column;
}

.select-mini {
  width: 120px;
}

.el-tabs__content {
  padding: 0 !important;
}

.el-tabs--border-card {
  -webkit-box-shadow: none;
  box-shadow: none;
}

.border {
  border: solid red 1px;
}

.el-table--mini td {
  padding: 3px 0;
}

.el-button-group .el-button--primary {
  border: none;
}

.el-form--label-top .el-form-item__label {
  padding: 0;
}
</style>
