<template>
  <div class="video-wall-container">
    <transition-group
      name="grid-fade"
      tag="div"
      class="video-grid"
      :style="gridStyle"
    >
      <div
        v-for="(item, index) in currentBoxList"
        :key="item.boxId"
        :id="'childBox_' + item.boxId"
        class="video-cell"
        :class="{
          'is-active': selectedMonitor && selectedMonitor.boxId === item.boxId,
          'is-dragging': draggedItem && draggedItem.boxId === item.boxId,
          'is-recording': item.recording
        }"
        draggable="true"
        @click="setActiveBox(item)"
        @dblclick="changeToOne(item)"
        @dragstart="handleDragStart(item, $event)"
        @dragover="handleDragOver($event)"
        @drop="handleDrop(item, $event)"
        @dragend="handleDragEnd($event)"
      >
        <div class="video-wrapper">
<!--          :video-src='active===1 ? item.mainUrl : item.auxiliaryUrl'-->
          <webrtc-player
            v-if="(item.code === 'H264' || item.code !== 'H265') && item.mainUrl"
            :video-src="active===1 ? item.mainUrl : item.auxiliaryUrl"
            :video-id="item.boxId"
            :camera-name="item.name"
            ref='player'
            @destroy="close"
            class="player-instance"
          />
<!--          :video-src='active===1 ? item.mainUrl : item.auxiliaryUrl'-->
          <jessibucaBox
            v-else-if="item.code === 'H265' && item.mainUrl"
            :video-src="active===1 ? item.mainUrl : item.auxiliaryUrl"
            :video-id="item.boxId"
            :camera-name="item.name"
            ref='player'
            @destroy="close"
            class="player-instance"
          ></jessibucaBox>
<!--          <video-player-->
<!--            v-else-if="item.hls"-->
<!--            class="video-player-box"-->
<!--            style="width: 100%; height: 90%"-->
<!--            ref="videoPlayer"-->
<!--            :options="{-->
<!--            playbackRates: [0.7, 1.0, 1.5, 2.0], // 播放速度-->
<!--            autoplay: true, // 禁止自动播放（浏览器限制）-->
<!--            muted: true, // 静音-->
<!--            controls: true, // 显示控制栏-->
<!--            preload: 'auto',-->
<!--            techOrder: ['html5', 'hls'], // 优先用 HLS 插件解析-->
<!--            width: '100%',-->
<!--            height: '100%',-->
<!--            sources: [-->
<!--              {-->
<!--                type: 'application/x-mpegURL', // m3u8 对应的 MIME 类型-->
<!--                src:  'http://10.168.1.232:8889/38/SIS-1766510219282/whep'-->
<!--              }-->
<!--            ],-->
<!--            notSupportedMessage: '当前浏览器不支持播放此视频'-->
<!--          }"-->
<!--          />-->

          <div v-else class="empty-state">
            <i class="el-icon-video-camera"></i>
            <span>无信号</span>
          </div>
        </div>

        <div class="video-overlay">
          <span class="video-title">{{ item.name || `通道 ${item.boxId}` }}</span>
          <div class="status-indicators">
            <i v-if="item.recording" class="el-icon-loading recording-icon" title="录像中"></i>
          </div>
        </div>
      </div>
    </transition-group>
  </div>
</template>

<script>
import player from '@/components/Jessibuca'
import webrtcPlayer from "@/components/WebrtcPlayer";
import jessibucaBox from './jessibucaBox.vue'
import { mapGetters } from 'vuex'

export default {
  name: 'VideoWall',
  components: { player, webrtcPlayer, jessibucaBox },
  data() {
    return {
      draggedItem: null,
      // 防抖定时器
      timer: null,
    }
  },
  computed: {
    ...mapGetters(['boxList', 'active', 'lastActive', 'selectedTreeData', 'selectedMonitor', 'boxListIndex']),

    // 获取当前页面需要渲染的列表
    currentBoxList() {
      // 逻辑保持不变，根据 active 数量截取
      // 注意：这里假设你的 boxListIndex 和 active 逻辑是分页用的
      // 如果 boxList 长度固定为24，这里可能需要根据分页逻辑调整 slice
      // 此处沿用你原本的逻辑: boxList.slice(boxListIndex)
      // 但通常建议精确截取: boxList.slice(startIndex, startIndex + pageSize)

      // 修正建议：根据 active 数量，精确切分当前页数据，避免v-for渲染过多隐藏元素
      let count = 0;
      switch (this.active) {
        case 1:
          count = 1;
          break;
        case 4:
          count = 4;
          break;
        case 9:
          count = 9;
          break;
        case 16:
          count = 16;
          break;
        case 36:
          count = 36;
          break;
        case 64:
          count = 64;
          break;
        default:
          count = this.active;
      }
      // 假设 boxListIndex 是起始索引
      return this.boxList.slice(this.boxListIndex, this.boxListIndex + count);
    },

    // [核心优化] 使用 CSS Grid 动态计算样式
    gridStyle() {
      let cols = 1;
      switch (this.active) {
        case 1:
          cols = 1;
          break;
        case 4:
          cols = 2;
          break;
        case 9:
          cols = 3;
          break;
        case 16:
          cols = 4;
          break;
        case 36:
          cols = 6;
          break;
        case 64:
          cols = 8;
          break;
        default:
          cols = Math.ceil(Math.sqrt(this.active));
      }
      return {
        'grid-template-columns': `repeat(${cols}, 1fr)`,
        'grid-template-rows': `repeat(${cols}, 1fr)`
      }
    }
  },
  methods: {
    // --- 业务逻辑保持原有不变，仅优化部分写法 ---

    stopRecordings(boxesToStop, shouldSave) {
      if (!this.$refs.player || this.$refs.player.length === 0) return;
      boxesToStop.forEach(box => {
        const playerComponent = this.$refs.player.find(p => p.videoId === box.boxId);
        if (playerComponent && typeof playerComponent.stopRecording === 'function') {
          playerComponent.stopRecording(shouldSave);
        }
      });
    },

    closeAllVideos() {
      this.boxList.forEach(item => {
        if (item.mainUrl || item.auxiliaryUrl) {
          this.setActiveBox(item);
          Object.assign(item, {
            mainUrl: '', auxiliaryUrl: '', code: '', cameraId: '',
            name: '', rtc: '', rtsp: '', recording: false
          });
        }
      });
      this.$store.commit('updateSelectedMonitor', {});
      this.$emit('clearTreeSelected');
      this.$message.success('所有预览已关闭');
    },

    changeToOne(item) {
      if (this.timer) {
        clearTimeout(this.timer);
        this.timer = null;
      }

      // 简单的防录像中断逻辑
      if (this.boxList.some(b => b.recording) && this.active !== 1) {
        this.$message.warning('正在录像中，切换分屏可能会中断录像！');
        // 这里看业务需求是否强制return
        // return
      }

      if (this.lastActive !== 0) {
        // 恢复多屏
        this.$store.commit('updateBoxListIndex', 0)
        this.$store.commit('updateActive', this.lastActive)
        this.$store.commit('updateLastActive', 0)
      } else {
        if (this.active === 1) return;
        // 切换单屏
        this.$store.commit('updateLastActive', this.active)
        // 计算正确的 index (原逻辑)
        const newIndex = item.boxId - 1;
        // 注意：这里要确保 boxId 和 索引 的对应关系是强绑定的
        this.$store.commit('updateBoxListIndex', newIndex)
        this.$store.commit('updateActive', 1)
      }
    },

    close(boxId) {
      // 1. 深拷贝一份当前的 boxList，避免直接修改 Vuex 数据
      let newBoxList = JSON.parse(JSON.stringify(this.boxList));

      // 2. 在拷贝的数据中找到对应的窗口并清空数据
      const index = newBoxList.findIndex(item => item.boxId === boxId);
      if (index !== -1) {
        // 保留 boxId，清空其他业务数据
        newBoxList[index] = {
          boxId: boxId, // 核心ID不能丢
          mainUrl: '',
          auxiliaryUrl: '',
          code: '',
          cameraId: '',
          name: '',
          rtc: '',
          rtsp: '',
          recording: false
        };
      }

      // 3. 通过 Vuex 提交更新（这会立即触发视图重绘）
      this.$store.commit('updateBoxList', newBoxList);

      // 4. 清理选中状态和红框
      this.showRedBorder = false;

      // 5. 如果需要，通知父组件清除树列表的选中状态
      this.$emit('clearTreeSelected');
    },

    setActiveBox(item) {
      console.log(this.$store.state.video)
      this.$store.commit('updateSelectedMonitor', item);
      if (item.cameraId) {
        this.$emit('setCurrentKeyTree', item.cameraId);
      } else {
        this.$emit('clearTreeSelected');
      }
    },

    // --- 拖拽逻辑 (保持核心逻辑，移除DOM操作样式的部分，改用数据驱动class) ---
    handleDragStart(item, event) {
      if (item.recording) {
        this.$message.warning('无法拖拽正在录像的窗口！');
        event.preventDefault();
        return;
      }
      this.draggedItem = item;
      event.dataTransfer.effectAllowed = 'move';
      // 这里的 opacity 通过 css class .is-dragging 控制，不需要 js 操作 style
    },

    handleDragOver(event) {
      event.preventDefault();
      event.dataTransfer.dropEffect = 'move';
    },

    handleDragEnd() {
      this.draggedItem = null;
    },

    handleDrop(targetItem, event) {
      event.preventDefault();
      const sourceItem = this.draggedItem;
      if (!sourceItem || sourceItem.boxId === targetItem.boxId) return;
      if (targetItem.recording) {
        this.$message.warning('无法拖拽到正在录像的窗口！');
        return;
      }

      // 深拷贝并交换
      const newBoxList = JSON.parse(JSON.stringify(this.boxList));
      const sourceIndex = newBoxList.findIndex(b => b.boxId === sourceItem.boxId);
      const targetIndex = newBoxList.findIndex(b => b.boxId === targetItem.boxId);

      if (sourceIndex !== -1 && targetIndex !== -1) {
        const { boxId: sId, ...sData } = newBoxList[sourceIndex];
        const { boxId: tId, ...tData } = newBoxList[targetIndex];

        newBoxList[sourceIndex] = { ...tData, boxId: sId };
        newBoxList[targetIndex] = { ...sData, boxId: tId };

        this.$store.commit('updateBoxList', newBoxList);

        // 交换后如果其中一个是选中状态，需要更新选中项的引用
        if (this.selectedMonitor && (this.selectedMonitor.boxId === sId || this.selectedMonitor.boxId === tId)) {
          const activeId = this.selectedMonitor.boxId === sId ? tId : sId; // 逻辑可能需要根据业务调整，这里仅做提示
          // 简单做法：交换后重置选中或者保持ID选中
        }
      }
      this.draggedItem = null;
    }
  }
}
</script>

<style lang="scss" scoped>
/* 定义变量方便主题切换 */
$bg-color: #1a1a1a;
$cell-bg: #000000;
$border-color: #333333;
$active-color: #409eff; // 选中色，也可以换成亮青色 #00ffff
$text-color: #eeeeee;

.video-wall-container {
  width: 100%;
  height: 100%;
  background-color: $bg-color;
  padding: 2px; /* 微小的外边距 */
  box-sizing: border-box;
  overflow: hidden;
}

.video-grid {
  display: grid;
  width: 100%;
  height: 100%; /* 撑满容器 */
  /* 核心：使用 gap 代替 margin，更整齐 */
  gap: 2px;

  /* 保持 16:9 比例的核心逻辑，如果想铺满屏幕可移除 aspect-ratio */
  // aspect-ratio: 16/9;
  // margin: 0 auto;
}

.video-cell {
  position: relative;
  background-color: $cell-bg;
  border: 1px solid $border-color;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  cursor: pointer;
  transition: all 0.2s ease-in-out;

  /* 确保子元素绝对定位基于此 */
  z-index: 1;

  /* 拖拽样式 */
  &.is-dragging {
    opacity: 0.4;
    border: 2px dashed #999;
  }

  /* 选中样式：外发光+高亮边框 */
  &.is-active {
    border: 1px solid $active-color;
    z-index: 10; /* 选中时层级提高，防止边框被遮挡 */
    box-shadow: 0 0 0 1px rgba($active-color, 0.5) inset, 0 0 8px rgba($active-color, 0.6);
  }

  /* 录像中样式 */
  &.is-recording {
    &::after {
      content: '';
      position: absolute;
      top: 6px;
      right: 6px;
      width: 8px;
      height: 8px;
      border-radius: 50%;
      background-color: #f56c6c;
      animation: blink 1s infinite;
      z-index: 20;
    }
  }

  &:hover {
    border-color: lighten($border-color, 20%);

    .video-overlay {
      opacity: 1;
      transform: translateY(0);
    }
  }
}

.video-wrapper {
  width: 100%;
  height: 100%;
  position: relative;

  .player-instance {
    width: 100%;
    height: 100%;
    object-fit: fill; /* 根据需求改为 contain */
    display: block;
  }
}

.empty-state {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  color: #555;

  i {
    font-size: 48px;
    margin-bottom: 10px;
  }

  span {
    font-size: 14px;
  }
}

/* 悬浮遮罩层 - 类似 Youtube/Bilibili 效果 */
.video-overlay {
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
  padding: 5px 10px;
  background: linear-gradient(to top, rgba(0, 0, 0, 0.8), rgba(0, 0, 0, 0));
  color: white;
  display: flex;
  justify-content: space-between;
  align-items: center;
  z-index: 5;

  /* 默认稍微隐藏，hover时完全显示 */
  opacity: 0.8;
  transition: opacity 0.3s;

  .video-title {
    font-size: 12px;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 1);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
}

/* 录像红点闪烁 */
@keyframes blink {
  0% {
    opacity: 1;
  }
  50% {
    opacity: 0.4;
  }
  100% {
    opacity: 1;
  }
}

/* 网格切换动画 */
.grid-fade-enter-active, .grid-fade-leave-active {
  transition: all 0.3s;
}

.grid-fade-enter, .grid-fade-leave-to {
  opacity: 0;
  transform: scale(0.9);
}
</style>
