<script setup lang="ts">
import type {
  ClassMonitorCurrent,
  ClassMonitorSessionRow,
  ClassMonitorSnapshot,
  ClassMonitorStudentSnapshot,
  ClassroomItem,
} from '../../../api/service/org/classroom-monitor'

import { computed, onBeforeUnmount, onMounted, reactive, ref } from 'vue'
import { useRouter } from 'vue-router'

import { classStudentService } from '../../../api/service/org/class-student'
import { classroomMonitorService } from '../../../api/service/org/classroom-monitor'
import hud from '../../../utils/hud'

const router = useRouter()

const classLoading = ref(false)
const detailLoading = ref(false)
const snapshotLoading = ref(false)
const controlLoading = ref(false)
const studentSnapshotLoading = ref(false)

const classList = ref<ClassroomItem[]>([])
const selectedClass = ref<ClassroomItem>()
const currentMonitor = ref<ClassMonitorCurrent>()
const snapshots = ref<ClassMonitorSnapshot[]>([])
const selectedSnapshotStudent = ref<ClassMonitorSnapshot>()
const studentSnapshots = ref<ClassMonitorStudentSnapshot[]>([])
const studentSnapshotDialogVisible = ref(false)

const sessionsDialogVisible = ref(false)
const sessionsLoading = ref(false)
const sessionsRows = ref<ClassMonitorSessionRow[]>([])
const sessionsPage = reactive({
  current: 1,
  size: 10,
  total: 0,
})

const isMonitoring = computed(() => currentMonitor.value?.monitoring === true)
const studentSnapshotPreviewList = computed(() => {
  return studentSnapshots.value.map((item) => item.url).filter(Boolean)
})
const SNAPSHOT_REFRESH_INTERVAL = 5000
const MONITOR_HEARTBEAT_INTERVAL = 60 * 1000
let snapshotRefreshTimer: ReturnType<typeof setInterval> | undefined
let heartbeatTimer: ReturnType<typeof setInterval> | undefined

onMounted(() => {
  loadClassList()
})

onBeforeUnmount(() => {
  stopSnapshotAutoRefresh()
  stopMonitorHeartbeat()
})

async function loadClassList() {
  classLoading.value = true
  try {
    classList.value = await classroomMonitorService.getClassList()
  } finally {
    classLoading.value = false
  }
}

async function handleViewMonitor(item: ClassroomItem) {
  stopSnapshotAutoRefresh()
  stopMonitorHeartbeat()
  selectedClass.value = item
  currentMonitor.value = undefined
  snapshots.value = []
  await loadMonitorDetail(item.id)
}

async function loadMonitorDetail(classId = selectedClass.value?.id) {
  if (!classId) return
  detailLoading.value = true
  try {
    const data = await classroomMonitorService.getCurrent(classId)
    currentMonitor.value = data
    if (data?.monitoring) {
      await loadSnapshots(classId)
      startSnapshotAutoRefresh()
      startMonitorHeartbeat()
    } else {
      stopSnapshotAutoRefresh()
      stopMonitorHeartbeat()
      snapshots.value = []
    }
  } finally {
    detailLoading.value = false
  }
}

async function loadSnapshots(classId = selectedClass.value?.id) {
  if (!classId) return
  snapshotLoading.value = true
  try {
    snapshots.value = await classroomMonitorService.getLatestSnapshots(classId)
  } finally {
    snapshotLoading.value = false
  }
}

async function openStudentSnapshots(item: ClassMonitorSnapshot) {
  if (!currentMonitor.value?.sessionId) {
    hud.error('暂无监控会话')
    return
  }
  selectedSnapshotStudent.value = item
  studentSnapshots.value = []
  studentSnapshotDialogVisible.value = true
  studentSnapshotLoading.value = true
  try {
    studentSnapshots.value = await classroomMonitorService.getStudentSnapshots(
      currentMonitor.value.sessionId,
      item.studentId,
    )
  } finally {
    studentSnapshotLoading.value = false
  }
}

function startSnapshotAutoRefresh() {
  if (snapshotRefreshTimer) return
  snapshotRefreshTimer = setInterval(() => {
    if (!isMonitoring.value || !selectedClass.value?.id) {
      stopSnapshotAutoRefresh()
      return
    }
    if (!snapshotLoading.value) {
      loadSnapshots(selectedClass.value.id)
    }
  }, SNAPSHOT_REFRESH_INTERVAL)
}

function startMonitorHeartbeat() {
  if (heartbeatTimer) return
  heartbeatTimer = setInterval(() => {
    if (!isMonitoring.value || !selectedClass.value?.id) {
      stopMonitorHeartbeat()
      return
    }
    void classroomMonitorService
      .heartbeat(selectedClass.value.id)
      .catch(() => undefined)
  }, MONITOR_HEARTBEAT_INTERVAL)
}

function stopSnapshotAutoRefresh() {
  if (!snapshotRefreshTimer) return
  clearInterval(snapshotRefreshTimer)
  snapshotRefreshTimer = undefined
}

function stopMonitorHeartbeat() {
  if (!heartbeatTimer) return
  clearInterval(heartbeatTimer)
  heartbeatTimer = undefined
}

async function updateMonitorStatus(status: 0 | 1) {
  if (!selectedClass.value?.id) return
  const option = status === 1 ? '开启' : '停止'
  controlLoading.value = true
  try {
    await classroomMonitorService.updateMonitorStatus(
      selectedClass.value.id,
      status,
    )
    hud.success(`${option}监控成功`)
    await loadMonitorDetail(selectedClass.value.id)
  } finally {
    controlLoading.value = false
  }
}

function backToClassList() {
  stopSnapshotAutoRefresh()
  stopMonitorHeartbeat()
  selectedClass.value = undefined
  currentMonitor.value = undefined
  snapshots.value = []
  studentSnapshotDialogVisible.value = false
  sessionsDialogVisible.value = false
}

function formatDurationSec(sec?: number | string) {
  if (sec === undefined || sec === null || sec === '') return '-'
  const n = Number(sec)
  if (Number.isNaN(n) || n < 0) return '-'
  const s = Math.floor(n)
  const m = Math.floor(s / 60)
  const rest = s % 60
  if (m === 0) return `${rest}秒`
  return `${m}分${rest}秒`
}

async function openHistoryMonitor() {
  if (!selectedClass.value?.id) return
  sessionsPage.current = 1
  sessionsDialogVisible.value = true
  await loadSessions()
}

async function loadSessions() {
  if (!selectedClass.value?.id) return
  sessionsLoading.value = true
  try {
    const data = await classroomMonitorService.getSessions(
      selectedClass.value.id,
      {
        current: sessionsPage.current,
        size: sessionsPage.size,
      },
    )
    sessionsRows.value = data?.rows ?? []
    sessionsPage.total = data?.totalRows ?? 0
  } finally {
    sessionsLoading.value = false
  }
}

function onSessionsSizeChange(size: number) {
  sessionsPage.size = size
  sessionsPage.current = 1
  loadSessions()
}

function onSessionsPageChange(p: number) {
  sessionsPage.current = p
  loadSessions()
}

function onSessionRowClick(row: ClassMonitorSessionRow) {
  if (!selectedClass.value) return
  sessionsDialogVisible.value = false
  router.push({
    path: `/org/classroom-monitor/session/${encodeURIComponent(String(row.sessionId))}`,
    query: {
      classId: String(selectedClass.value.id),
      className: selectedClass.value.name ?? '',
    },
  })
}

function formatTime(time?: number | string) {
  if (!time) return '-'
  const timestamp = Number(time)
  if (Number.isNaN(timestamp)) return String(time)
  const date = new Date(
    String(timestamp).length === 10 ? timestamp * 1000 : timestamp,
  )
  if (Number.isNaN(date.getTime())) return String(time)
  return date.toLocaleString()
}

/** teacher-electron 注入：打开独立屏幕共享窗口 */
async function openTeacherScreenShareWindow(item: ClassroomItem) {
  const api = window.teacherApi
  if (!api?.openScreenShareWindow) {
    hud.warning('请在教师端桌面客户端中使用「共享屏幕」')
    return
  }
  await hud.load({
    option: '准备共享屏幕',
    task: async () => {
      try {
        const page = await classStudentService.findPage(1, 999, {
          classId: item.id,
        })
        const rows = (page as any)?.data?.rows ?? page?.rows ?? []
        await api.openScreenShareWindow(rows, item.name ?? '')
      } catch (e) {
        console.error(e)
        throw e
      }
    },
    error: async () => {
      hud.error('打开屏幕共享窗口失败')
    },
  })
}

/** teacher-electron：学员 JPEG 截屏监控窗口 */
async function openStudentScreenMonitorWindow(item: ClassroomItem) {
  const openMon = window.teacherApi?.openStudentScreenMonitorWindow
  if (!openMon) {
    hud.warning('请在教师端桌面客户端中使用「屏幕监控」')
    return
  }
  await hud.load({
    option: '准备屏幕监控',
    task: async () => {
      try {
        const page = await classStudentService.findPage(1, 999, {
          classId: item.id,
        })
        const rows = (page as any)?.data?.rows ?? page?.rows ?? []
        await openMon(rows, item.name ?? '')
      } catch (e) {
        console.error(e)
        throw e
      }
    },
    error: async () => {
      hud.error('打开屏幕监控窗口失败')
    },
  })
}
</script>

<template>
  <div class="classroom-monitor g-container">
    <el-card v-if="!selectedClass" class="content-card" shadow="never">
      <template #header>
        <div class="card-header">
          <div>
            <div class="page-title">课堂监控</div>
            <div class="page-desc">请选择班级查看当前课堂监控。</div>
          </div>
          <div class="header-actions">
            <el-button
              :loading="classLoading"
              type="primary"
              @click="loadClassList"
            >
              刷新
            </el-button>
          </div>
        </div>
      </template>

      <div v-loading="classLoading" class="class-list">
        <div v-for="item in classList" :key="item.id" class="class-row">
          <div class="class-row-info">
            <span class="class-name">{{ item.name }}</span>
            <el-tag
              :type="item.monitorState === 1 ? 'success' : 'info'"
              size="small"
            >
              {{ item.monitorState === 1 ? '监控开启' : '监控关闭' }}
            </el-tag>
          </div>
          <div class="class-row-actions">
            <el-button
              type="primary"
              @click="openTeacherScreenShareWindow(item)"
            >
              共享屏幕
            </el-button>
            <el-button
              type="primary"
              @click="openStudentScreenMonitorWindow(item)"
            >
              屏幕监控
            </el-button>
            <el-button type="primary" @click="handleViewMonitor(item)">
              查看监控
            </el-button>
          </div>
        </div>

        <el-empty
          v-if="!classLoading && classList.length === 0"
          description="暂无班级"
        />
      </div>
    </el-card>

    <el-card v-else class="content-card" shadow="never">
      <template #header>
        <div class="card-header">
          <div>
            <div class="page-title">{{ selectedClass.name }}</div>
            <div class="page-desc">课堂监控详情</div>
          </div>
          <div class="header-actions">
            <el-button @click="backToClassList">返回班级列表</el-button>
            <el-button @click="openHistoryMonitor">历史监控</el-button>
            <el-button
              :loading="detailLoading || snapshotLoading"
              type="primary"
              @click="loadMonitorDetail()"
            >
              刷新监控
            </el-button>
          </div>
        </div>
      </template>

      <div v-loading="detailLoading" class="monitor-detail">
        <div class="status-panel">
          <div>
            <span class="status-label">当前状态</span>
            <el-tag :type="isMonitoring ? 'success' : 'info'" size="large">
              {{ isMonitoring ? '监控中' : '未开启' }}
            </el-tag>
          </div>
          <div v-if="currentMonitor?.startTime">
            <span class="status-label">开始时间</span>
            <strong>{{ currentMonitor.startTime }}</strong>
          </div>
          <div v-if="currentMonitor?.intervalMs">
            <span class="status-label">采集间隔</span>
            <strong>{{ currentMonitor.intervalMs }}ms</strong>
          </div>
          <el-button
            v-if="isMonitoring"
            :loading="controlLoading"
            type="danger"
            @click="updateMonitorStatus(0)"
          >
            停止监控
          </el-button>
          <el-button
            v-else
            :loading="controlLoading"
            type="primary"
            @click="updateMonitorStatus(1)"
          >
            开启监控
          </el-button>
        </div>

        <template v-if="isMonitoring">
          <div class="snapshot-header">
            <div class="section-title">学生监控信息</div>
            <el-button :loading="snapshotLoading" @click="loadSnapshots()">
              刷新截图
            </el-button>
          </div>

          <div v-loading="snapshotLoading" class="snapshot-grid">
            <el-card
              v-for="item in snapshots"
              :key="item.studentId"
              class="snapshot-card"
              shadow="hover"
              @click="openStudentSnapshots(item)"
            >
              <el-image
                v-if="item.latestUrl"
                class="snapshot-image"
                fit="cover"
                :src="item.latestUrl"
              />
              <div v-else class="snapshot-empty">暂无截图</div>

              <div class="student-info">
                <el-avatar :size="36" :src="item.avatar">
                  {{ item.studentName?.slice(0, 1) || '学' }}
                </el-avatar>
                <div>
                  <div class="student-name">{{ item.studentName || '-' }}</div>
                  <div class="student-meta">
                    最新时间：{{ formatTime(item.latestTs) }}
                  </div>
                  <div class="student-meta">
                    延迟：{{ item.staleSeconds ?? 0 }}秒
                  </div>
                </div>
              </div>
            </el-card>

            <el-empty
              v-if="!snapshotLoading && snapshots.length === 0"
              description="暂无学生监控信息"
            />
          </div>
        </template>
      </div>
    </el-card>

    <el-dialog
      v-model="sessionsDialogVisible"
      title="历史监控"
      width="960px"
      align-center
      destroy-on-close
    >
      <div v-loading="sessionsLoading">
        <el-table
          :data="sessionsRows"
          stripe
          highlight-current-row
          class="sessions-table"
          @row-click="onSessionRowClick"
        >
          <el-table-column prop="sessionId" label="会话 ID" width="100" />
          <el-table-column prop="teacherName" label="教师" min-width="110" />
          <el-table-column prop="startTime" label="开始时间" min-width="160" />
          <el-table-column prop="endTime" label="结束时间" min-width="160" />
          <el-table-column label="时长" width="110">
            <template #default="{ row }">
              {{ formatDurationSec(row.durationSec) }}
            </template>
          </el-table-column>
          <el-table-column prop="studentCount" label="学生数" width="88" />
          <el-table-column prop="snapshotCount" label="截图数" width="88" />
          <el-table-column prop="status" label="状态" width="80" />
          <el-table-column prop="intervalMs" label="采集间隔(ms)" width="120" />
          <el-table-column label="操作" width="88" fixed="right">
            <template #default="{ row }">
              <el-button
                type="primary"
                link
                @click.stop="onSessionRowClick(row)"
              >
                查看
              </el-button>
            </template>
          </el-table-column>
        </el-table>

        <div class="sessions-pagination">
          <el-pagination
            :current-page="sessionsPage.current"
            :page-size="sessionsPage.size"
            layout="total, sizes, prev, pager, next"
            :total="sessionsPage.total"
            :page-sizes="[10, 20, 50]"
            @current-change="onSessionsPageChange"
            @size-change="onSessionsSizeChange"
          />
        </div>
      </div>
    </el-dialog>

    <el-dialog
      v-model="studentSnapshotDialogVisible"
      :title="`${selectedSnapshotStudent?.studentName || '-'}的全部截图`"
      width="900px"
      align-center
      destroy-on-close
    >
      <div v-loading="studentSnapshotLoading" class="student-snapshot-dialog">
        <div class="student-snapshot-summary">
          <el-avatar :size="40" :src="selectedSnapshotStudent?.avatar">
            {{ selectedSnapshotStudent?.studentName?.slice(0, 1) || '学' }}
          </el-avatar>
          <div>
            <div class="student-name">
              {{ selectedSnapshotStudent?.studentName || '-' }}
            </div>
            <div class="student-meta">
              共 {{ studentSnapshots.length }} 张截图
            </div>
          </div>
        </div>

        <div v-if="studentSnapshots.length" class="student-snapshot-list">
          <div
            v-for="item in studentSnapshots"
            :key="`${item.ts}-${item.url}`"
            class="student-snapshot-item"
          >
            <el-image
              class="student-snapshot-image"
              fit="cover"
              :preview-src-list="studentSnapshotPreviewList"
              :src="item.url"
            />
            <div class="student-meta">截图时间：{{ formatTime(item.ts) }}</div>
          </div>
        </div>

        <el-empty v-else-if="!studentSnapshotLoading" description="暂无截图" />
      </div>
    </el-dialog>
  </div>
</template>

<style lang="scss" scoped>
.classroom-monitor {
  .content-card {
    min-height: 360px;
    border: 1px solid #edf0f5;
  }

  .card-header {
    display: flex;
    gap: 16px;
    align-items: center;
    justify-content: space-between;
  }

  .page-title {
    font-size: 20px;
    font-weight: 600;
    color: #1f2937;
  }

  .page-desc {
    margin-top: 6px;
    font-size: 14px;
    color: #6b7280;
  }

  .header-actions {
    display: flex;
    gap: 12px;
  }

  .class-list {
    min-height: 240px;
  }

  .class-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 16px 0;
    border-bottom: 1px solid #edf0f5;

    &:last-child {
      border-bottom: 0;
    }
  }

  .class-row-info {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    align-items: center;
    min-width: 0;
  }

  .class-row-actions {
    display: flex;
    flex-shrink: 0;
    gap: 12px;
    align-items: center;
  }

  .class-name {
    font-size: 16px;
    font-weight: 500;
    color: #111827;
  }

  .monitor-detail {
    min-height: 260px;
  }

  .status-panel {
    display: flex;
    gap: 24px;
    align-items: center;
    padding: 16px;
    margin-bottom: 18px;
    background: #f8fafc;
    border: 1px solid #edf0f5;
    border-radius: 8px;

    > div {
      display: flex;
      gap: 8px;
      align-items: center;
    }

    strong {
      font-weight: 600;
      color: #111827;
    }
  }

  .status-label {
    font-size: 14px;
    color: #6b7280;
  }

  .snapshot-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 16px;
  }

  .section-title {
    font-size: 16px;
    font-weight: 600;
    color: #111827;
  }

  .snapshot-grid {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 16px;
    min-height: 220px;
  }

  .snapshot-card {
    overflow: hidden;
    cursor: pointer;
    transition:
      border-color 0.2s,
      box-shadow 0.2s;

    &:hover {
      border-color: #409eff;
    }
  }

  .snapshot-image,
  .snapshot-empty {
    width: 100%;
    height: 180px;
    border-radius: 8px;
  }

  .snapshot-empty {
    display: flex;
    align-items: center;
    justify-content: center;
    color: #9ca3af;
    background: #f3f4f6;
  }

  .student-info {
    display: flex;
    gap: 10px;
    margin-top: 12px;
  }

  .student-name {
    font-weight: 600;
    color: #111827;
  }

  .student-meta {
    margin-top: 4px;
    font-size: 12px;
    color: #6b7280;
  }

  .student-snapshot-dialog {
    min-height: 240px;
  }

  .student-snapshot-summary {
    display: flex;
    gap: 12px;
    align-items: center;
    padding-bottom: 16px;
    margin-bottom: 16px;
    border-bottom: 1px solid #edf0f5;
  }

  .student-snapshot-list {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 16px;
    max-height: 620px;
    overflow-y: auto;
  }

  .student-snapshot-item {
    padding: 12px;
    border: 1px solid #edf0f5;
    border-radius: 8px;
  }

  .student-snapshot-image {
    width: 100%;
    height: 180px;
    border-radius: 8px;
  }

  .sessions-table {
    width: 100%;
    cursor: pointer;
  }

  .sessions-pagination {
    display: flex;
    justify-content: flex-end;
    margin-top: 16px;
  }
}

@media (max-width: 1400px) {
  .classroom-monitor {
    .snapshot-grid {
      grid-template-columns: repeat(3, minmax(0, 1fr));
    }

    .student-snapshot-list {
      grid-template-columns: repeat(2, minmax(0, 1fr));
    }
  }
}

@media (max-width: 1080px) {
  .classroom-monitor {
    .snapshot-grid {
      grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .status-panel {
      flex-direction: column;
      align-items: flex-start;
    }
  }
}

@media (max-width: 768px) {
  .classroom-monitor {
    .card-header,
    .class-row,
    .snapshot-header {
      flex-direction: column;
      align-items: stretch;
    }

    .header-actions {
      flex-direction: column;
    }

    .snapshot-grid {
      grid-template-columns: 1fr;
    }

    .student-snapshot-list {
      grid-template-columns: 1fr;
    }
  }
}
</style>
