<template>
  <div class="gateway-form">
    <div class="gateway-form-item">
      <el-form
        :model="state.form.ruleRows"
        ref="form_ref"
        :rules="state.tableRules"
        label-width="0"
        style="width: 100%">
        <el-table :data="state.form.ruleRows" stripe border>
          <el-table-column
            v-for="header in ruleHeaders"
            :prop="header.prop"
            :key="header.prop"
            :label="header.label"
            :width="header.width">
            <template #default="{ $index }">
              <div class="warning-threshold" v-if="header.prop == 'warning_threshold'">
                <el-form-item :prop="`[${$index}].from`" :rules="state.tableRules.from" style="flex: 1">
                  <el-input
                    style="flex: 1"
                    v-model.number="state.form.ruleRows[$index].from"
                    placeholder="请输入"
                    @input="changeWarningThresholdFrom($index)">
                    <template v-if="state.form.rule_type != 'empty'" #append>ms</template>
                  </el-input>
                </el-form-item>
                <span class="to">-</span>
                <el-form-item label="" :prop="`${$index}.to`" :rules="state.tableRules.to" style="flex: 1">
                  <el-input
                    style="flex: 1"
                    v-model.number="state.form.ruleRows[$index].to"
                    placeholder="请输入"
                    clearable
                    @input="changeWarningThresholdTo($index)">
                    <template v-if="state.form.rule_type != 'empty'" #append>ms</template>
                  </el-input>
                </el-form-item>
              </div>
              <div v-else-if="header.prop == 'risk_level'">
                <el-form-item label="" :prop="`[${$index}].risk_level`" :rules="state.tableRules.risk_level">
                  <el-select style="flex: 1" v-model="state.form.ruleRows[$index].risk_level" placeholder="请选择">
                    <el-option
                      v-for="item in riskLevelOptions($index)"
                      :key="item.id"
                      :label="item.name"
                      :value="item.id">
                    </el-option>
                  </el-select>
                </el-form-item>
              </div>
            </template>
          </el-table-column>
          <el-table-column prop="" label="操作" width="150px">
            <template #default="{ $index }">
              <div class="table-operation">
                <el-button
                  link
                  type="primary"
                  @click="createRule($index)"
                  :disabled="state.form.ruleRows.length >= riskLevels.length">
                  新增
                </el-button>
                <span class="line"></span>
                <el-button link type="primary" @click="removeRule($index)" :disabled="state.form.ruleRows.length == 1">
                  删除
                </el-button>
              </div>
            </template>
          </el-table-column>
        </el-table>
      </el-form>
    </div>
  </div>
</template>

<script setup>
import { computed, reactive, ref, watch } from "vue";
import gapTitle from "@/components/gap-title.vue";
const props = defineProps({
  form: {
    type: Object,
    default: null,
  },
});

const state = reactive({
  form: {
    ruleRows: [],
  },
  tableRules: {
    from: [{ required: true, message: "请输入", trigger: "blur" }],
    to: [{ required: true, message: "请输入", trigger: "blur" }],
    risk_level: [{ required: true, message: "请选择", trigger: "change" }],
  },
});
const form_ref = ref(null);
const Submit = async () => {
  let form_valid = await new Promise((resolve, reject) => {
    form_ref.value.validate((res) => resolve(res));
  });
  return form_valid;
};
const riskLevels = ref([
  {
    id: 1,
    name: "重大风险",
  },
  {
    id: 2,
    name: "较大风险",
  },
  {
    id: 3,
    name: "一般风险",
  },
  {
    id: 4,
    name: "低风险",
  },
]);
const riskLevelOptions = computed(() => {
  return (index) => {
    let risk_level = state.form.ruleRows[index].risk_level;
    let rows = state.form.ruleRows.map((e) => e.risk_level);
    if (risk_level) {
      let i = rows.findIndex((e) => e == risk_level);
      rows.splice(i, 1);
    }
    return riskLevels.value.filter((e) => !rows.includes(e.id));
  };
});
const ruleHeaders = [
  {
    prop: "warning_threshold",
    label: "预警阈值",
    width: "500px",
  },
  {
    prop: "risk_level",
    label: "风险程度",
  },
];
const createRule = (index = -1) => {
  state.form.ruleRows.splice(index + 1, 0, {
    from: "",
    to: "",
    risk_level: "",
  });
};
const setLimits = (index) => {
  let rows = [...state.form.ruleRows];
  rows.splice(index, 1);
  return (
    rows.map((e) => {
      return {
        down: +e.from,
        up: +e.to,
      };
    }) || []
  );
};
const changeWarningThresholdFrom = (index) => {
  let { down, up } = limit.value;
  if (down === "") return;
  let { from, to } = state.form.ruleRows[index];
  if (+from > +up || (index == 0 && +from < +down) || +from > +to) {
    state.form.ruleRows[index].from = "";
    return;
  }
  let rows = setLimits(index);
  if (rows.length == 0) return;
  try {
    rows.forEach((e) => {
      if (+e.up >= +from > +e.down) {
        throw "";
      }
    });
  } catch (e) {
    state.form.ruleRows[index].from = "";
  }
};
const changeWarningThresholdTo = (index) => {
  let { down, up } = limit.value;
  if (up === "") return;
  let { from, to } = state.form.ruleRows[index];
  if ((index == 0 && +to > +up) || +to < +down || +from > +to) {
    state.form.ruleRows[index].to = "";
    return;
  }
  let rows = setLimits(index);
  if (rows.length == 0) return;
  try {
    rows.forEach((e) => {
      if (+e.up > +to > +e.down) {
        throw "";
      }
    });
  } catch (e) {
    state.form.ruleRows[index].to = "";
  }
};
const removeRule = (index) => {
  state.form.ruleRows.splice(index, 1);
};
watch(
  () => props.form,
  (f) => {
    if (!f?.ruleRows) {
      createRule();
      return;
    }
    state.form.ruleRows =
      f.ruleRows.map((e) => {
        return {
          from: e.from,
          to: e.to,
          risk_level: e.risk_level,
        };
      }) || [];
    if (state.form.ruleRows.length == 0) {
      createRule();
    }
  },
  {
    deep: true,
    immediate: true,
  }
);
defineExpose({
  Submit,
  form: state.form,
  form_ref,
});
</script>

<style lang="scss" scoped>
.gateway-form {
  margin-bottom: 16px;
  :deep(.gap-title) {
    margin-bottom: 16px;
  }
  &-item {
    max-width: 1080px;
    width: 100%;
    padding-left: 110px;
    :deep(.el-table thead th) {
      background-color: #f5f6f9;
    }
    .indicator-expression {
      height: 300px;
      width: 100%;
      :deep(.vue-ace-editor) {
        margin-top: 0;
      }
    }
  }
}
:deep(.el-form-item) {
  margin-bottom: 0 !important;
}
.warning-threshold {
  display: flex;
  align-items: center;
  :deep(.el-input-group__append, .el-input-group__prepend) {
    border-radius: 4px;
    border-top-left-radius: 0;
    border-bottom-left-radius: 0;
  }
}
.to {
  margin: 0 16px;
}
.line {
  width: 1px;
  height: 14px;
  background-color: #c1c7d7;
  margin: 0 16px;
  display: inline-block;
}
.rule-table {
  :deep(.el-table thead th) {
    background-color: #f5f6f9;
  }
}
</style>
