<template>
  <div class="cameraTreeWrapper">
    <div class="cameraTreeTitle">
      <span>场景树</span>
      <span class="detail-num" v-if="totalNum">
        (总相机:{{ totalNum }} 未联网:{{ noNetworkingNum }} 未进入平台:{{ noIntegrationNum }})
      </span>
    </div>
    <div class="cameraTreeInputWrapper">
      <el-input
        class="filterTextInput"
        v-model="queryForm.queryString"
        placeholder="请输入相机名称/设备ID/算法名称"
        @keyup.enter.native="handleSearchCamera"
        clearable
        @clear="handleSearchCamera"
      >
        <template #suffix>
          <el-icon class="el-input__icon" @click="handleSearchCamera"><search /></el-icon>
        </template>
      </el-input>
      <div class="cameraTreeCheckboxWrapper">
        <el-checkbox
          v-model="queryForm.isEnableAlgo"
          label="添加算法"
          @change="handleSearchCamera"
        />
        <el-checkbox
          v-model="queryForm.isEnableRender"
          label="开启渲染"
          @change="handleSearchCamera"
        />
        <el-button v-if="isSearch" text type="primary" @click="handleCollapseTree">收起</el-button>
        <el-button v-if="!isSearch" text type="primary" @click="handleExpandTree">展开</el-button>
      </div>
      <el-scrollbar class="tree-scroll">
        <el-tree
          v-if="treeCollapse"
          ref="treeRef"
          node-key="code"
          :data="cameraTreeTemp"
          :props="defaultProps"
          :default-expand-all="isSearch"
          :default-expanded-keys="workSpaceKeys"
          @node-click="handleNodeClick"
        >
          <template #default="{ node, data }">
            <span
              class="flexCenter"
              :class="{ integrationState: data.integrationState === 1, nodeSelect: isSelect(data) }"
            >
              <span
                v-if="data.nodeType === CameraTreeNodeType.camera"
                class="iconWrapper flexCenter"
              >
                <span
                  class="cameraCommon"
                  :class="{
                    cameraSelect: isSelect(data),
                  }"
                ></span>

                <el-icon
                  class="cameraIcon"
                  :class="{
                    iconSelect: isSelect(data),
                  }"
                >
                  <VideoCamera />
                </el-icon>
                <el-icon class="invalidCamera" v-if="isInvalid(data)"><WarningFilled /></el-icon>
              </span>
              {{ node.label }}
            </span>
          </template>
        </el-tree>
      </el-scrollbar>
    </div>
  </div>
</template>
<script lang="ts" setup>
  import { nextTick, onMounted, onUnmounted, ref } from 'vue';
  import { ElMessage, ElTree } from 'element-plus';
  import { Search, VideoCamera, WarningFilled } from '@element-plus/icons-vue';
  import { useRouteQuery } from '@vueuse/router';
  import useCameraStatus from '../../store/useCameraStatus';
  import {
    CameraTree,
    CameraTreeNodeType,
    CameraQueryForm,
    getCameraTree,
  } from '@/api/camera/camera-preview';

  const cameraId = useRouteQuery('cameraId');
  const cameraStatus = useCameraStatus();
  const { noNetworkingNum, openInterval, closeInterval } = cameraStatus;

  const queryForm = ref<CameraQueryForm>({
    isEnableAlgo: false,
    isEnableRender: false,
    queryString: '',
  });
  const totalNum = ref(0); // 总相机数
  const noIntegrationNum = ref(0); // 未进入平台相机数
  const cameraTree = ref<CameraTree[]>([]); // 保存从接口获取的所有树节点信息
  const cameraTreeTemp = ref<CameraTree[]>([]); // 保存修改name之后的树
  const codeShowList = ref<string[]>([]); // 保存当前所有相机code列表
  const isSearch = ref(true); // 默认展开全部
  const treeCollapse = ref(true);
  const workSpaceKeys = ref<string[]>([]); // 当前要收起的工位code

  const treeRef = ref<InstanceType<typeof ElTree>>();
  const defaultProps = {
    children: 'children',
    label: 'name',
  };

  const handleNodeClick = (e: CameraTree) => {
    if (e.integrationState === 1) {
      ElMessage.error('该相机未进入平台');
    } else {
      if (e.nodeType === CameraTreeNodeType.camera) {
        cameraId.value = String(e.id);
      }
    }
  };

  const isSelect = (data) =>
    data.nodeType === CameraTreeNodeType.camera && data.id === Number(cameraId.value);

  const isInvalid = (data) => {
    return data.networkingState !== 0;
  };

  // 把树节点中所有 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;
  }

  // 获取当前树结构下总相机code列表
  function getCameraList(data) {
    let cameraList = [] as string[];
    for (let i = 0; i < data.length; i++) {
      const node = data[i];
      if (node.nodeType === 'camera') {
        cameraList.push(node.code);
      }
      if (node.children && node.children.length > 0) {
        const childCameraList = getCameraList(node.children);
        cameraList.push(...childCameraList);
      }
    }
    return cameraList;
  }

  // 获取当前树结构下nodeType=workshop的节点code集合
  function getWorkShopCodeList(data) {
    let tempCodeList = [] as string[];
    for (let i = 0; i < data.length; i++) {
      const node = data[i];
      if (node.nodeType === 'workshop') tempCodeList.push(node.code);
      if (node.children && node.children.length > 0) {
        const childList = getWorkShopCodeList(node.children);
        tempCodeList.push(...childList);
      }
    }
    return tempCodeList;
  }

  // 更新/获取未进入平台相机数量
  function updateNetworkingState(data, targetData) {
    let integrationCount = 0;
    for (let i = 0; i < data.length; i++) {
      const node = data[i];
      const matchedNode = targetData.find((item) => item.cameraCode === node.code);
      if (matchedNode) {
        node.networkingState = matchedNode.status;
        node.integrationState = matchedNode.integrationState;
      }
      if (node.integrationState === 1) {
        integrationCount++;
      }
      if (node.children && node.children.length > 0) {
        const childIntegrationCount = updateNetworkingState(node.children, targetData);
        integrationCount += childIntegrationCount;
      }
    }
    noIntegrationNum.value = integrationCount;
    return integrationCount;
  }

  // 输入框回车搜索 + checkbox 搜索
  const handleSearchCamera = async () => {
    treeCollapse.value = false;
    workSpaceKeys.value = [];
    await getCameraData(queryForm.value);
    nextTick(() => {
      isSearch.value = true;
      treeCollapse.value = true;
    });
  };

  // 收起相机，收起到工位
  const handleCollapseTree = () => {
    treeCollapse.value = false;
    workSpaceKeys.value = getWorkShopCodeList(cameraTreeTemp.value);
    nextTick(() => {
      isSearch.value = false;
      treeCollapse.value = true;
    });
  };

  // 展开相机
  const handleExpandTree = () => {
    treeCollapse.value = false;
    workSpaceKeys.value = [];
    nextTick(() => {
      isSearch.value = true;
      treeCollapse.value = true;
    });
  };

  const getCameraData = async (tempQuery) => {
    await getCameraTree(tempQuery).then((res) => {
      cameraTree.value = res;
      cameraTreeTemp.value = getCameraNameCode(res);
      codeShowList.value = getCameraList(res);
      totalNum.value = codeShowList.value.length;
      openInterval(codeShowList.value, (targetData) => {
        updateNetworkingState(cameraTree.value, targetData);
      });
    });
  };

  onMounted(() => {
    getCameraData(queryForm.value);
  });

  onUnmounted(() => {
    closeInterval();
  });
</script>
<style scoped>
  .cameraCommon {
    width: 6px;
    height: 6px;
    display: inline-block;
    align-items: center;
    margin-right: 6px;
  }

  .tree-scroll {
    height: calc(100vh - 64px - 170px);
  }

  .cameraSelect {
    width: 6px;
    height: 6px;
    background: #0052d9;
    display: inline-block;
    border-radius: 6px;
    margin-right: 6px;
  }
  .cameraTreeTitle {
    background: #f0f2f5;
    padding: 12px;
    display: flex;
  }

  .detail-num {
    font-size: 10px;
    margin-top: 4px;
    margin-left: 6px;
  }

  .cameraTreeInputWrapper {
    padding: 8px;
  }
  .filterTextInput {
    margin: 8px 0;
  }
  .flexCenter {
    display: flex;
    align-items: center;
  }

  .integrationState {
    cursor: not-allowed;
    color: #ccc;
  }
  .cameraIcon {
    margin-right: 5px;
    font-size: 18px;
  }
  .iconSelect {
    color: #0052d9;
  }

  .iconWrapper {
    position: relative;
  }

  .invalidCamera {
    color: #dd5869;
    font-size: 12px;
    position: absolute;
    right: 2px;
    top: -4px;
  }

  .nodeSelect {
    color: #0052d9;
  }

  .el-input__icon {
    cursor: pointer;
  }

  .el-input__icon:hover {
    color: #0052d9;
  }

  .cameraTreeCheckboxWrapper {
    display: flex;
    justify-content: space-between;

    .el-checkbox {
      margin-right: 0;
    }
  }
</style>
