<template>
  <div class="security-monitor panel">
    <!-- Monitor Header -->
    <div class="monitor-header">
      <span class="monitor-title-cn">&#x1F4F9; &#x5B9E;&#x65F6;&#x76D1;&#x63A7;</span>
      <span class="monitor-title-en">CCTV Live Feed</span>
      <div class="monitor-button" v-if="effective">
        <p :class="checkButton == 1 ? 'checkButton':'noCheckButton'" @click="buttonClick(1)">默认</p>
        <p :class="checkButton == 2 ? 'checkButton':'noCheckButton'" @click="buttonClick(2)">全部</p>
      </div>
      <div class="monitor-status">
        <div class="status-dot green"></div>
        <span class="monitor-status-text">&#x4FE1;&#x53F7;&#x6B63;&#x5E38;</span>
      </div>
    </div>
    <div v-if="checkButton == 1" class="monitor-play-box">
      <videoForMod
          v-for="(item,index) in modList" :key="index"
          :deviceNo="item.deviceNo"
      ></videoForMod>
    </div>
    <!-- Monitor Inner: 2-column grid -->
    <div class="monitor-inner" v-if="checkButton == 2">
      <!-- Left Column: Search + Filter + Tree -->
      <div class="monitor-left">
        <div class="search-box">
          <span class="search-icon">&#x1F50D;</span>
          <el-input class="video-select"
            @keyup.enter.native="handleEnter"
            @clear="handleEnter"
            clearable
            v-model="queryParams.searchValue"
            type="text" placeholder="搜索楼栋/楼层...." >
          </el-input>
        </div>

        <el-select class="filter-select"
          @change="handleEnter"
          @clear="handleEnter"
          clearable
          v-model="queryParams.deptId"
          placeholder="请选择二级单位">
          <el-option
            v-for="item in options"
            :key="item.deptId"
            :label="item.deptName"
            :value="item.deptId">
          </el-option>
        </el-select>

        <div class="tree-wrap">
          <el-tree
            class="dark-tree"
            @node-click="nodeClickButton"
            :current-node-key="treeId"
            :check-on-click-node="false"
            check-strictly
            highlight-current
            :default-expanded-keys="defaultKey"
            node-key="treeId"
            :data="deptOptions"
            :props="defaultProps"
            ref="tree"
            :load="loadNode"
            accordion
            lazy>
            <template #default="{ node, data }">
              <span class="tree-node-label">
                <span>{{ data.deptName }}</span>
              </span>
            </template>
          </el-tree>
        </div>
      </div>

      <!-- Right Column: Breadcrumb + Pager + Camera Grid -->
      <div class="monitor-right">
        <div class="camera-grid-header">
          <div class="camera-breadcrumb">
            <span>{{breadcrumb}}</span>
          </div>
          <div class="camera-pager">
            <button class="pager-btn" @click="prevPage">&lsaquo;</button>
            <span class="pager-info">{{ videoQueryParams.page }} / {{ totalPages }} &#x9875;</span>
            <button class="pager-btn" @click="nextPage">&rsaquo;</button>
          </div>
        </div>

        <div class="camera-grid">
          <H5PlayerVideo v-for="(item,index) in videoList" :key="index" :videoProps="item"></H5PlayerVideo>
          <!-- <div
            v-for="(cam, idx) in cameras"
            :key="'cam-' + idx"
            class="camera-cell"
            :class="{ 'ai-cam': idx === 0 }"
          >
            <div v-if="idx === 0" class="camera-ai-badge">&#x1F916; AI&#x68C0;&#x6D4B;</div>
            <div class="camera-rec">REC</div>
            <div class="camera-placeholder-text">CCTV</div>
            <div v-if="idx === 0" class="ai-detection-box" style="left:28%;top:18%;width:22%;height:38%">
              <div class="ai-detection-label">&#x5371;&#x9669;&#x884C;&#x4E3A;: &#x672A;&#x4F69;&#x6234;&#x9632;&#x62A4;</div>
            </div>
            <div class="camera-label">{{ cam }}</div>
          </div> -->
        </div>
      </div>
    </div>
    <fullH5PlayerVideo v-if="fullVideoType" :fullVideoProps="fullVideoProps"></fullH5PlayerVideo>
  </div>
</template>

<script>
import { getCameraList,getMonitorTree,getRooms,getDeptDropList,
  getCameraStream,laboratoryLabScreenScreenConfigGet } from '@/api/screen'

import H5PlayerVideo from '@/components/H5PlayerVideo/H5PlayerVideo.vue'
import videoForMod from '@/components/videoForMod/videoForMod.vue'
import fullH5PlayerVideo from '@/components/fullH5PlayerVideo/fullH5PlayerVideo.vue'
const TreeNode = {
  name: 'TreeNode',
  props: {
    node: { type: Object, required: true },
    depth: { type: Number, default: 0 },
    selectedLabel: { type: String, default: '' }
  },
  data() {
    return {
      expanded: this.depth === 0,
    }
  },
  computed: {
    isLeaf() {
      return !this.node.children || this.node.children.length === 0
    },
    icon() {
      const icons = ['\u{1F3E2}', '\u{1F3D7}\uFE0F', '\u{1F4D0}', '\u{1F52C}']
      return icons[Math.min(this.depth, 3)]
    },
    isSelected() {
      return this.node.label === this.selectedLabel
    },
    totalPages() {
      return Math.ceil(this.videoTotal / 9) || 1
    }
  },
  methods: {
    toggle() {
      if (!this.isLeaf) {
        this.expanded = !this.expanded
      }
      this.$emit('select', this.node.label)
    },
    onChildSelect(label) {
      this.$emit('select', label)
    }
  },
  template: `
    <div class="tree-node">
      <div
        class="tree-node-label"
        :class="{ selected: isSelected }"
        @click="toggle"
      >
        <span class="arrow" :class="{ open: expanded }">
          <template v-if="!isLeaf">&#x25B6;</template>
          <template v-else>&nbsp;&nbsp;</template>
        </span>
        <span>{{ icon }}</span>
        <span>{{ node.label }}</span>
      </div>
      <div v-if="!isLeaf" class="tree-children" :class="{ open: expanded }">
        <tree-node
          v-for="(child, i) in node.children"
          :key="i"
          :node="child"
          :depth="depth + 1"
          :selected-label="selectedLabel"
          @select="onChildSelect"
        />
      </div>
    </div>
  `
}

export default {
  name: 'SecurityMonitor',
  components: {
    TreeNode,
    H5PlayerVideo,
    fullH5PlayerVideo,
    videoForMod,
  },
  data() {
    return {
      searchText: '',
      selectedUnit: '',
      selectedTreeLabel: '',
      currentPage: 1,
      totalPages: 3,
      cameras: [],
      treeData: {
        label: '\u5B89\u79D1\u9662\u4E3B\u56ED\u533A',
        children: [
          {
            label: '\u7EFC\u5408\u5B9E\u9A8C\u697CA',
            children: [
              { label: '1\u5C42', children: [{ label: 'A101 \u5316\u5B66\u5B9E\u9A8C\u5BA4' }, { label: 'A102 \u5206\u6790\u5BA4' }] },
              { label: '2\u5C42', children: [{ label: 'A201 \u751F\u7269\u5B9E\u9A8C\u5BA4' }] },
              { label: '3\u5C42', children: [{ label: 'A301 \u6709\u673A\u5408\u6210\u5BA4' }, { label: 'A302 \u6838\u78C1\u5171\u632F\u5BA4' }, { label: 'A303 \u8D28\u8C31\u5BA4' }] },
              { label: '4\u5C42', children: [{ label: 'A401 X\u5C04\u7EBF\u5BA4' }] }
            ]
          },
          {
            label: '\u7269\u7406\u5B9E\u9A8C\u697CB',
            children: [
              { label: '1\u5C42', children: [{ label: 'B101 \u5149\u5B66\u5B9E\u9A8C\u5BA4' }] },
              { label: '2\u5C42', children: [{ label: 'B201 \u4F4E\u6E29\u5B9E\u9A8C\u5BA4' }] }
            ]
          },
          {
            label: '\u5DE5\u7A0B\u6280\u672F\u697CC',
            children: [
              { label: '1\u5C42', children: [{ label: 'C101 \u673A\u68B0\u52A0\u5DE5\u5BA4' }] },
              { label: '2\u5C42', children: [{ label: 'C201 \u6750\u6599\u6D4B\u8BD5\u5BA4' }] }
            ]
          }
        ]
      },
      //左侧部分
      defaultProps: {
        children: "childTreeList",
        label: "deptName",
        isLeaf:"leaf",
      },
      queryParams:{
        searchValue: "",
        deptId: '',
      },
      deptOptions: [],
      options:[],
      treeId:null,
      defaultKey:null,
      // 地址部分
      breadcrumb:'',
      // 视频部分
      videoQueryParams:{
        page:1,
        pageSize:4,
        streamType:1,
        source:0,
      },
      videoType:false,
      videoList:[],
      videoTotal:0,
      //全屏视频参数
      fullVideoProps:{},
      fullVideoType:false,
      //切换
      checkButton:2,
      effective:false,
      modList:[],
      //定时器
      pollTimer: null
    }
  },
  created() {
    // this.fetchCameras()
  },
  mounted() {
    this.getMonitorTree();
    this.getDeptDropList();
    this.laboratoryLabScreenScreenConfigGet();
    this.pollTimer = setInterval(this.laboratoryLabScreenScreenConfigGet, 5 * 60 * 1000)
  },
  beforeDestroy() {
    if (this.pollTimer) clearInterval(this.pollTimer)
  },
  methods: {
    buttonClick(val){
      this.$set(this,'checkButton',val);
      if(val == 2){
        this.handleEnter();
      }
    },
    handleEnter(){
      this.getMonitorTree();
    },
    //二级学院下拉列表
    async getDeptDropList() {
      let self = this;
      try {
        const res = await getDeptDropList({})
        this.$set(this,'options',res.data[0].child);
      } catch (e) {
        console.error('BuildingNav:', e)
      }
    },
    async getMonitorTree() {
      let self = this;
      let obj = JSON.parse(JSON.stringify(this.queryParams))
      try {
        const res = await getMonitorTree(obj)
        let list = this.forTreeId(res.data);
        this.$set(self,'deptOptions',list)
        this.$nextTick(()=>{
          let checkData = []
          if(this.queryParams.searchValue){
            checkData = list[0].childTreeList[0].childTreeList[0];
            //展开列表
            self.$set(self,'defaultKey',[list[0].treeId,list[0].childTreeList[0].treeId]);
            setTimeout(function(){
              self.$set(self,'defaultKey',[list[0].treeId,list[0].childTreeList[0].childTreeList[0].treeId]);
            },200)
          }else{
            checkData = list[0].childTreeList[0];
            //展开列表
            self.$set(self,'defaultKey',[list[0].treeId,list[0].childTreeList[0].treeId]);
          }
          setTimeout(function(){
            //选中列表
            self.$refs.tree.setCurrentKey(checkData.treeId);
            self.$set(self,'treeId',checkData.treeId);
            //当前位置展示
            self.checkAddress(checkData.treeId);
            //父级视屏数据
            self.getSubId(checkData);
          },600);
        })
      } catch (e) {
        console.error('BuildingNav:', e)
      }
    },
    nodeClickButton(e,data){
      let self = this;
      this.$nextTick(() => {
        if (!e.level||e.level == 2||e.level == 3) {
          if(this.treeId != e.treeId){
            this.treeId = e.treeId;
            //等待后续逻辑-面板展示-实验室信息-视屏信息
            //当前位置展示
            this.checkAddress(e.treeId);
            //查询楼栋/楼层下所有实验室ID
            this.getSubId(e);
          }
        }
        this.$refs.tree.setCurrentKey(this.treeId);
      });
    },
    forTreeId(list){
      let self = this;
      list.forEach((item,index)=>{
        item.treeId = item.id;
        item.deptName = item.name;
        item.level = item.type;
        item.childTreeList = item.buildFloorVoList;
        delete item.id
        delete item.name
        delete item.type
        delete item.buildFloorVoList
        if(item.childTreeList[0]){
          self.forTreeId(item.childTreeList);
        }
      })
      return list
    },
    //手动加载
    loadNode(node, resolve) {
      let self = this;
      if (node.data){
        if(node.data.level == 3){
          let obj = {
            deptId:this.queryParams.deptId,
            searchValue:this.queryParams.searchValue,
          }
          obj.floorId = node.data.treeId;
          getRooms(obj).then(response => {
            for(let i=0;i<response.data.length;i++){
              response.data[i].deptName = response.data[i].formatRoomName;
              response.data[i].leaf = true;
            }
            resolve(response.data[0]?response.data:[]);
          })
        }else{
          if(node.data.childTreeList){
            if(node.data.childTreeList[0]){
              if(node.data.level != 2){
                node.data.childTreeList.forEach((item)=>{
                  if(item.childTreeList){
                    if(!item.childTreeList[0]){
                      item.leaf = true;
                    }
                  }else{
                    item.leaf = true;
                  }
                })
              }
              resolve(node.data.childTreeList);
            }else{
              resolve([]);
            }
          }else{
            resolve([]);
          }
        }
      }

    },
    //实验室ID查询
    getSubId(e){
      let self = this;
      let obj = {
        deptId:this.queryParams.deptId,
        levelIds:[],
      }
      if(!e.level){
        //实验室
        // this.$parent.setVideoData([e.treeId]);
        this.getVideoData([e.treeId])
      }else if(e.level == 2){
        //楼栋
        obj.buildingId = e.treeId;
        getRooms(obj).then(response => {
          let  list = [];
          for(let i=0;i<response.data.length;i++){
            list.push(response.data[i].treeId)
          }
          // this.$parent.setVideoData(list);
          this.getVideoData(list)
        })
      }else if(e.level == 3){
        //楼层
        obj.floorId = e.treeId;
        getRooms(obj).then(response => {
          let  list = [];
          for(let i=0;i<response.data.length;i++){
            list.push(response.data[i].treeId)
          }
          // this.$parent.setVideoData(list);
          this.getVideoData(list)
        })
      }
    },
    //选中位置联查
    checkAddress(id){
      let list = this.forAddress(this.$refs.tree._data.root.childNodes,id);
      // this.$parent.setAddress(list);
      let text = '';
      for(let i=0;i<list.length;i++){
        if(i==0){
          text = text + list[i];
        }else{
          text = text + ' - ' + list[i];
        }
      }
      this.$set(this,'breadcrumb',text);
    },
    forAddress(list,id){
      let self = this;
      let nameList = [];
      let name = []
      for(let i=0;i<list.length;i++){
        if(list[i].data.treeId == id){
          return list[i].data.deptName
        }else{
          if(list[i].childNodes){
            if(list[i].childNodes[0]){
              name = self.forAddress(list[i].childNodes,id);
              if(name){
                nameList = [list[i].data.deptName].concat(name)
                return nameList
              }
            }
          }
        }
      }
    },
    //视频部分
    //刷新视屏
    getVideoData(data){
      let obj = {
        page:1,
        pageSize:9,
        passageway:'',
        protocol:window.location.href.indexOf('https') !== -1?'wss':'ws',
        streamType:1,
        source:4,
        subIds:data,
      };
      this.$set(this,'videoQueryParams',obj);
      this.$nextTick(()=>{
        this.videoInitialize()
      })
    },
    async videoInitialize() {
      let self = this;
      self.$set(self, 'videoType', false);
      self.$set(self, 'videoList', []);
      try {
        const res = await getCameraStream(this.videoQueryParams)
        let list = [];
        // res.data.total = 100;
        // res.data.records = [
        //   {streamUrl:'1', deviceNo:'1'},
        //   {streamUrl:'2', deviceNo:'2'},
        //   {streamUrl:'3', deviceNo:'3'},
        //   {streamUrl:'4', deviceNo:'4'},
        //   {streamUrl:'5', deviceNo:'5'},
        //   {streamUrl:'6', deviceNo:'6'},
        //   {streamUrl:'7', deviceNo:'7'},
        //   {streamUrl:'8', deviceNo:'8'},
        //   {streamUrl:'9', deviceNo:'9'},
        // ];
        for(let i=0;i<res.data.records.length;i++){
          list.push(
            {
              width: 1214, //(宽度:非必传-默认600)
              height: 792, //(高度:非必传-默认338)
              url: res.data.records[i].streamUrl,
              cameraIndexCode: res.data.records[i].deviceNo,
            }
          )
        }
        this.$set(this,'videoList',list)
        this.$set(this,'videoTotal',res.data.total);
        this.$nextTick(()=>{
          setTimeout(function(){
            self.$set(self, 'videoType', true);
          },1000);
        })
      } catch (e) {
        console.error('VideoGrid:', e)
      }
    },
    //指定视频
    async laboratoryLabScreenScreenConfigGet(){
      try {
        const res = await laboratoryLabScreenScreenConfigGet({ screenType: 1 })
        if (res.code === 200) {
          this.$set(this,'effective',res.data.effective);
          this.$set(this,'modList',res.data.items);
          if(res.data.effective){
            this.$set(this,'checkButton',1);
          }else{
            this.$set(this,'checkButton',2);
          }
        }
      } catch (e) {

      }
    },
    //全屏开启-关闭轮播
    stopTime(cameraIndexCode){
      this.$set(this,'fullVideoProps',{cameraIndexCode:cameraIndexCode});
      this.$set(this,'fullVideoType',true);
    },
    //全屏关闭-开启轮播
    outFullScreen(){
      let self = this;
      this.$set(this,'fullVideoType',false);
      this.$set(this,'fullVideoProps',{});
    },

    //旧

    async fetchCameras() {
      try {
        const res = await getCameraList({ page: 1, pageSize: 9 })
        if (res.code === 200) {
          const records = (res.data && res.data.records) || []
          this.cameras = records.map(r => r.deviceName || r.room || r.subjectName || '')
        }
      } catch (e) {
        // fallback to static data
        this.cameras = [
          'A301 \u6709\u673A\u5408\u6210\u5BA4',
          'A302 \u6838\u78C1\u5171\u632F\u5BA4',
          'A303 \u8D28\u8C31\u5BA4',
          'A301 \u8D70\u5ECA',
          'A302 \u8D70\u5ECA',
          'A303 \u8D70\u5ECA',
          'A\u5C42\u516C\u5171\u533A\u57DF',
          'A\u5C42\u5B89\u5168\u901A\u9053',
          'A\u5C42\u51FA\u5165\u53E3'
        ]
      }
    },
    onTreeNodeSelect(label) {
      this.selectedTreeLabel = label
    },
    prevPage() {
      if (this.videoQueryParams.page > 1) {
        this.videoQueryParams.page--
        this.videoInitialize()
      }
    },
    nextPage() {
      if (this.videoQueryParams.page < this.totalPages) {
        this.videoQueryParams.page++
        this.videoInitialize()
      }
    }
  }
}
</script>
<style lang="scss">
.el-select-dropdown{
  background-color: rgba(8, 55, 106, 0.8);
  border:1px solid rgba(8, 55, 106, 1);
  color:#A8CCE8;
  .el-select-dropdown__item{
    color:#A8CCE8;
    height:62px;
    line-height:62px;
    font-size:28px;
  }
  .el-select-dropdown__item.hover, .el-select-dropdown__item:hover{
    background-color: rgba(8, 55, 106, 0.5);
    color:#fff;
  }
  .el-scrollbar{
    height: 500px;
    .el-select-dropdown__wrap{
      max-height:500px;
    }
  }
}
</style>
<style lang="scss" scoped>
.security-monitor {
  display: flex;
  flex-direction: column;
  height: 100%;
  min-height: 0;
}

// ========== Monitor Header ==========
.monitor-header {
  padding: 20px 30px;
  border-bottom: 1px solid $border;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: 25px;
  background: linear-gradient(90deg, rgba(0, 60, 160, 0.18), transparent);
}

.monitor-title-cn {
  font-size: 32px;
  font-weight: 600;
  color: $cyan;
  letter-spacing: 2px;
}

.monitor-title-en {
  font-size: 28px;
  color: $text-dim;
  margin-left: 10px;
}
.monitor-button{
  display: flex;
  position: absolute;
  top:15px;
  right:240px;
  p{
    width:160px;
    height:50px;
    line-height:48px;
    font-size:28px;
    text-align: center;
    margin-right:20px;
    border-radius:10px;
    cursor: pointer;
  }
  .checkButton{
    border:1px solid #00D8FF;
    color:#00D8FF;
  }
  .noCheckButton{
    border:1px solid #3D6187;
    color:#3D6187;
  }
}
.monitor-status {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 15px;
}

.monitor-status-text {
  font-size: 28px;
  color: $text-dim;
}
.monitor-play-box{
  .for-play-box{
    display:inline-block;
    width:1398px;
    height:810px;
    margin:20px 0 0 20px;
  }
}
// ========== Monitor Inner (2-column grid) ==========
.monitor-inner {
  flex: 1;
  display: grid;
  grid-template-columns: 575px 1fr;
  gap: 0;
  min-height: 0;
  overflow: hidden;
}

// ========== Left Column ==========
.monitor-left {
  display: flex;
  flex-direction: column;
  gap: 15px;
  padding: 20px;
  border-right: 1px solid $border;
  min-height: 0;
  overflow: hidden;
}

.search-box {
  display: flex;
  align-items: center;
  gap: 18px;
  border-radius: 10px;
  background: $bg-card;
  border: 1px solid $border;
  flex-shrink: 0;

  .search-icon {
    font-size: 32px;
    color: $text-dim;
    margin:15px 0 15px 25px;
  }

  .video-select {
    flex: 1;
    background: none;
    border: none;
    outline: none;
    color: $text;
    font-size: 30px;
    font-family: inherit;

    &::placeholder {
      color: $text-dim;
    }
  }
  ::v-deep .el-input__inner{
    height:70px;
    color: #a8cce8;
    font-size: 30px;
    background: rgba(7, 22, 54, 0);
    border: none;
    padding-left:0;
  }
  ::v-deep .el-input__inner::placeholder{
    color: rgba(110, 165, 210, 0.55);
  }
  ::v-deep .el-input .el-input__clear{
    font-size:24px;
    margin-right:12px;
  }
}

.filter-select {
  // padding: 12px 25px;
  border-radius: 10px;
  width: 100%;
  flex-shrink: 0;
  background: $bg-card;
  border: 1px solid $border;
  color: $text;
  font-size: 28px;
  font-family: inherit;
  outline: none;
  cursor: pointer;
  appearance: none;
  // background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8'%3E%3Cpath d='M0 0l6 8 6-8z' fill='rgba(30,144,255,0.6)'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 25px center;
  ::v-deep .el-input__inner{
    height:70px;
    color: #a8cce8;
    font-size: 30px;
    background: rgba(7, 22, 54, 0);
    border: none;
    padding-left: 28px;
  }
  ::v-deep .el-input__icon{
    margin-right:13px;
    color: #a8cce8;
  }
  .el-input__inner::placeholder{
    color: rgba(110, 165, 210, 0.55);
  }
}
::v-deep .el-select .el-input .el-select__caret{
  font-size:24px;
}
// ========== Tree ==========
.tree-wrap {
  flex: 1;
  overflow-y: auto;
  overflow-x: hidden;
  min-height: 0;

  &::-webkit-scrollbar {
    width: 8px;
  }

  &::-webkit-scrollbar-thumb {
    background: $border;
    border-radius: 5px;
  }
  .el-tree{
    background: rgba(7, 22, 54, 0);
    color:#A8CCE8;
  }
  ::v-deep .el-tree-node__content{
    height:62px;
    font-size:28px;
  }
  ::v-deep .el-tree-node__expand-icon{
    font-size:26px;
    color:#3E6185;
  }
  ::v-deep .el-tree--highlight-current .el-tree-node.is-current>.el-tree-node__content{
    background-color: rgba(8, 55, 106, 0.5);
  }
  ::v-deep .el-tree-node__content:hover{
    background-color: rgba(8, 55, 106, 0.5);
  }
  ::v-deep .tree-node-label:hover{
    background-color: rgba(8, 55, 106, 0);
    color:#A8CCE8;
  }
  ::v-deep .el-tree-node:focus>.el-tree-node__content{
    background-color: rgba(8, 55, 106, 0.5);
  }
}
::v-deep .tree-node-label {
  display: flex;
  align-items: center;
  gap: 15px;
  padding: 12px 20px;
  border-radius: 8px;
  font-size: 28px;
  color: $text;
  transition: all 0.2s;
  user-select: none;
  cursor: pointer;

  &:hover {
    background: $blue-dim;
    color: $blue;
  }

  &.selected {
    background: rgba(30, 144, 255, 0.15);
    color: $cyan;
    border-left: 5px solid $blue;
  }

  .arrow {
    transition: transform 0.2s;
    font-size: 25px;
    color: $text-dim;
    flex-shrink: 0;

    &.open {
      transform: rotate(90deg);
    }
  }
}

::v-deep .tree-children {
  padding-left: 35px;
  display: none;

  &.open {
    display: block;
  }
}

// ========== Right Column ==========
.monitor-right {
  padding: 20px;
  display: flex;
  flex-direction: column;
  gap: 15px;
  min-height: 0;
}

.camera-grid-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-shrink: 0;
}

.camera-breadcrumb {
  font-size: 30px;
  color: $text-dim;

  span {
    color: $cyan;
  }
}

.camera-pager {
  display: flex;
  align-items: center;
  gap: 15px;
}

.pager-btn {
  width: 60px;
  height: 60px;
  border-radius: 8px;
  cursor: pointer;
  background: $bg-card;
  border: 1px solid $border;
  color: $text-dim;
  font-size: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.2s;

  &:hover {
    border-color: $blue;
    color: $blue;
  }
}

.pager-info {
  font-size: 28px;
  color: $text-dim;
}

// ========== Camera Grid (3x3) ==========
.camera-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
  gap: 12px;
  flex: 1;
  min-height: 0;
}

.camera-cell {
  position: relative;
  border-radius: 10px;
  overflow: hidden;
  background: #020810;
  border: 1px solid $border;
  display: flex;
  align-items: center;
  justify-content: center;

  &:hover {
    border-color: $blue;
  }

  &.ai-cam {
    border-color: rgba(0, 230, 118, 0.4);
  }
}

.camera-placeholder-text {
  font-size: 48px;
  color: rgba(110, 165, 210, 0.15);
  letter-spacing: 8px;
  font-weight: 700;
  user-select: none;
}

.camera-label {
  position: absolute;
  bottom: 10px;
  left: 15px;
  font-size: 25px;
  color: rgba(255, 255, 255, 0.75);
  background: rgba(0, 0, 0, 0.5);
  padding: 3px 10px;
  border-radius: 5px;
}

.camera-rec {
  position: absolute;
  top: 10px;
  right: 15px;
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 25px;
  color: $red;
  background: rgba(0, 0, 0, 0.5);
  padding: 3px 10px;
  border-radius: 5px;

  &::before {
    content: '';
    width: 12px;
    height: 12px;
    border-radius: 50%;
    background: $red;
    animation: blinkRed 1s ease-in-out infinite;
  }
}

.camera-ai-badge {
  position: absolute;
  top: 10px;
  left: 15px;
  font-size: 25px;
  color: $green;
  background: rgba(0, 30, 15, 0.75);
  padding: 3px 10px;
  border-radius: 5px;
  border: 1px solid rgba(0, 230, 118, 0.3);
  z-index: 2;
}

.ai-detection-box {
  position: absolute;
  border: 5px solid $red;
  background: rgba(255, 59, 59, 0.1);
  border-radius: 5px;
  animation: detBox 1.5s ease-in-out infinite;
}

.ai-detection-label {
  position: absolute;
  bottom: 100%;
  left: 0;
  white-space: nowrap;
  font-size: 25px;
  background: $red;
  color: #fff;
  padding: 3px 10px;
  border-radius: 5px;
  margin-bottom: 5px;
}

// ========== Keyframes ==========
@keyframes blinkRed {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.35; }
}

@keyframes detBox {
  0%, 100% {
    border-color: #ff3b3b;
    box-shadow: 0 0 20px rgba(255, 59, 59, 0.4);
  }
  50% {
    border-color: #fca5a5;
    box-shadow: 0 0 45px rgba(255, 59, 59, 0.7);
  }
}


</style>
