<template>
  <div class="select-tree">
    <div class="left">
      <el-form-item>
        <el-input
          v-model="queryStr"
          :style="{ width: '300px', height: '30px' }"
          placeholder="请输入相机名称/设备ID"
          :prefix-icon="Search"
          @change="getCameraData({ queryString: queryStr })"
          clearable
      /></el-form-item>
      <el-tree
        ref="treeRef"
        :data="cameraTreeTemp"
        show-checkbox
        node-key="code"
        :props="defaultProps"
        :render-after-expand="false"
        :filter-node-method="filterNode"
        :default-checked-keys="defaultSelectedByCode"
        accordion
        @node-click="handleNodeClick"
        @check-change="handleCheckChange"
      />
    </div>
    <div class="right" style="margin-left: 16px">
      <div class="head" style="margin-bottom: 22px">
        <span style="font-weight: 400; font-size: 16px; color: rgba(0, 0, 0, 0.88); line-height: 22px"
          >已选择({{ selected }})</span
        >
      </div>
      <div class="selected">
        <el-tag v-for="(person, index) in selectedPeople" :key="index" closable @close="handleTagClose(person.code)">
          {{ person.name }}
        </el-tag>
      </div>
      <div class="footer">
        <el-button @click="handleCancle"> 取消 </el-button>
        <el-button type="primary" @click="handleSubmit">提交</el-button>
      </div>
    </div>
  </div>
</template>

<script lang="ts" setup>
  import { onMounted, ref } from 'vue';
  import { Search } from '@element-plus/icons-vue';
  import { ElTree } from 'element-plus';
  import { ElMessage } from 'element-plus';
  import { getPushRange, updatePushRange } from '@/api/message/question-notifications';
  import { treeSelected } from '../type';
  import { CameraTree, getCameraTree } from '@/api/camera/camera-preview';

  const props = defineProps<{
    selectedUser: treeSelected[];
    refreshCamera: (arr: treeSelected[]) => unknown;
  }>();

  //相机树信息
  const cameraTreeTemp = ref<CameraTree[]>([]); // 保存修改name之后的树

  // 把树节点中所有 nodeType = camera 的 name 替换成 name + code
  function getCameraNameCode(data) {
    const cameraNameCode = data;
    for (let i = 0; i < data.length; i++) {
      const node = cameraNameCode[i];
      if (node.nodeType === 'camera') {
        node.name = node.name + ` [${node.code}] `;
      }
      if (node.children && node.children.length > 0) {
        getCameraNameCode(node.children);
      }
    }
    return cameraNameCode;
  }

  const getCameraData = async (tempQuery) => {
    await getCameraTree(tempQuery).then((res) => {
      cameraTreeTemp.value = getCameraNameCode(res);
    });
  };

  const queryStr = ref<string>('');
  const defaultProps = { label: 'name' };

  const filterNode = (query, nodeData, node) => {
    if (!query) return true;
    nodeData.filter = nodeData.name!.includes(query);
    if (!nodeData.filter && node.level > 1) {
      nodeData.filter = node.parent.data.filter;
    }
    return nodeData.filter!;
  };
  const treeRef = ref<InstanceType<typeof ElTree>>();
  const total = ref<number>(0);
  const selected = ref<number>(0);
  const defaultSelectedByCode = ref<(string | number)[]>([]);
  const selectedPeople = ref<treeSelected[]>([]);
  const handleTagClose = (code) => {
    const index = selectedPeople.value.findIndex((item) => item.code === code);
    if (index !== -1) {
      selectedPeople.value.splice(index, 1);
      selected.value = selectedPeople.value.length;
      treeRef.value!.setChecked(code, false, true);
    }
  };
  const emit = defineEmits(['cancel', 'submit']);
  const handleCancle = () => {
    emit('cancel');
  };
  const handleSubmit = () => {
    const arr = selectedPeople.value.map((selectedPeople) => selectedPeople.id);
    updatePushRange({ cameraIdList: arr })
      .then(() => {
        ElMessage({
          message: '修改成功',
          type: 'success',
          plain: true,
        });
        props.refreshCamera(selectedPeople.value);
      })
      .catch((error) => {
        console.error(error);
        handleCancle();
      });
  };
  const handleCheckChange = (node, checked) => {
    if (!node.children) {
      if (checked) {
        const exists = selectedPeople.value.some((item) => item.code === node.code);
        if (!exists) {
          selectedPeople.value.push({
            id: node.id,
            code: node.code,
            name: node.name,
          });
        }
      } else {
        const index = selectedPeople.value.findIndex((item) => item.code === node.code);
        if (index !== -1) {
          selectedPeople.value.splice(index, 1);
        }
      }
      selected.value = selectedPeople.value.length;
    }
  };
  const handleNodeClick = (node, checked) => {
    if (!node.children) {
      treeRef.value!.setChecked(node.code, !checked.checked, true);
    }
  };

  onMounted(() => {
    getPushRange().then((res) => {
      selectedPeople.value = res;
      selected.value = selectedPeople.value.length;
      defaultSelectedByCode.value = selectedPeople.value.map((item) => item.code);
    });
    getCameraData({});
  });
</script>

<style lang="scss" scoped>
  .select-tree {
    display: flex;
    width: 100%;
    height: 100%;
    .left {
      display: flex;
      flex-direction: column;
      width: 50%;
      height: 100%;
      border-right: 1px solid rgba(0, 0, 0, 0.06);
      .el-tree {
        width: 100%;
        margin-top: 20px;
        font-weight: 500;
        font-size: 14px;
        color: #303133;
        line-height: 22px;
        overflow-y: auto;
        max-height: calc(100% - 80px);
      }
    }
    .right {
      display: flex;
      flex-direction: column;
      flex: 1;
      height: 100%;
      position: relative;
      .head {
        display: flex;
        align-items: center;
        font-weight: 400;
        font-size: 16px;
        color: rgba(0, 0, 0, 0.88);
        line-height: 22px;
      }
      .selected {
        display: flex;
        flex-wrap: wrap;
        gap: 8px;
        overflow-y: auto;
        max-height: calc(100% - 120px);
      }
      .footer {
        display: flex;
        gap: 6px;
        position: absolute;
        right: 24px;
        bottom: 20px;
      }
    }
  }
</style>
