<template>
  <div class="static-form">
    <el-form :model="state.form" ref="form_ref" :rules="state.rules" label-width="120px">
      <div class="static-form-item">
        <el-form-item label="预警对象/分类" prop="warn_type">
          <el-cascader
            :disabled="props.isEdit"
            ref="cascader_ref"
            style="flex: 1"
            placeholder="请选择预警对象/分类"
            :options="staticTypeOptions"
            v-model="state.form.warn_type"
            @change="changeWarnStaticType"
            :props="cascaderProps">
          </el-cascader>
        </el-form-item>
        <el-form-item label="预警指标" prop="warn_indicator">
          <el-select
            style="flex: 1"
            :disabled="!formFormat.warn_type || props.isEdit"
            v-model="state.form.warn_indicator"
            placeholder="请选择预警指标"
            @change="chooseWarnIndicator">
            <el-option v-for="item in warningIndexOptions" :key="item.id" :label="item.metric_name" :value="item.id">
            </el-option>
          </el-select>
        </el-form-item>
      </div>
      <div>
        <div v-if="state.form.warning_scpoe_form.length > 0">
          <gap-title :hasLine="true" title="预警范围"></gap-title>
          <div class="static-form-item">
            <div class="warning-scope-main">
              <div class="warn-scpoe-form" v-for="(item, index) in state.form.warning_scpoe_form" :key="index">
                <el-form-item :label="item.chinese_name">
                  <el-select class="warn-scpoe-select" v-model="item.select" style="width: 114px">
                    <el-option v-for="(value, key) in selectRule" :key="key" :label="value" :value="key" />
                  </el-select>
                </el-form-item>
                <el-form-item
                  label=""
                  class="no-el-label warn-scpoe-input-item"
                  prop="value"
                  :rules="[
                    {
                      validator: (rule, value, callback) => validateValue(rule, value, callback, item, index),
                      trigger: showSelect.includes(item.select) ? 'change' : 'blur',
                    },
                  ]">
                  <el-input
                    class="warn-scpoe-input-value"
                    v-model="state.form.warning_scpoe_form[index].value"
                    :placeholder="`请输入${item.chinese_name}`"
                    v-if="!item.is_linked"
                    :disabled="item.select == 'all'">
                  </el-input>
                  <el-select
                    class="warn-scpoe-input-value"
                    v-else
                    v-model="item.value"
                    :placeholder="`请选择${item.chinese_name}`"
                    filterable
                    :loading="item.loading"
                    remote
                    :disabled="item.select == 'all'"
                    :remote-method="(query) => remoteMethod(query, index, item)">
                    <el-option v-for="item in item.options" :key="item" :label="item" :value="item"> </el-option>
                  </el-select>
                </el-form-item>
              </div>
            </div>
          </div>
        </div>
        <gap-title :hasLine="true" title="预警规则"></gap-title>
        <div class="static-form-item">
          <div class="warning-rule-main">
            <el-form-item label="风险程度" prop="risk_level" v-if="isEmpty">
              <el-select style="flex: 1" v-model="state.form.risk_level" placeholder="请选择风险程度" filterable>
                <el-option v-for="item in riskLevelOptions" :key="item.id" :label="item.name" :value="item.id">
                </el-option>
              </el-select>
            </el-form-item>
            <Gateway v-else ref="warn_type_com" :form="rule_rows" :rule_type="alert_rule_type" />
          </div>
        </div>
      </div>
    </el-form>
  </div>
</template>

<script setup>
import { computed, nextTick, onMounted, reactive, ref, shallowReactive, watch } from "vue";
import gapTitle from "@/components/gap-title.vue";
import Gateway from "./gateway.vue";
import { ElMessage } from "element-plus";
import axios from "@/request/http.js";
import { GetRuleTypeOptions, Empty } from "@/components/env.js";

const showSelect = ["=~", "!~"];
const selectRule = ref({
  all: "全部",
  "=": "等于",
  "!=": "不等于",
  "=~": "正则匹配",
  "!~": "正则不匹配",
});
const riskLevelOptions = ref([
  {
    id: 4,
    name: "重大风险",
  },
  {
    id: 3,
    name: "较大风险",
  },
  {
    id: 2,
    name: "一般风险",
  },
  {
    id: 1,
    name: "低风险",
  },
]);
const props = defineProps({
  form: {
    type: Object,
    default: null,
  },
  isEdit: {
    type: Boolean,
    default: false,
  },
});
const validateValue = (rule, value, callback, item, index) => {
  if (!item.is_required || item.select == "all") return callback();
  if (item.value == "") {
    let msg = showSelect.includes(item.select) ? `请选择${item.chinese_name}` : `请输入${item.chinese_name}`;
    return callback(new Error(msg));
  }
  return callback();
};
const state = reactive({
  form: {
    warn_type: [],
    warn_indicator: "",
    risk_level: "",
    warning_scpoe_form: [],
  },
  rules: {
    warn_type: [{ type: "array", required: true, message: "请选择预警对象/分类", trigger: "change" }],
    warn_indicator: [{ required: true, message: "请选择预警指标", trigger: "change" }],
    risk_level: [{ required: true, message: "请选择风险程度", trigger: "change" }],
  },
});
const info = () => {
  state.form.warn_type =
    props.form.warn_target && props.form.warn_type ? [props.form.warn_target, props.form.warn_type] : [];
  state.form.warn_indicator = props.form.warn_indicator;
  alert_rule_type.value = props.form.rule_type || "1";
  let params = {
    page: 1,
    page_size: 10000000000000,
    class_id: props.form.warn_type,
    is_enabled: 1,
  };
  getWarningIndicator(params, () => {
    state.form.warning_scpoe_form = props.form?.warning_scpoe_form || [];
  });
  state.form.risk_level = props.form.risk_level;
};
const ruleTypeOptions = ref({});
const getRuleTypeOptions = async (cb) => {
  ruleTypeOptions.value = await GetRuleTypeOptions();
  if (props.form) {
    info();
  }
};
watch(
  () => props.form,
  (n) => {
    if (!n) return;
    info();
  },
  {
    deep: true,
  }
);
const module_data = ref({});
const alert_rule_type = ref("");
const isEmpty = computed(() => {
  return Empty(alert_rule_type.value, ruleTypeOptions.value);
});
const emits = defineEmits(["update-duration"]);
const chooseWarnIndicator = () => {
  axios
    .get("/v1/api/metric_config", {
      params: {
        id: state.form.warn_indicator,
      },
    })
    .then((res) => {
      if (res.data.code == 200) {
        module_data.value = res.data.data;
        alert_rule_type.value = module_data.value.alert_rule_type;
        state.form.warning_scpoe_form = module_data.value.alert_range.map((e) => {
          return {
            ...e,
            value: "",
            select: "all",
            options: [],
            loading: false,
          };
        });
        emits("update-duration", module_data.value);
      } else {
        ElMessage.error(res.data.data);
      }
    });
};
const remoteMethod = (query, index, item) => {
  state.form.warning_scpoe_form[index].loading = true;
  const params = {
    metric_name: item.metric_name,
    // metric_name: "grpc_client_handled_total",
    metric_label: item.metric_label,
    // metric_label: "grpc_method",
    value: query,
  };
  axios.get(`/v1/api/prometheus/value`, { params }).then((res) => {
    if (res.data.code == 200) {
      state.form.warning_scpoe_form[index].options = res.data.data.list || [];
      state.form.warning_scpoe_form[index].loading = false;
    }
  });
};
const warn_type_com_form = computed(() => props.form?.warn_type_com || null);
const cascaderProps = {
  value: "class_id",
  label: "class_name",
};
const staticTypeOptions = ref([]);
const staticTypeFormat = (res) => {
  let arr = res?.map((e) => {
    let children = [];
    let is_disabled = false;
    if (e.children?.length == 0 && e.parent_id == 0) {
      children = [];
      is_disabled = true;
    } else {
      children = staticTypeFormat(e.children);
      is_disabled = false;
    }
    return {
      ...e,
      children: children,
      disabled: is_disabled,
    };
  });
  return arr;
};
const getStaticTypeOptions = () => {
  axios.get("/v1/api/alert_class/tree").then(async (res) => {
    if (res.data.code == 200) {
      staticTypeOptions.value = staticTypeFormat(res.data.data);
    } else {
      ElMessage.error(res.data.msg);
    }
  });
};
const formFormat = computed(() => {
  let [warn_target = "", warn_type = ""] = state.form.warn_type || [];
  let obj = {
    ...state.form,
    warn_target,
    warn_type,
    isEmpty: isEmpty.value,
    alert_rule_type: module_data.value.alert_rule_type,
  };
  if (!isEmpty.value) {
    obj = {
      ...obj,
      ...(warn_type_com.value?.form || {}),
    };
  }
  return obj;
});
const warningIndexOptions = ref({});
const cascader_ref = ref(null);
const changeWarnStaticType = async () => {
  let class_id = state.form.warn_type[1];
  if (!class_id) return;
  let params = { page: 1, page_size: 10000000000000, class_id, is_enabled: 1 };
  getWarningIndicator(params);
};
const getWarningIndicator = (params, cb) => {
  axios.get("/v1/api/metric_config/list", { params }).then((res) => {
    if (res.data.code == 200) {
      warningIndexOptions.value = res.data.data?.list || [];
      if (!cb) {
        state.form.warn_indicator = warningIndexOptions.value[0]?.id || "";
        if (state.form.warn_indicator) {
          chooseWarnIndicator();
        }
      } else {
        cb();
      }
      setTimeout(() => {
        form_ref.value.clearValidate(["warn_indicator"]);
      });
    }
  });
};
const changeRuleType = () => {};
const form_ref = ref(null);
const warn_type_com = ref(null);
const Submit = async () => {
  let form_valid = await new Promise((resolve, reject) => {
    form_ref.value.validate((res) => resolve(res));
  });
  if (isEmpty.value) return form_valid;
  let warn_type_com_valid = await warn_type_com.value?.Submit();
  return form_valid && warn_type_com_valid;
};
const ruleHeaders = [
  {
    prop: "warning_threshold",
    label: "预警阈值",
    width: "500px",
  },
  {
    prop: "risk_level",
    label: "风险程度",
  },
];
const rule_rows = computed(() => props.form?.ruleRows || []);
onMounted(() => {
  getStaticTypeOptions();
  getRuleTypeOptions();
});
defineExpose({
  Submit,
  form: formFormat,
  form_ref,
});
</script>

<style lang="scss" scoped>
.static-form {
  :deep(.gap-title) {
    margin-bottom: 16px;
  }
  &-item {
    max-width: 1080px;
    width: 100%;
    padding-left: 8px;
    .warning-scope-main {
      //   display: grid;
      //   grid-template-columns: 1fr 1fr;
      //   grid-column-gap: 16px;
      :deep(.el-input-group__prepend) {
        border-radius: 4px;
        border-top-right-radius: 0;
        border-bottom-right-radius: 0;
      }
      .warn-scpoe-form {
        width: 100%;
        display: flex;
        align-items: center;
        .warn-scpoe-select {
          width: 114px !important;
          :deep(.el-input__wrapper) {
            background-color: #2b4695;
            border-radius: 4px;
            border-top-right-radius: 0;
            border-bottom-right-radius: 0;
            .el-input__inner {
              color: #fff;
            }
          }
        }
        .warn-scpoe-input-item {
          flex: 1;
          .warn-scpoe-input-value {
            flex: 1;
            :deep(.el-input__wrapper) {
              border-top-left-radius: 0;
              border-bottom-left-radius: 0;
            }
          }
        }
      }
    }
  }
}
.no-el-label {
  :deep(.el-form-item__content) {
    margin-left: 0 !important;
  }
}
</style>
