<template>
  <div ref="bigscreenRef" class="bigscreen" @dblclick="toggleFullscreen">
    <!-- 顶部标题区 -->
    <header class="bs-header">
      <div class="bs-header-left">
        <div class="header-decoration"></div>
      </div>
      <div class="bs-header-center">
        <h1 class="bs-title">教室智能人脸考勤数据大屏</h1>
        <p class="bs-subtitle">Classroom Smart Attendance Data Dashboard</p>
      </div>
      <div class="bs-header-right">
        <div class="header-time">
          <el-icon><Clock /></el-icon>
          <span>{{ currentTime }}</span>
        </div>
        <el-button :icon="Refresh" circle size="small" class="refresh-btn" @click="refreshData" />
        <el-tooltip :content="isFullscreen ? '退出全屏' : '全屏展示'" placement="bottom">
          <el-button :icon="FullScreen" circle size="small" class="fullscreen-btn" @click="toggleFullscreen" />
        </el-tooltip>
      </div>
    </header>

    <!-- 核心数据卡片 -->
    <div class="bs-stats">
      <div class="bs-stat-card">
        <div class="stat-icon" style="background: linear-gradient(135deg, #52c41a, #73d13d)">
          <el-icon :size="28"><UserFilled /></el-icon>
        </div>
        <div class="stat-body">
          <div class="stat-value">{{ stats.attendanceRate }}<span class="stat-unit">%</span></div>
          <div class="stat-label">全校今日出勤率</div>
          <div class="stat-trend" :class="stats.trend >= 0 ? 'up' : 'down'">
            <el-icon><CaretTop v-if="stats.trend >= 0" /><CaretBottom v-else /></el-icon>
            {{ Math.abs(stats.trend) }}% 较昨日
          </div>
        </div>
      </div>

      <div class="bs-stat-card">
        <div class="stat-icon" style="background: linear-gradient(135deg, #722ed1, #9254de)">
          <el-icon :size="28"><TrendCharts /></el-icon>
        </div>
        <div class="stat-body">
          <div class="stat-value">{{ stats.focusRate }}<span class="stat-unit">%</span></div>
          <div class="stat-label">课堂专注度占比</div>
          <div class="stat-trend" :class="stats.focusTrend >= 0 ? 'up' : 'down'">
            <el-icon><CaretTop v-if="stats.focusTrend >= 0" /><CaretBottom v-else /></el-icon>
            {{ Math.abs(stats.focusTrend) }}% 较昨日
          </div>
        </div>
      </div>
    </div>

    <!-- 多维度展示区 -->
    <div class="bs-charts">
      <!-- 左侧：出勤趋势 -->
      <div class="bs-panel">
        <div class="panel-header">
          <h3>出勤趋势</h3>
        </div>
        <div ref="trendChartRef" class="panel-body"></div>
      </div>

      <!-- 右侧：行为分布饼图 -->
      <div class="bs-panel">
        <div class="panel-header">
          <h3>课堂行为分布</h3>
        </div>
        <div ref="behaviorChartRef" class="panel-body"></div>
      </div>
    </div>

    <!-- 底部实时监控 -->
    <div class="bs-monitor">
      <div class="monitor-header">
        <h3>教室实时监控</h3>
        <div class="monitor-selects">
          <el-select v-model="selectedBuildingId" placeholder="选择教学楼" size="small" class="monitor-select" popper-class="monitor-select-popper" :teleported="false" @change="onBuildingChange">
            <el-option v-for="b in buildingList" :key="b.id" :label="b.buildingName" :value="b.id" />
          </el-select>
          <el-select v-model="selectedRoomId" placeholder="选择教室" size="small" class="monitor-select" popper-class="monitor-select-popper" :teleported="false" :disabled="!selectedBuildingId" @change="onRoomChange">
            <el-option v-for="r in filteredRooms" :key="r.id" :label="r.roomName" :value="r.id" />
          </el-select>
        </div>
      </div>
      <div class="monitor-grid">
        <div v-if="!selectedBuildingId" class="monitor-empty">请选择教学楼和教室查看监控</div>
        <template v-else-if="!selectedRoomId">
          <div class="monitor-empty">请选择教室查看监控</div>
        </template>
        <template v-else>
          <div v-for="device in filteredDevices" :key="device.id" class="monitor-cell">
            <div class="monitor-feed">
              <WebRtcPlayer v-if="device.streamUrl" :src="`${device.streamUrl}/whep`"/>
              <el-icon v-else :size="36" color="#4a4a6a"><VideoCamera /></el-icon>
            </div>
            <div class="monitor-label">
              <span class="label-left">
                <span class="dot" :class="{ pulse: device.onlineStatus === 1, offline: device.onlineStatus !== 1 }"></span>
                {{ device.deviceName || device.deviceNo }} · {{ device.onlineStatus === 1 ? '直播中' : '离线' }}
              </span>
              <el-icon :size="15" class="zoom-icon" @click.stop="enlargeMonitor(device)"><FullScreen /></el-icon>
            </div>
          </div>
          <div v-if="filteredDevices.length === 0" class="monitor-empty">暂无数据</div>
        </template>
      </div>
    </div>
    <!-- 视频放大弹窗 -->
    <el-dialog v-model="videoDialogVisible" :title="videoDialogDevice?.deviceName || videoDialogDevice?.deviceNo || '监控画面'" width="80%" top="5vh" class="video-dialog" destroy-on-close>
      <div class="dialog-video-wrapper">
        <WebRtcPlayer v-if="videoDialogDevice?.streamUrl" :src="`${videoDialogDevice.streamUrl}/whep`" />
        <div v-else class="dialog-no-stream">该设备暂无视频流</div>
      </div>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, reactive, computed, onMounted, onUnmounted } from 'vue'
import { ElMessage } from 'element-plus'
import * as echarts from 'echarts'
import { Refresh, FullScreen } from '@element-plus/icons-vue'
import { getBigScreenStats, getBigScreenTrend, getBigScreenBehavior } from '@/api/bigscreen'
import { getBuildingList, getRoomsList, getDeviceList } from '@/api/info'
import WebRtcPlayer from '@/components/WebRtcPlayer.vue' 

const currentTime = ref('')
const timer = ref(null)

// 监控区域
const buildingList = ref([])
const roomList = ref([])
const deviceList = ref([])
const selectedBuildingId = ref(null)
const selectedRoomId = ref(null)

const filteredRooms = computed(() => {
  if (!selectedBuildingId.value) return []
  return roomList.value.filter(r => r.buildingId === selectedBuildingId.value)
})

const filteredDevices = computed(() => {
  if (!selectedRoomId.value) return []
  return deviceList.value.filter(d => d.classroomId === selectedRoomId.value)
})

const onBuildingChange = () => {
  selectedRoomId.value = null
}

const onRoomChange = () => {
  // 选择教室后设备自动过滤
}

const trendChartRef = ref(null)
const behaviorChartRef = ref(null)
const trendChart = ref(null)

const stats = reactive({
  attendanceRate: 0,
  trend: 0,
  focusRate: 0,
  focusTrend: 0
})

const fetchStats = async () => {
  try {
    const res = await getBigScreenStats()
    if (res?.data) {
      stats.attendanceRate = res.data.attendanceRate ?? stats.attendanceRate
      stats.trend = res.data.trend ?? stats.trend
      stats.focusRate = res.data.focusRate ?? stats.focusRate
      stats.focusTrend = res.data.focusTrend ?? stats.focusTrend
    }
  } catch {
    ElMessage.warning('获取大屏数据失败')
  }
}

const fetchTrend = async () => {
  try {
    const res = await getBigScreenTrend()
    if (!res?.data || !trendChartRef.value) return
    const { dates, rates } = res.data
    const yMin = Math.max(0, Math.floor(Math.min(...rates) - 2))
    const yMax = Math.min(100, Math.ceil(Math.max(...rates) + 2))

    // 释放旧实例，重新初始化确保 tooltip 等配置完整生效
    const old = echarts.getInstanceByDom(trendChartRef.value)
    old?.dispose()

    const chart = echarts.init(trendChartRef.value)
    trendChart.value = chart
    chart.setOption({
      tooltip: {
        trigger: 'axis',
        backgroundColor: 'rgba(6, 12, 28, 0.92)',
        borderColor: 'rgba(82, 196, 26, 0.35)',
        textStyle: { color: '#fff', fontSize: 13 },
        formatter: (params) => {
          const p = Array.isArray(params) ? params[0] : params
          return `<div style="line-height:1.8">
            <span style="color:rgba(255,255,255,0.5)">日期：</span><span style="color:#fff">${p.axisValue}</span><br/>
            <span style="color:rgba(255,255,255,0.5)">出勤率：</span><span style="color:#52c41a;font-weight:700;font-size:16px">${p.value}%</span>
          </div>`
        }
      },
      grid: { top: 20, right: 20, bottom: 20, left: 40 },
      xAxis: { type: 'category', data: dates, axisLabel: { fontSize: 11 } },
      yAxis: { type: 'value', min: yMin, max: yMax, axisLabel: { formatter: '{value}%' } },
      series: [{
        name: '出勤率',
        data: rates,
        type: 'line',
        smooth: true,
        symbol: 'circle',
        symbolSize: 8,
        lineStyle: { color: '#52c41a', width: 2.5 },
        itemStyle: { color: '#52c41a' },
        areaStyle: {
          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
            { offset: 0, color: 'rgba(82,196,26,0.2)' },
            { offset: 1, color: 'rgba(82,196,26,0.02)' }
          ])
        }
      }]
    })
  } catch {
    ElMessage.warning('获取出勤趋势失败')
  }
}

const fetchBehavior = async () => {
  try {
    const res = await getBigScreenBehavior()
    if (!res?.data || !behaviorChartRef.value) return

    const old = echarts.getInstanceByDom(behaviorChartRef.value)
    old?.dispose()

    const chart = echarts.init(behaviorChartRef.value)
    chart.setOption({
      tooltip: {
        trigger: 'item',
        backgroundColor: 'rgba(6, 12, 28, 0.92)',
        borderColor: 'rgba(114, 46, 209, 0.35)',
        textStyle: { color: '#fff', fontSize: 13 },
        formatter: '{b}: {c}%'
      },
      series: [{
        type: 'pie',
        radius: ['50%', '75%'],
        center: ['50%', '55%'],
        label: { fontSize: 11, color: 'rgba(255,255,255,0.6)' },
        data: res.data.map(item => ({
          value: item.value,
          name: item.name,
          itemStyle: { color: item.color }
        }))
      }]
    })
  } catch {
    ElMessage.warning('获取行为分布失败')
  }
}

const refreshData = () => {
  Promise.all([fetchStats(), fetchTrend(), fetchBehavior()])
  ElMessage.success('数据已刷新')
}

const bigscreenRef = ref(null)
const isFullscreen = ref(false)

const syncFullscreenState = () => {
  isFullscreen.value = document.fullscreenElement === bigscreenRef.value
}

const toggleFullscreen = () => {
  if (document.fullscreenElement) {
    document.exitFullscreen()
  } else {
    bigscreenRef.value?.requestFullscreen()
  }
}

onMounted(() => {
  document.addEventListener('fullscreenchange', syncFullscreenState)
})

onUnmounted(() => {
  document.removeEventListener('fullscreenchange', syncFullscreenState)
})

const enlargeMonitor = (device) => {
  videoDialogDevice.value = device
  videoDialogVisible.value = true
}

// 视频放大弹窗
const videoDialogVisible = ref(false)
const videoDialogDevice = ref(null)

const fetchMonitorData = async () => {
  try {
    const [bRes, rRes, dRes] = await Promise.all([
      getBuildingList(),
      getRoomsList(),
      getDeviceList()
    ])
    if (bRes?.data) buildingList.value = bRes.data
    if (rRes?.data) roomList.value = rRes.data
    if (dRes?.data) deviceList.value = dRes.data
  } catch {
    ElMessage.warning('获取监控数据失败')
  }
}

const updateTime = () => {
  const now = new Date()
  currentTime.value = now.toLocaleString('zh-CN', {
    year: 'numeric', month: '2-digit', day: '2-digit',
    hour: '2-digit', minute: '2-digit', second: '2-digit'
  })
}

const initCharts = () => {
  // 出勤趋势图表由 fetchTrend 完整初始化（含 API 数据）
  // 课堂行为分布图表由 fetchBehavior 完整初始化（含 API 数据）
}

onMounted(() => {
  updateTime()
  timer.value = setInterval(updateTime, 1000)
  initCharts()
  Promise.all([fetchStats(), fetchTrend(), fetchBehavior(), fetchMonitorData()])
  window.addEventListener('resize', () => {
    [trendChartRef.value, behaviorChartRef.value].forEach(el => {
      const instance = echarts.getInstanceByDom(el)
      instance?.resize()
    })
  })
})

onUnmounted(() => {
  clearInterval(timer.value)
})
</script>

<style lang="scss" scoped>
.bigscreen {
  width: 100%;
  height: calc(100vh - 96px);
  background: linear-gradient(180deg, #0a1628 0%, #132042 50%, #1a2d4a 100%);
  color: #ffffff;
  padding: 0 24px 20px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

/* 全屏时占满整个屏幕，隐藏左侧菜单和顶部导航 */
.bigscreen:fullscreen {
  height: 100vh;
  width: 100vw;
  padding: 16px 32px 24px;
  box-sizing: border-box;
}

.bs-header {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 64px;
  padding: 0 8px;
}

.bs-header-left,
.bs-header-right {
  width: 200px;
  display: flex;
  align-items: center;
  gap: 12px;
}

.bs-header-center {
  text-align: center;
}

.bs-title {
  font-size: 24px;
  font-weight: 700;
  background: linear-gradient(90deg, #52c41a, #73d13d);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
  margin-bottom: 2px;
}

.bs-subtitle {
  font-size: 12px;
  color: rgba(255, 255, 255, 0.3);
  letter-spacing: 2px;
}

.header-time {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 14px;
  color: rgba(255, 255, 255, 0.5);
  font-family: monospace;
}

.refresh-btn,
.fullscreen-btn {
  --el-button-bg-color: rgba(82, 196, 26, 0.12) !important;
  --el-button-border-color: rgba(82, 196, 26, 0.25) !important;
  --el-button-hover-bg-color: rgba(82, 196, 26, 0.22) !important;
  --el-button-hover-border-color: rgba(82, 196, 26, 0.45) !important;
  --el-button-text-color: #52c41a !important;
  box-shadow: 0 0 12px rgba(82, 196, 26, 0.15);
  transition: all 0.3s ease;

  &:hover {
    box-shadow: 0 0 20px rgba(82, 196, 26, 0.3);
    transform: translateY(-1px);
  }
}

.bs-stats {
  flex-shrink: 0;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 16px;
  margin-bottom: 16px;
}

.bs-stat-card {
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 8px;
  padding: 20px;
  display: flex;
  gap: 16px;
  align-items: center;
  backdrop-filter: blur(10px);
  transition: all 0.3s ease;

  &:hover {
    border-color: rgba(82, 196, 26, 0.3);
    background: rgba(82, 196, 26, 0.04);
  }
}

.stat-icon {
  width: 56px;
  height: 56px;
  border-radius: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
}

.stat-body {
  flex: 1;
}

.stat-value {
  font-size: 36px;
  font-weight: 700;
  color: #ffffff;
  line-height: 1;
}

.stat-unit {
  font-size: 18px;
  font-weight: 400;
  opacity: 0.5;
}

.stat-label {
  font-size: 13px;
  color: rgba(255, 255, 255, 0.4);
  margin-top: 4px;
  margin-bottom: 6px;
}

.stat-trend {
  font-size: 12px;
  display: flex;
  align-items: center;
  gap: 2px;

  &.up { color: #52c41a; }
  &.down { color: #f5222d; }
}

.bs-charts {
  flex-shrink: 0;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
  margin-bottom: 16px;
}

.bs-panel {
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 8px;
  overflow: hidden;
}

.panel-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 16px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);

  h3 {
    font-size: 15px;
    font-weight: 600;
    color: rgba(255, 255, 255, 0.8);
  }
}

.panel-body {
  height: 260px;
}

.bs-monitor {
  flex: 1;
  min-height: 0;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 8px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

.monitor-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 16px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);

  h3 {
    font-size: 15px;
    font-weight: 600;
    color: rgba(255, 255, 255, 0.8);
  }
}

.monitor-selects {
  display: flex;
  gap: 8px;
}

.monitor-select {
  width: 160px;

  :deep(.el-select__wrapper) {
    background: rgba(255, 255, 255, 0.06);
    border-color: rgba(255, 255, 255, 0.12);
    box-shadow: none;
  }

  :deep(.el-select__wrapper:hover) {
    border-color: rgba(82, 196, 26, 0.35);
  }

  :deep(.el-select__wrapper.is-focus) {
    border-color: rgba(82, 196, 26, 0.5);
    box-shadow: 0 0 0 1px rgba(82, 196, 26, 0.2);
  }

  :deep(.el-select__placeholder) {
    color: rgba(255, 255, 255, 0.3);
  }

  :deep(.el-select__placeholder.is-transparent) {
    color: rgba(255, 255, 255, 0.3);
  }

  :deep(.el-select__selected-item) {
    color: rgba(255, 255, 255, 0.85);
  }

  :deep(.el-select__caret) {
    color: rgba(255, 255, 255, 0.35);
  }
}

.monitor-grid {
  flex: 1;
  min-height: 0;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: min-content;
  gap: 12px;
  padding: 16px;
  overflow-y: auto;
  align-content: start;
}

.monitor-cell {
  border-radius: 8px;
  overflow: hidden;
  cursor: pointer;
  transition: all 0.3s ease;
  border: 1px solid transparent;

  &:hover {
    border-color: rgba(82, 196, 26, 0.4);
    transform: scale(1.02);
  }
}

.monitor-feed {
  height: 180px;
  background: #0a1020;
  display: flex;
  align-items: center;
  justify-content: center;
}

.monitor-label {
  padding: 8px 12px;
  background: rgba(0, 0, 0, 0.3);
  font-size: 12px;
  color: rgba(255, 255, 255, 0.6);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
}

.label-left {
  display: flex;
  align-items: center;
  gap: 6px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}

.zoom-icon {
  flex-shrink: 0;
  color: rgba(255, 255, 255, 0.3);
  cursor: pointer;
  transition: all 0.2s ease;

  &:hover {
    color: #52c41a;
    transform: scale(1.2);
  }
}

.dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #52c41a;
  display: inline-block;

  &.offline { background: #666; }
}

.monitor-empty {
  grid-column: 1 / -1;
  text-align: center;
  padding: 48px 0;
  color: rgba(255, 255, 255, 0.3);
  font-size: 14px;
}

/* 视频放大弹窗 */
.dialog-video-wrapper {
  width: 100%;
  aspect-ratio: 16 / 9;
  background: #0a1020;
  border-radius: 6px;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;

  :deep(.webrtc-wrapper),
  :deep(.video-player) {
    width: 100%;
    height: 100%;
  }
}

.dialog-no-stream {
  color: rgba(255, 255, 255, 0.3);
  font-size: 15px;
}

@media (max-width: 1200px) {
  .bs-charts { grid-template-columns: 1fr 1fr; }
  .monitor-grid { grid-template-columns: repeat(2, 1fr); }
}
</style>

<style lang="scss">
/* 视频弹窗全局暗色覆盖（dialog 渲染到 body，需非 scoped） */
.video-dialog {
  --el-dialog-bg-color: #0a1628;
  --el-dialog-border-radius: 10px;
  --el-border-color: rgba(82, 196, 26, 0.15);

  .el-dialog__header {
    padding: 16px 20px;
    border-bottom: 1px solid rgba(255, 255, 255, 0.06);
  }

  .el-dialog__title {
    color: rgba(255, 255, 255, 0.85);
    font-size: 16px;
    font-weight: 600;
  }

  .el-dialog__headerbtn .el-dialog__close {
    color: rgba(255, 255, 255, 0.4);
    font-size: 18px;

    &:hover {
      color: #52c41a;
    }
  }

  .el-dialog__body {
    padding: 16px 20px 20px;
  }
}

/* 大屏监控下拉框浮层 — popper-class 挂在 .el-popper 根元素上 */
.el-popper.monitor-select-popper {
  /* 浮层容器：暗色背景 + 深色边框，与选中框视觉一致 */
  &.is-light,
  &.is-dark {
    background-color: rgba(10, 22, 40, 0.96) !important;
    border-color: rgba(60, 80, 110, 0.4) !important;

    /* 小三角：背景和边框与浮层完全一致 */
    .el-popper__arrow::before {
      background-color: rgba(10, 22, 40, 0.96);
      border-color: rgba(60, 80, 110, 0.4);
    }
  }

  /* 下拉列表区域 */
  .el-select-dropdown {
    background: transparent !important;
  }

  /* 列表项文字 + hover / 选中态 */
  .el-select-dropdown__item {
    color: rgba(255, 255, 255, 0.75) !important;
  }

  .el-select-dropdown__item:hover,
  .el-select-dropdown__item.is-hovering {
    color: #fff !important;
    background: rgba(82, 196, 26, 0.15) !important;
  }

  .el-select-dropdown__item.is-selected {
    color: #52c41a !important;
    background: rgba(82, 196, 26, 0.12) !important;
    font-weight: 600;
  }
}
</style>
