<template>
  <div class="add-form">
    <el-form :model="state.form" ref="form_ref" :rules="state.rules" label-width="100px">
      <div class="add-form-item">
        <el-form-item label="指标名称" prop="name">
          <el-input v-model="state.form.name" :disabled="isEdit" placeholder="请输入指标名称"></el-input>
        </el-form-item>
        <el-form-item label="指标表达式" prop="indicator_expression">
          <div class="indicator-expression">
            <bg-code-editor v-model="state.form.indicator_expression"></bg-code-editor>
          </div>
        </el-form-item>
        <el-form-item label="预警范围" prop="">
          <el-form
            :model="state.form.warningScopeRows"
            ref="table_form_ref"
            :rules="state.tableRules"
            label-width="0"
            style="width: 100%">
            <el-table
              :data="state.form.warningScopeRows"
              stripe
              border
              empty-text="请输入表达式，根据表达式$...$自动生成表格">
              <el-table-column
                v-for="header in warningScopeHeaders"
                :prop="header.prop"
                :key="header.prop"
                :label="header.label"
                :width="header.width">
                <template #default="{ $index }">
                  <div v-if="header.prop == 'indicator_tag'">
                    <el-form-item
                      :prop="`[${$index}].input_indicator_tag`"
                      :rules="state.tableRules.input_indicator_tag">
                      <div class="indictor-tag">
                        <el-popover popper-class="cascader-operation" placement="bottom-start">
                          <template #reference>
                            <el-input
                              v-model="state.form.warningScopeRows[$index].input_indicator_tag"
                              placeholder="请选择指标标签"
                              @input="getDataTree"></el-input>
                          </template>
                          <div class="is-loading" v-show="isLoading">
                            <el-icon>
                              <Loading />
                            </el-icon>
                            <span>加载中</span>
                          </div>
                          <el-cascader-panel
                            v-show="!isLoading"
                            :options="dataTree"
                            :props="indicator_tag_props"
                            @change="(val) => handleChange(val, $index)" />
                        </el-popover>
                      </div>
                    </el-form-item>
                  </div>
                  <div v-else-if="header.prop == 'cname'">
                    <el-form-item :prop="`[${$index}].cname`" :rules="state.tableRules.cname">
                      <el-input
                        style="flex: 1"
                        v-model="state.form.warningScopeRows[$index].cname"
                        :maxlength="20"
                        show-word-limit
                        placeholder="请输入中文名称">
                      </el-input>
                    </el-form-item>
                  </div>
                  <div v-else-if="header.prop == 'is_required'">
                    <el-form-item :prop="`[${$index}].is_required`" :rules="state.tableRules.is_required">
                      <el-select
                        v-model="state.form.warningScopeRows[$index].is_required"
                        placeholder="请选择"
                        style="flex: 1">
                        <el-option v-for="(value, key) in tableSelOptions" :key="key" :label="value" :value="key">
                        </el-option>
                      </el-select>
                    </el-form-item>
                  </div>
                  <div v-else-if="header.prop == 'is_linkage'">
                    <el-form-item :prop="`[${$index}].is_linkage`" :rules="state.tableRules.is_linkage">
                      <el-select
                        v-model="state.form.warningScopeRows[$index].is_linkage"
                        placeholder="请选择"
                        style="flex: 1">
                        <el-option v-for="(value, key) in tableSelOptions" :key="key" :label="value" :value="key">
                        </el-option>
                      </el-select>
                    </el-form-item>
                  </div>
                </template>
              </el-table-column>
            </el-table>
          </el-form>
        </el-form-item>
        <el-form-item label="预警规则类型" prop="rule_type">
          <el-select
            style="flex: 1"
            v-model="state.form.rule_type"
            placeholder="请选择"
            filterable
            @change="changeRuleType">
            <el-option v-for="(value, key) in ruleTypeOptions" :key="key" :label="value" :value="key"> </el-option>
          </el-select>
        </el-form-item>
        <div class="duration">
          <el-form-item label="持续时间" prop="time">
            <span>当预警持续</span>
            <el-input v-model="state.form.time" placeholder="请输入持续时间" @input="inputNum"></el-input>
          </el-form-item>
          <el-form-item label="" class="no-el-label">
            <el-select v-model="state.form.unit" placeholder="请选择">
              <el-option v-for="(value, key) in unitOptions" :key="key" :label="value.label" :value="key"> </el-option>
            </el-select>
            <span>时产生报警</span>
          </el-form-item>
        </div>
        <el-form-item label="检查周期" prop="inspection_cycle">
          <el-select style="flex: 1" v-model="state.form.inspection_cycle" placeholder="请选择检查周期">
            <el-option v-for="item in inspectionCycleOptions" :key="item" :label="item" :value="item"> </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="是否立即启用">
          <el-switch
            class="bg-switch-ele"
            v-model="state.form.state"
            :active-value="1"
            :inactive-value="0"
            inline-prompt
            active-text="是"
            inactive-text="否" />
        </el-form-item>
      </div>
    </el-form>
  </div>
</template>

<script setup>
import { reactive, ref, shallowReactive, computed, nextTick, watch } from "vue";
import gapTitle from "@/components/gap-title.vue";
import ManualDistributionForm from "@/components/manual-distribution/form.vue";
import { MAX_DAY, ONLY_INPUT_NUM } from "@/components/env.js";
const props = defineProps({
  row: {
    type: Object,
    default: null,
  },
});
const tableSelOptions = ["否", "是"];
const ruleTypeOptions = {
  empty: "空",
  1: "百分比范围",
  2: "毫秒范围",
  3: "秒范围",
  4: "个范围",
  5: "温度范围",
};
const isEdit = computed(() => !!props.row);
const history = computed(() => props.row?.manual_distribution_form || null);
const typrFormData = computed(() => props.row?.type_com_ref || null);
const unitOptions = {
  s: { label: "秒", max: MAX_DAY * 24 * 3600 },
  m: { label: "分钟", max: MAX_DAY * 24 * 60 },
  h: { label: "小时", max: MAX_DAY * 24 },
};
const state = reactive({
  form: {
    name: "",
    indicator_expression: "",
    rule_type: "empty",
    time: 10,
    unit: "s",
    inspection_cycle: 1,
    warningScopeRows: [],
    state: 1,
  },
  rules: {
    name: [{ required: true, message: "请输入指标名称", trigger: "blur" }],
    indicator_expression: [{ required: true, message: "请输入指标表达式", trigger: "blur" }],
    time: [{ required: true, message: "请输入持续时间", trigger: "blur" }],
  },
  tableRules: {
    input_indicator_tag: [{ required: true, message: "请选择", trigger: "blur" }],
    cname: [{ required: true, message: "请输入", trigger: "blur" }],
  },
});
const warningScopeHeaders = [
  {
    prop: "key",
    label: "变量名称",
    width: 100,
  },
  {
    prop: "indicator_tag",
    label: "指标标签",
  },
  {
    prop: "cname",
    label: "中文名称",
  },
  {
    prop: "is_required",
    label: "是否必填",
    width: 150,
  },
  {
    prop: "is_linkage",
    label: "是否联动",
    width: 150,
  },
];
const dataTree = ref([]);
const isLoading = ref(false);
const getDataTree = () => {
  isLoading.value = true;
  setTimeout(() => {
    const res = {
      code: 200,
      msg: "OK",
      data: [
        {
          name: "http_requests_total",
          children: [
            {
              name: "instance",
              value: "localhost:2023",
            },
            {
              name: "job",
              value: "prometheus",
            },
            {
              name: "method",
              value: "GET",
            },
          ],
        },
        {
          name: "system_monitor_counter",
          children: [
            {
              name: "instance",
              value: "localhost:2023",
            },
            {
              name: "job",
              value: "prometheus",
            },
            {
              name: "system_id",
              value: "YW230177",
            },
            {
              name: "user_id",
              value: "xc-admin",
            },
          ],
        },
      ],
    };
    dataTree.value = res.data;
    isLoading.value = false;
  }, 2000);
};

const handleChange = async (val, index) => {
  state.form.warningScopeRows[index].indicator_scope = val[0];
  state.form.warningScopeRows[index].input_indicator_tag = val[1];
  state.form.warningScopeRows[index].indicator_tag = val[1];
};
const indicator_tag_props = {
  value: "name",
  label: "name",
};
const tableCreateKeys = ref([]);
watch(
  () => state.form.indicator_expression,
  (n) => {
    tableCreateKeys.value = n?.match(/\$(.+?)\$/g) || [];
    let arr = [];
    tableCreateKeys.value.forEach((e) => {
      let i = state.form.warningScopeRows.findIndex((el) => el.key == e);
      arr.push(
        i != -1
          ? state.form.warningScopeRows[i]
          : {
              key: e,
              input_indicator_tag: "",
              indicator_scope: "",
              indicator_tag: "",
              cname: "",
              is_required: 1,
              is_linkage: 0,
            }
      );
    });
    state.form.warningScopeRows = arr;
  }
);
const inputNum = () => {
  state.form.time = state.form.time.replace(/[^\d]/g, "");
  let time = +state.form.time;
  let { max } = unitOptions[state.form.unit];
  if (time > +max) {
    state.form.time = max;
  }
};
const inspectionCycleOptions = ref([1, 3, 5, 10, 20]);
const form_ref = ref(null);
const table_form_ref = ref(null);
const Submit = async () => {
  let form_valid = await new Promise((resolve, reject) => {
    form_ref.value.validate((res) => resolve(res));
  });
  let table_form_valid = await new Promise((resolve, reject) => {
    table_form_ref.value.validate((res) => resolve(res));
  });
  if (form_valid && table_form_valid) {
    return {
      ...state.form,
    };
  }
  return;
};
const changeRuleType = () => {};
watch(
  () => props.row,
  async (n) => {
    if (!n) return;
    state.form.warningScopeRows =
      n.warningScopeRows.map((e) => {
        return {
          key: e.key,
          input_indicator_tag: e.input_indicator_tag,
          indicator_scope: e.indicator_scope,
          indicator_tag: e.indicator_tag,
          cname: e.cname,
          is_required: e.is_required || 1,
          is_linkage: e.is_linkage || 0,
        };
      }) || [];
    state.form.name = n.name;
    state.form.rule_type = n.rule_type || "empty";
    state.form.inspection_cycle = n.inspection_cycle || 1;
    state.form.state = n.state || 1;
    state.form.time = n.time || 10;
    state.form.unit = n.unit || "s";
    state.form.indicator_expression = n.indicator_expression;
  },
  { deep: true, immediate: true }
);
defineExpose({
  Submit,
});
</script>

<style lang="scss" scoped>
.add-form {
  :deep(.gap-title) {
    margin-bottom: 16px;
  }
  &-item {
    max-width: 1080px;
    width: 100%;
    .indicator-expression {
      height: 300px;
      width: 100%;
      :deep(.vue-ace-editor) {
        margin-top: 0;
      }
    }
    .duration {
      display: flex;
      align-items: center;
      gap: 8px;
      :deep(.el-form-item__content) {
        display: flex;
        align-items: center;
        gap: 8px;
        > .el-input {
          flex: 1;
          width: 80px;
        }
      }
      .no-el-label {
        :deep(.el-form-item__content) {
          .el-select {
            width: 80px;
          }
        }
      }
    }
    :deep(.el-switch__inner) {
      .is-hide {
        display: none;
      }
    }
    :deep(.el-input-group__append, .el-input-group__prepend) {
      border-radius: 4px;
      border-top-left-radius: 0;
      border-bottom-left-radius: 0;
    }
  }
}
.no-el-label {
  :deep(.el-form-item__content) {
    margin-left: 0 !important;
  }
}
.manual-distribution-form {
  :deep(.el-form-item) {
    &:not(:last-child) {
      margin-bottom: 18px;
    }
  }
}
.indictor-tag {
  width: 100%;
}
</style>
<style lang="scss">
.el-form-item {
  min-height: 36px;
  label {
    height: 36px;
    line-height: 36px;
  }
  .el-input__inner {
    min-height: 34px;
  }
}
.cascader-operation {
  width: auto !important;
  padding: 0 !important;
  min-width: 180px !important;
  position: relative;
  min-height: 204px;
  .is-loading {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 4px;
    svg {
      animation: rotate 3s linear infinite;
    }
    @keyframes rotate {
      from {
        transform: rotate(0deg);
      }
      to {
        transform: rotate(360deg);
      }
    }
  }
  .el-scrollbar {
    border-radius: 0;
  }
  .el-cascader-panel {
    border: 0 !important;
    box-shadow: none !important;
  }
}
</style>
