<template>
  <div class="main-slide">
    <div class="slide-title">预警对象</div>
    <div class="slide-search">
      <el-input v-model="search" placeholder="请输入关键字" clearable @input="Search" @clear="Search">
        <template #prefix>
          <bg-icon style="font-size: 12px; color: #404a62" icon="#bg-ic-search"></bg-icon>
        </template>
      </el-input>
      <el-button type="primary" size="default" @click="Add">
        <bg-icon style="font-size: 12px; color: #fff" icon="#bg-ic-add"></bg-icon>
      </el-button>
    </div>
    <div class="slide-tree bg-scroll">
      <el-tree
        ref="treeRef"
        default-expand-all
        :data="slideTree"
        :current-node-key="selectId"
        node-key="class_id"
        empty-text="暂无数据"
        :props="treeProps"
        :highlight-current="true"
        :expand-on-click-node="false"
        :filter-node-method="filterNode"
        @node-click="treeNodeChoose">
        <template #default="{ node, data }">
          <span class="custom-tree-node">
            <span>{{ node.label }}</span>
            <el-popover popper-class="tree-operation" placement="right-start" :width="120" trigger="click">
              <template #reference>
                <span class="operation" @click.stop="">
                  <bg-icon style="font-size: 12px; color: #404a62" icon="#bg-ic-s-more"></bg-icon>
                </span>
              </template>
              <template #default>
                <ul class="operation-lists">
                  <li v-for="(value, key) in operations" :key="key" @click.stop="Operation(key, node, data)">
                    <el-button link :disabled="value.disabled(node, data)">{{ value.label(node) }}</el-button>
                  </li>
                </ul>
              </template>
            </el-popover>
          </span>
        </template>
      </el-tree>
    </div>
  </div>
  <el-dialog :close-on-click-modal="false" v-model="addWarnType" width="558px" :before-close="Cancel">
    <template #header>
      <GapTitle :title="isEditWarnType ? '编辑预警分类' : '新增预警分类'"></GapTitle>
    </template>
    <div style="padding-top: 20px">
      <el-form :model="state.form" ref="add_warn_type_form" :rules="state.rules" label-width="80px">
        <el-form-item label="预警分类" prop="name">
          <el-input v-model="state.form.name" placeholder="请输入预警分类" maxlength="20" show-word-limit></el-input>
        </el-form-item>
      </el-form>
    </div>
    <template #footer>
      <el-button size="default" @click="Cancel">取消</el-button>
      <el-button type="primary" size="default" @click="Save"> 保存 </el-button>
    </template>
  </el-dialog>
  <el-dialog :close-on-click-modal="false" v-model="addWarnTarget" width="558px" :before-close="Cancel">
    <template #header>
      <GapTitle :title="isEditWarnType ? '编辑预警对象' : '新增预警对象'"></GapTitle>
    </template>
    <div style="padding-top: 20px">
      <el-form :model="state.form_target" ref="add_warn_target_form" :rules="state.target_rules" label-width="80px">
        <el-form-item label="预警分类" prop="type">
          <el-select style="flex: 1" v-model="state.form_target.type" placeholder="请选择预警分类" filterable>
            <el-option v-for="item in slideTree" :key="item.class_id" :label="item.class_name" :value="item.class_id">
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="预警对象" prop="target">
          <el-input
            v-model="state.form_target.target"
            placeholder="请输入预警对象"
            maxlength="20"
            show-word-limit></el-input>
        </el-form-item>
      </el-form>
    </div>
    <template #footer>
      <el-button size="default" @click="CancelAddWarnTarget">取消</el-button>
      <el-button type="primary" size="default" @click="SaveAddWarnTarget"> 保存 </el-button>
    </template>
  </el-dialog>
  <el-dialog v-model="delWarnType" width="400px" :before-close="Cancel">
    <template #header>
      <GapTitle title="删除预警分类"></GapTitle>
    </template>
    <div style="padding: 20px 0">是否确定删除 {{ activeTree.own.label }} 这个预警分类</div>
    <template #footer>
      <el-button size="default" @click="CancelDel">取消</el-button>
      <el-button type="primary" size="default" @click="ConfirmDel"> 确定 </el-button>
    </template>
  </el-dialog>
</template>

<script setup>
import { nextTick, onBeforeMount, reactive, ref } from "vue";
import GapTitle from "@/components/gap-title.vue";
import axios from "@/request/http.js";
import { ElMessage } from "element-plus";
const props = defineProps({
  modelValue: {
    type: Object,
    default: () => ({}),
  },
});
const search = ref("");
let slideTree = ref([]);
const treeProps = {
  // 组织树获取数据规则
  children: "children",
  label: "class_name",
};
const treeRef = ref(null);
const selectId = ref("");
const getSlideTree = () => {
  axios.get("/v1/api/alert_class/tree").then(async (res) => {
    if (res.data.code == 200) {
      slideTree.value = res.data.data;
      try {
        slideTree.value.forEach((e) => {
          if (e.children && e.children.length > 0) {
            throw e.children[0];
          }
        });
      } catch (item) {
        await nextTick();
        treeRef.value.setCurrentKey(item.class_id);
        const node = treeRef.value.getNode(item);
        if (node) {
          treeNodeChoose(item, node);
        }
      }
    } else {
      ElMessage.error(res.data.msg);
    }
  });
};
const filterNode = (value, data) => {
  if (!value) return data;
  return data.label.includes(value);
};
const Search = async () => {
  await nextTick();
  treeRef.value.filter(search.value);
};
const Add = () => {
  addWarnType.value = true;
};
const emits = defineEmits(["undate:modelValue"]);
const treeNodeChoose = (data, node) => {
  if (node.level == 1) return;
  emits("update:modelValue", { data, node });
};
const getBrotherNodes = (node) => {
  let arr = [];
  if (node.level == 1) {
    arr = slideTree.value;
  } else {
    arr = node.parent.data.children;
  }
  return arr;
};
const operations = {
  1: {
    label: (node) => {
      return node.level == 1 ? "编辑预警分类" : "编辑预警对象";
    },
    disabled: () => {
      return false;
    },
  },
  2: {
    label: () => "新增预警对象",
    disabled: () => {
      return false;
    },
  },
  3: {
    label: () => "删除",
    disabled: () => {
      return false;
    },
  },
  4: {
    label: () => "上移",
    disabled: (node, data) => {
      let arr = getBrotherNodes(node);
      let id = data.class_id;
      let i = arr.findIndex((e) => e.class_id == id);
      return 0 == i;
    },
  },
  5: {
    label: () => "下移",
    disabled: (node, data) => {
      let arr = getBrotherNodes(node);
      let id = data.class_id;
      let i = arr.findIndex((e) => e.class_id == id);
      return arr.length - 1 == i;
    },
  },
};
const addWarnType = ref(false);
const addWarnTarget = ref(false);
const delWarnType = ref(false);
const isEditWarnType = ref(false);
const activeTree = ref({});
const Operation = (key, node, data) => {
  activeTree.value = {
    node,
    own: data,
    data: node.level == 1 ? data : node.parent.data,
  };
  let operation_handled_fn = {
    1: async () => {
      if (node.level == 1) {
        addWarnType.value = true;
        await nextTick();
        state.form.name = data.class_name;
      } else {
        addWarnTarget.value = true;
        await nextTick();
        state.form_target.type = activeTree.value.data.class_id;
        state.form_target.target = data.class_name;
      }
      isEditWarnType.value = true;
    },
    2: () => {
      addWarnTarget.value = true;
      isEditWarnType.value = false;
      state.form_target.type = activeTree.value.data.class_id;
    },
    3: () => {
      delWarnType.value = true;
    },
    4: () => {
      move(data.class_id, "up");
    },
    5: () => {
      move(data.class_id, "down");
    },
  };
  operation_handled_fn[key]();
};
const move = (class_id, type) => {
  const params = {
    class_id,
  };
  axios.put(`/v1/api/alert_class/move/${type}`, params).then((res) => {
    if (res.data.code == 200) {
      let text = {
        up: "上移",
        down: "下移",
      };
      ElMessage.success(`${text[type]}成功`);
      getSlideTree();
    } else {
      ElMessage.error(res.data.msg);
    }
  });
};
const add_warn_type_form = ref(null);
const add_warn_target_form = ref(null);
const state = reactive({
  form: {
    name: "",
  },
  form_target: {
    type: "",
    target: "",
  },
  rules: {
    name: [{ required: true, message: "请输入预警分类", trigger: "blur" }],
  },
  target_rules: {
    type: [{ required: true, message: "请选择预警分类", trigger: "change" }],
    target: [{ required: true, message: "请输入预警对象", trigger: "blur" }],
  },
});
const Cancel = async () => {
  add_warn_type_form.value.resetFields();
  await nextTick();
  addWarnType.value = false;
};
const Save = () => {
  add_warn_type_form.value.validate((valid) => {
    if (valid) {
      const params = {
        class_name: state.form.name,
        parent_id: 0,
      };
      if (isEditWarnType.value) {
        params.class_id = activeTree.value.own.class_id;
      }
      let method = isEditWarnType.value ? "put" : "post";
      axios[method]("/v1/api/alert_class", params).then((res) => {
        if (res.data.code == 200) {
          ElMessage.success("预警分类新建成功");
          Cancel();
          getSlideTree();
        } else {
          ElMessage.error(res.data.msg);
        }
      });
    } else {
      return false;
    }
  });
};
const CancelAddWarnTarget = async () => {
  add_warn_target_form.value.resetFields();
  await nextTick();
  addWarnTarget.value = false;
};
const SaveAddWarnTarget = () => {
  add_warn_target_form.value.validate((valid) => {
    if (valid) {
      const params = {
        class_name: state.form_target.target,
        parent_id: state.form_target.type,
      };
      if (isEditWarnType.value) {
        params.class_id = activeTree.value.own.class_id;
      }
      let method = isEditWarnType.value ? "put" : "post";
      axios[method]("/v1/api/alert_class", params).then((res) => {
        if (res.data.code == 200) {
          ElMessage.success("预警对象新建成功");
          CancelAddWarnTarget();
          getSlideTree();
        } else {
          ElMessage.error(res.data.msg);
        }
      });
    } else {
      return false;
    }
  });
};
const CancelDel = () => {
  delWarnType.value = false;
};
const ConfirmDel = () => {
  axios
    .delete("/v1/api/alert_class", {
      data: {
        class_id: activeTree.value.own.class_id,
      },
    })
    .then((res) => {
      if (res.data.code == 200) {
        ElMessage.success("删除成功");
        CancelDel();
        getSlideTree();
      } else {
        ElMessage.error(res.data.msg);
      }
    });
};
onBeforeMount(() => {
  getSlideTree();
});
</script>

<style lang="scss" scoped>
.main-slide {
  width: 320px;
  height: 100%;
  background-color: #fff;
  box-shadow: 0 1px 4px 0 rgba(0, 7, 101, 0.15);
  border-radius: 6px;
  margin-right: 16px;
  overflow: hidden;
  .slide-title {
    height: 40px;
    background-color: #f7f7f9;
    display: flex;
    align-items: center;
    padding-left: 16px;
  }
  .slide-search {
    padding: 16px;
    display: flex;
    align-items: center;
    :deep(.el-button) {
      margin-left: 8px;
    }
  }
  .slide-tree {
    height: calc(100% - 108px);
    :deep(.el-tree-node__content) {
      height: 36px;
    }
    .custom-tree-node {
      flex: 1;
      display: flex;
      align-items: center;
      justify-content: space-between;
      font-size: 14px;
      overflow: hidden;
      &:hover {
        .operation {
          visibility: visible;
        }
      }
      .operation {
        display: flex;
        visibility: hidden;
        width: 36px;
        height: 36px;
        align-items: center;
        justify-content: center;
        box-shadow: -4px 0 4px 0px rgba(0, 7, 101, 0.15);
      }
    }
  }
}
.add-warn-type-form {
  padding-top: 20px;
}
</style>
<style lang="scss">
.tree-operation {
  padding: 4px 0 !important;
  min-width: 0 !important;
  .operation-lists {
    li {
      line-height: 34px;
      cursor: pointer;
      transition: all 300ms;
      .el-button {
        width: 100%;
        height: 34px;
        justify-content: flex-start;
        padding: 0 16px;
      }
      &:hover {
        background-color: #f2f3f7;
        .el-button {
          &:not(.is-disabled) {
            color: #3759be;
          }
        }
      }
    }
  }
}
</style>
