<template>
  <div style="height: 100%">
    <el-card id="devicePosition" shadow="never" style="height: calc(100% - 40px);border: 0;" :body-style="{ padding: '0px' }" class="border-none">
      <el-container
        v-loading="loading"
        style="height: 100%"
        :element-loading-text="t('sip.splitview998531-0')"
      >
        <el-aside width="250px" style="background-color: #ffffff">
          <DeviceTree :click-event="clickEvent" />
        </el-aside>
        <el-main style="padding: 0">
          <div
            height="5vh"
            style="text-align: left; font-size: 17px; line-height: 5vh; margin-bottom: 10px"
          >
            {{ t('sip.splitview998531-1') }}
            <el-button
              type="success"
              style="margin-left: 10px"
              :class="{ active: spilt == 1 }"
              @click="spilt = 1"
              :icon="FullScreen"
              plain
              size="small"
            >
              {{ t('sip.splitview998531-2') }}
            </el-button>
            <el-button
              type="info"
              style="margin-left: 10px"
              :class="{ active: spilt == 4 }"
              @click="spilt = 4"
              :icon="Menu"
              plain
              size="small"
            >
              {{ t('sip.splitview998531-3') }}
            </el-button>
            <el-button
              type="warning"
              style="margin-left: 10px"
              :class="{ active: spilt == 9 }"
              @click="spilt = 9"
              :icon="Grid"
              plain
              size="small"
            >
              {{ t('sip.splitview998531-4') }}
            </el-button>
          </div>
          <div style="height: 85vh; display: flex; flex-wrap: wrap">
            <div
              v-for="i in spilt"
              :key="i"
              class="play-box"
              :style="liveStyle"
              :class="{ redborder: playerIdx == i - 1 }"
              @click="playerIdx = i - 1"
            >
              <div
                v-if="!videoUrl[i - 1]"
                style="color: #ffffff; font-size: 30px; font-weight: bold"
                >{{ i }}</div
              >
              <player
                v-else
                :ref="(el) => setPlayerRef(el, i - 1)"
                :video-url="videoUrl[i - 1]"
                fluent
                autoplay
                @screenshot="shot"
                class="player-wrap"
                @destroy="destroy"
              />
            </div>
          </div>
        </el-main>
      </el-container>
    </el-card>
  </div>
</template>

<script setup>
import { ref, reactive, computed, watch, onMounted, onUnmounted, nextTick } from 'vue'
import { useRoute } from 'vue-router'
import { FullScreen, Menu, Grid } from '@element-plus/icons-vue'
import player from './components/player/jessibuca.vue'
import DeviceTree from './components/player/DeviceTree.vue'
import { startPlay } from '@/api/pms/video/channel'
import { listSipDeviceChannel } from '@/api/pms/video/sipdevice';

const { t } = useI18n()

// 使用组合式API
const route = useRoute()

// refs
const playerRefs = ref([])

// 数据状态
const videoUrl = ref([''])
const spilt = ref(1) //分屏
const playerIdx = ref(0) //激活播放器
const updateLooper = ref(0) //数据刷新轮训标志
const count = ref(15)
const total = ref(0)
const loading = ref(false)



// 设置播放器引用
const setPlayerRef = (el, index) => {
  if (el) {
    playerRefs.value[index] = el
  }
}

// 计算属性 - 直播样式
const liveStyle = computed(() => {
  let style = { width: '81%', height: '99%' }
  switch (spilt.value) {
    case 4:
      style = { width: '40%', height: '49%' }
      break
    case 9:
      style = { width: '27%', height: '32%' }
      break
  }

  nextTick(() => {
    for (let i = 0; i < spilt.value; i++) {
      const player = playerRefs.value[i]
      if (player && typeof player.updatePlayerDomSize === 'function') {
        player.updatePlayerDomSize()
      }
    }
  })

  return style
})

// 监听分屏变化
watch(
  () => spilt.value,
  async (newSplit, oldSplit) => {
    // 只有当分屏数增加（例如从1到4，或从4到9）且有当前选中设备时才执行
    if (newSplit > oldSplit && currentDevice.value) {
      console.log(`分屏从 ${oldSplit} 变为 ${newSplit}，自动填充设备 ${currentDevice.value.name} 的通道`)
      
      // 延迟执行，确保DOM更新完成
      await nextTick()
      
      loading.value = true
      try {
        // 1. 重新获取当前设备的通道
        const channels = await getDeviceChannels(currentDevice.value.id)
        
        if (!channels || channels.length === 0) {
          console.warn('该设备下没有可用通道')
          return
        }
        
        // 2. 重新分配通道到所有播放器
        await assignChannelsToPlayers(channels)
        
      } catch (error) {
        console.error('分屏变化时填充通道出错:', error)
        ElMessage.error('自动填充通道失败')
      } finally {
        loading.value = false
      }
    }
    // 可选：当分屏数减少时，可以清空多余的播放器
    else if (newSplit < oldSplit) {
      // 清空超出当前分屏数的播放器
      for (let i = newSplit; i < oldSplit; i++) {
        const newVideoUrls = [...videoUrl.value]
        newVideoUrls[i] = ''
        videoUrl.value = newVideoUrls
        clear(i + 1) // 清理存储的数据
      }
    }
  },
  { immediate: false } // 不需要立即执行
)

// 监听路由变化
watch(
  () => route.fullPath,
  () => {
    checkPlayByParam()
  }
)

// 生命周期钩子
onMounted(() => {
  checkPlayByParam()
})

onUnmounted(() => {
  clearTimeout(updateLooper.value)
})

// 销毁事件
const destroy = (idx) => {
  console.log(idx)
  clear(idx.substring(idx.length - 1))
}
const currentDevice = ref(null) // 存储当前选中的设备信息
// 点击事件
const clickEvent = async (data) => {
  // 情况1：点击的是设备节点 (type === 0)
  if (data.type === 0) {
     currentDevice.value = {
      id: data.userData?.serialNumber,
      name: data.name,
      data: data
    }
    const deviceId = data.userData?.serialNumber; // 从树节点数据中提取设备ID
    if (!deviceId) return;

    loading.value = true;
    try {
      // 1. 获取该设备下的所有通道
      const channels = await getDeviceChannels(deviceId);
      if (!channels || channels.length === 0) {
        console.warn('该设备下没有可用通道');
        return;
      }

      // 2. 将通道智能分配给播放器
      await assignChannelsToPlayers(channels);

    } catch (error) {
      console.error('处理设备通道时出错:', error);
    } finally {
      loading.value = false;
    }
  }
  // 情况2：点击的是具体的通道节点，保持原有逻辑不变
  else if (data.userData?.channelSipId) {
    sendDevicePush(data.userData);
  }
};

const getDeviceChannels = async (deviceId) => {
  try {
    const response = await listSipDeviceChannel(deviceId);
    console.log('获取设备通道列表成功:', response);
    // 假设接口返回的是通道数组，且每个通道对象结构符合 { basicData: { channelSipId, ... }, ... }
    return response || [];
  } catch (error) {
    console.error('获取设备通道列表失败:', error);
    return [];
  }
};

const assignChannelsToPlayers = async (channels) => {
  const currentSplit = spilt.value
  console.log(`分配 ${channels.length} 个通道到 ${currentSplit} 个播放窗口`)
  
  // 决定从哪个播放器窗口开始分配：始终从第一个窗口(0)开始
  // 这样保证每次分屏变化时都能从头开始重新分配
  const startPlayerIndex = 0
  
  // 决定从哪个通道开始取：总是从第一个通道开始
  const startChannelIndex = 0
  
  // 循环，为当前分屏布局中的每个位置分配通道
  for (let screenPosition = 0; screenPosition < currentSplit; screenPosition++) {
    const channelIndex = startChannelIndex + screenPosition
    const targetPlayerIndex = startPlayerIndex + screenPosition
    
    // 延迟执行，避免同时发起大量请求
    await new Promise(resolve => setTimeout(resolve, 50))
    
    if (channelIndex < channels.length) {
      // 有对应通道，开始播放
      const channelData = channels[channelIndex]
      // 构建符合 sendDevicePush 要求的参数格式
      const playData = {
        deviceSipId: channelData.deviceId,
        channelSipId: channelData.basicData?.channelSipId || channelData.id,
        name: channelData.name || `通道${channelIndex + 1}`,
        ...channelData.basicData
      }
      console.log(`将通道 ${playData.name} 分配给播放器 ${targetPlayerIndex}`)
      await sendDevicePush(playData, targetPlayerIndex)
    } else {
      // 没有更多通道，清空当前位置
      const newVideoUrls = [...videoUrl.value]
      newVideoUrls[targetPlayerIndex] = ''
      videoUrl.value = newVideoUrls
      // 清理存储的数据
      clear(targetPlayerIndex + 1)
      console.log(`播放器 ${targetPlayerIndex} 没有可用通道，已清空`)
    }
  }
}
// 通知设备上传媒体流
const sendDevicePush = (itemData, targetIndex = null) => {
  // 关键修改：允许从外部传入 targetIndex，默认使用当前激活的 playerIdx
  const playIndex = targetIndex !== null ? targetIndex : playerIdx.value;

  save(itemData, playIndex); // 保存数据也要使用正确的索引

  let deviceId = itemData.deviceSipId;
  let channelId = itemData.channelSipId;
  loading.value = true;

  return startPlay(deviceId, channelId)
    .then((response) => {
      let res = response;
      if (window.location.protocol === 'http:') {
        itemData.playUrl = res.ws_flv;
      } else {
        itemData.playUrl = res.wss_flv;
      }
      itemData.streamId = res.streamId;
      setPlayUrl(itemData.playUrl, playIndex); // 播放URL设置到指定位置
    })
    .finally(() => {
      loading.value = false;
    });
};




// 设置播放URL
const setPlayUrl = (url, idx) => {
  const newVideoUrls = [...videoUrl.value]
  newVideoUrls[idx] = url
  videoUrl.value = newVideoUrls

  setTimeout(() => {
    window.localStorage.setItem('videoUrl', JSON.stringify(videoUrl.value))
  }, 100)
}

// 检查播放参数
const checkPlayByParam = () => {
  let { deviceId, channelId } = route.query
  if (deviceId && channelId) {
    sendDevicePush({ deviceId, channelId })
  }
}

// 截图处理
const shot = (e) => {
  var base64ToBlob = function (code) {
    let parts = code.split(';base64,')
    let contentType = parts[0].split(':')[1]
    let raw = window.atob(parts[1])
    let rawLength = raw.length
    let uInt8Array = new Uint8Array(rawLength)
    for (let i = 0; i < rawLength; ++i) {
      uInt8Array[i] = raw.charCodeAt(i)
    }
    return new Blob([uInt8Array], {
      type: contentType
    })
  }

  let aLink = document.createElement('a')
  let blob = base64ToBlob(e)
  let evt = document.createEvent('HTMLEvents')
  evt.initEvent('click', true, true)
  aLink.download = 't("sip.splitview998531-5")' 
  aLink.href = URL.createObjectURL(blob)
  aLink.click()
}

// 保存数据
const save = (item, index) => {
  let dataStr = window.localStorage.getItem('playData') || '[]';
  let data = JSON.parse(dataStr);
  data[index] = item;
  window.localStorage.setItem('playData', JSON.stringify(data));
};

// 清除数据
const clear = (idx) => {
  let dataStr = window.localStorage.getItem('playData') || '[]'
  let data = JSON.parse(dataStr)
  data[idx - 1] = null
  console.log(data)
  window.localStorage.setItem('playData', JSON.stringify(data))
}
</script>

<style scoped>
.btn {
  margin: 0 10px;
}

.btn:hover {
  color: #409eff;
}

.btn.active {
  color: #409eff;
}

.redborder {
  border: 2px solid red !important;
}

.play-box {
  background-color: #000000;
  border: 1px solid #505050;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-right: 10px;
  position: relative;
  border-radius: 5px;
}

.player-wrap {
  position: absolute;
  top: 0px;
  height: 100% !important;
}
</style>
