<template>
  <div class="call-number-display" ref="screenContainer">
    <!-- 头部区域 -->
    <div class="header">
      <h1>{{ departmentName }}</h1>
      <div class="header-right">
        <button class="fullscreen-btn" @click="toggleFullscreen">
          {{ isFullscreen ? '退出全屏' : '全屏' }}
        </button>
        <div class="time">{{ currentTime }}</div>
      </div>
    </div>
    
    <!-- 当前呼叫区 -->
    <div class="current-call">
      <div class="call-box">
        <div class="call-text">
          请 <span class="highlight">{{ currentCall?.number || '-' }}</span> 号 
          <span class="highlight">{{ currentCall?.name || '-' }}</span> 
          到 <span class="highlight">{{ currentCall?.room || '-' }}</span> 诊室就诊
        </div>
      </div>
    </div>
    
    <!-- 候诊信息区 -->
    <div class="waiting-area">
      <h2 class="section-title">候诊信息</h2>
      <div class="table-container" ref="tableContainer">
        <table class="waiting-table">
          <thead style="position: sticky; top: 0; background: #f0f7ff; z-index: 1;">
            <tr>
              <th>序号</th>
              <th>患者</th>
              <th>诊室</th>
              <th>状态</th>
            </tr>
          </thead>
          <tbody>
            <template v-for="doctorName in paginatedDoctors">
              <template v-if="groupedPatients[doctorName]">
                <!-- 医生分组标题 -->
                <tr class="doctor-header" :key="`doctor-${doctorName}`">
                  <td colspan="4">{{ doctorName }} 医生 (诊室: {{ getDoctorRoom(doctorName) }})</td>
                </tr>
                <!-- 患者列表 -->
                <tr v-for="(patient, index) in groupedPatients[doctorName]" :key="`${doctorName}-${patient.id}`">
                  <td>{{ index + 1 }}</td>
                  <td>{{ patient.name }}</td>
                  <td>{{ getDoctorRoom(doctorName) }}</td>
                  <td :style="{ color: patient.status === 'CALLING' ? '#e74c3c' : '#27ae60' }">
                    {{ patient.status === 'CALLING' ? '就诊中' : '等待' }}
                  </td>
                </tr>
              </template>
            </template>
          </tbody>
        </table>
      </div>
      
      <!-- 分页控制 -->
      <div class="pagination-controls">
        <button 
          id="prevPage" 
          @click="previousPage" 
          :disabled="currentPage === 1 || loading"
        >上一页</button>
        <span id="pageInfo">{{ currentPage }}/{{ totalPages }}</span>
        <button 
          id="nextPage" 
          @click="nextPage" 
          :disabled="currentPage === totalPages || loading"
        >下一页</button>
      </div>
    </div>
    
    <!-- 辅助信息区 -->
    <div class="info-bar">
      <div class="info-item">
        <span class="icon">⏱</span>
        <span>当前时间: {{ currentTime }}</span>
      </div>
      <div class="info-item">
        <span class="icon">🔢</span>
        <span>当前号: {{ currentCall?.number || '-' }}</span>
      </div>
      <div class="info-item">
        <span class="icon">👥</span>
        <span>等待人数: {{ waitingCount }}</span>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, reactive, computed, onMounted, onUnmounted, nextTick, watchEffect } from 'vue'
import { storeToRefs } from 'pinia'
import { ElMessage } from 'element-plus'
import dayjs from 'dayjs'
import request from '@/utils/request'
import useUserStore from '@/store/modules/user'

// ========== 配置参数 ==========
const userStore = useUserStore()
const { orgId: userOrgId, tenantId: userTenantId } = storeToRefs(userStore)

// 从登录用户获取科室ID（避免硬编码；后端已确保 orgId 以字符串返回）
const ORGANIZATION_ID = computed(() => (userOrgId.value ? String(userOrgId.value) : ''))
const TENANT_ID = computed(() => (userTenantId.value ? Number(userTenantId.value) : 1))
const API_BASE_URL = '/triage/queue'
// SSE 地址（走后端 API 代理）
const SSE_URL = computed(() => {
  const baseApi = import.meta.env.VITE_APP_BASE_API || ''
  const orgId = ORGANIZATION_ID.value
  const tenantId = TENANT_ID.value
  return `${baseApi}${API_BASE_URL}/display/stream?organizationId=${encodeURIComponent(orgId)}&tenantId=${tenantId}`
})

// 响应式数据
const currentTime = ref('')
const currentCall = ref(null)
const patients = ref([])
const loading = ref(false)
const currentPage = ref(1)
const patientsPerPage = 5
const autoScrollInterval = ref(null)
const scrollInterval = 5000 // 5秒自动翻页
const sseConnection = ref(null) // SSE 连接
const timeInterval = ref(null)
const isFullscreen = ref(false)
const screenContainer = ref(null)
let tableContainer = null

// 科室名称
const departmentName = ref('叫号显示屏幕')

const applyDefaultDepartmentName = () => {
  if (userStore.orgName) {
    departmentName.value = `${userStore.orgName} 叫号显示屏`
  }
}

// 等待总人数（从后端返回）
const waitingCount = ref(0)

// 计算属性：按医生分组的患者列表
const groupedPatients = computed(() => {
  const grouped = {}
  patients.value.forEach(doctorGroup => {
    grouped[doctorGroup.doctorName] = doctorGroup.patients || []
  })
  return grouped
})

// 获取排序后的医生列表
const sortedDoctors = computed(() => {
  return patients.value.map(group => group.doctorName)
})

// 按医生分组的分页逻辑
const paginatedDoctors = computed(() => {
  const startIndex = (currentPage.value - 1) * 1 // 每页显示1个医生组
  const endIndex = startIndex + 1
  return sortedDoctors.value.slice(startIndex, endIndex)
})

// 获取当前页的患者
const currentPatients = computed(() => {
  const result = {}
  paginatedDoctors.value.forEach(doctor => {
    result[doctor] = groupedPatients.value[doctor]
  })
  return result
})

const totalPages = computed(() => {
  return Math.ceil(sortedDoctors.value.length) || 1
})

// 方法
const updateTime = () => {
  const now = dayjs()
  currentTime.value = now.format('YYYY-MM-DD HH:mm')
}

const updateFullscreenState = () => {
  const isActive = !!document.fullscreenElement
  isFullscreen.value = isActive
  document.body.classList.toggle('call-screen-fullscreen', isActive)
}

const toggleFullscreen = async () => {
  try {
    if (document.fullscreenElement) {
      await document.exitFullscreen()
    } else if (screenContainer.value && screenContainer.value.requestFullscreen) {
      await screenContainer.value.requestFullscreen()
    }
  } catch (error) {
    console.error('切换全屏失败:', error)
  }
}

const formatPatientName = (name) => {
  if (!name || typeof name !== 'string') return '-'
  if (name.length === 0) return '-'
  return name.charAt(0) + '*' + name.slice(-1)
}

const getDoctorRoom = (doctorName) => {
  // 从后端数据中查找医生的诊室号
  const doctorGroup = patients.value.find(group => group.doctorName === doctorName)
  return doctorGroup?.roomNo || '1号'
}

const ensureUserInfo = async () => {
  if (!userStore.orgId) {
    try {
      await userStore.getInfo()
    } catch (error) {
      console.error('获取用户信息失败:', error)
    }
  }
  applyDefaultDepartmentName()
}

/**
 * 获取显示屏数据（从后端API）
 */
const fetchDisplayData = async () => {
  try {
    if (!ORGANIZATION_ID.value) {
      ElMessage.warning('未获取到登录用户科室信息')
      return
    }
    loading.value = true
    
    console.log('正在获取显示屏数据...', {
      url: `${API_BASE_URL}/display`,
      organizationId: ORGANIZATION_ID.value,
      tenantId: TENANT_ID.value
    })
    
    const response = await request({
      url: `${API_BASE_URL}/display`,
      method: 'get',
      params: {
        organizationId: ORGANIZATION_ID.value,
        tenantId: TENANT_ID.value
      }
    })
    
    console.log('后端响应：', response)
    
    if (response.code === 200 && response.data) {
      const data = response.data
      
      // 更新科室名称
      if (data.departmentName && data.departmentName !== '叫号显示屏') {
        departmentName.value = data.departmentName
      } else {
        applyDefaultDepartmentName()
      }
      
      // 更新当前叫号信息
      if (data.currentCall) {
        currentCall.value = data.currentCall
      } else {
        currentCall.value = {
          number: null,
          name: '-',
          room: '-',
          doctor: '-'
        }
      }
      
      // 更新等候队列（按医生分组）
      if (data.waitingList && Array.isArray(data.waitingList)) {
        patients.value = data.waitingList
        console.log('等候队列数据：', data.waitingList)
      } else {
        patients.value = []
        console.log('等候队列为空')
      }
      
      // 更新等待人数
      waitingCount.value = data.waitingCount || 0
      
      console.log('显示屏数据更新成功', data)
      ElMessage.success('数据加载成功')
    } else {
      throw new Error(response.msg || '获取数据失败')
    }
  } catch (error) {
    console.error('获取显示屏数据失败:', error)
    ElMessage.error('获取显示屏数据失败：' + (error.message || '未知错误'))
    
    // 出错时设置默认值
    patients.value = []
    currentCall.value = { number: null, name: '-', room: '-', doctor: '-' }
    waitingCount.value = 0
    applyDefaultDepartmentName()
  } finally {
    loading.value = false
  }
}

const previousPage = () => {
  if (currentPage.value > 1) {
    currentPage.value--
    scrollToTop()
  }
}

const nextPage = () => {
  if (currentPage.value < totalPages.value) {
    currentPage.value++
    scrollToTop()
  }
}

const scrollToTop = () => {
  nextTick(() => {
    const container = document.querySelector('.table-container')
    if (container && container.scrollTo) {
      container.scrollTo({
        top: 0,
        behavior: 'smooth'
      })
    }
  })
}

const startAutoScroll = () => {
  stopAutoScroll()
  autoScrollInterval.value = setInterval(() => {
    if (currentPage.value < totalPages.value) {
      currentPage.value++
    } else {
      currentPage.value = 1
    }
    scrollToTop()
  }, scrollInterval)
}

const stopAutoScroll = () => {
  if (autoScrollInterval.value) {
    clearInterval(autoScrollInterval.value)
    autoScrollInterval.value = null
  }
}

/**
 * 初始化 SSE 连接
 */
const initSse = () => {
  try {
    if (!ORGANIZATION_ID.value) {
      console.warn('未获取到科室ID，跳过 SSE 连接')
      return
    }
    if (sseConnection.value) {
      sseConnection.value.close()
    }
    console.log('正在连接 SSE:', SSE_URL.value)
    sseConnection.value = new EventSource(SSE_URL.value)
    
    sseConnection.value.onopen = () => {
      console.log('SSE 连接成功')
      ElMessage.success('实时连接已建立')
    }
    
    sseConnection.value.onmessage = (event) => {
      try {
        const message = JSON.parse(event.data)
        console.log('收到 SSE 消息:', message)
        
        if (message.type === 'init') {
          handleSseUpdate(message.data)
        } else if (message.type === 'update') {
          handleSseUpdate(message.data)
        }
      } catch (error) {
        console.error('解析 SSE 消息失败:', error)
      }
    }
    
    sseConnection.value.onerror = (error) => {
      console.error('SSE 错误:', error)
      ElMessage.error('实时连接出现错误')
    }
  } catch (error) {
    console.error('初始化 SSE 失败:', error)
  }
}

/**
 * 处理 SSE 推送的更新数据
 */
const handleSseUpdate = (data) => {
  if (!data) return
  
  // 更新科室名称
  if (data.departmentName) {
    departmentName.value = data.departmentName
  }
  
  // 更新当前叫号信息
  if (data.currentCall) {
    currentCall.value = data.currentCall
  }
  
  // 更新等候队列
  if (data.waitingList && Array.isArray(data.waitingList)) {
    patients.value = data.waitingList
  }
  
  // 更新等待人数
  if (data.waitingCount !== undefined) {
    waitingCount.value = data.waitingCount
  }
  
  console.log('显示屏数据已更新（来自 SSE）')
  
  // 播放语音（如果有新的叫号）
  if (data.currentCall && data.currentCall.number) {
    playVoiceNotification(data.currentCall)
  }
}

/**
 * 播放语音通知
 */
const playVoiceNotification = (callInfo) => {
  if (!callInfo || !callInfo.number) return
  
  try {
    // 使用 Web Speech API 播放语音
    const utterance = new SpeechSynthesisUtterance(
      `请${callInfo.number}号${callInfo.name}到${callInfo.room}诊室就诊`
    )
    utterance.lang = 'zh-CN'
    utterance.rate = 0.9 // 语速
    utterance.pitch = 1.0 // 音调
    utterance.volume = 1.0 // 音量
    
    window.speechSynthesis.speak(utterance)
  } catch (error) {
    console.error('语音播放失败:', error)
  }
}

/**
 * 关闭 SSE 连接
 */
const closeSse = () => {
  if (sseConnection.value) {
    sseConnection.value.close()
    sseConnection.value = null
    console.log('SSE 连接已关闭')
  }
}

// 生命周期钩子
onMounted(async () => {
  document.addEventListener('fullscreenchange', updateFullscreenState)
  await ensureUserInfo()
  // 初始化时间
  updateTime()
  // 每分钟更新时间
  timeInterval.value = setInterval(updateTime, 60000)
  
  // ✅ 获取初始数据（从后端 API）
  await fetchDisplayData()
  
  // ✅ 初始化 SSE 连接（实时推送）
  initSse()
  
  // 启动自动滚动
  startAutoScroll()
  
  // 鼠标悬停时暂停自动滚动
  tableContainer = document.querySelector('.table-container')
  if (tableContainer) {
    tableContainer.addEventListener('mouseenter', stopAutoScroll)
    tableContainer.addEventListener('mouseleave', startAutoScroll)
  }
})

onUnmounted(() => {
  // 组件卸载时的清理工作
  if (timeInterval.value) {
    clearInterval(timeInterval.value)
    timeInterval.value = null
  }
  stopAutoScroll()
  closeSse() // ✅ 关闭 SSE 连接
  if (tableContainer) {
    tableContainer.removeEventListener('mouseenter', stopAutoScroll)
    tableContainer.removeEventListener('mouseleave', startAutoScroll)
    tableContainer = null
  }
  document.removeEventListener('fullscreenchange', updateFullscreenState)
  document.body.classList.remove('call-screen-fullscreen')
})

// 监听页面变化，重置滚动位置
watchEffect(() => {
  scrollToTop()
})
</script>

<style lang="scss" scoped>
.call-number-display {
  width: 100%;
  max-width: 1200px;
  background-color: #fff;
  border-radius: 16px;
  box-shadow: 0 8px 30px rgba(0, 0, 0, 0.05);
  overflow: hidden;
  border: 1px solid #eaeaea;
  margin: 0 auto;
  padding: 20px;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

:global(body.call-screen-fullscreen) {
  overflow: hidden;
  background: #f5f7fa;
}

:global(body.call-screen-fullscreen .sidebar-wrapper),
:global(body.call-screen-fullscreen .navbar),
:global(body.call-screen-fullscreen .tags-view-container),
:global(body.call-screen-fullscreen #tags-view-container),
:global(body.call-screen-fullscreen .drawer-bg) {
  display: none !important;
}

:global(body.call-screen-fullscreen .app-wrapper),
:global(body.call-screen-fullscreen .main-wrapper),
:global(body.call-screen-fullscreen .content-wrapper),
:global(body.call-screen-fullscreen .app-main) {
  width: 100% !important;
  height: 100% !important;
  margin: 0 !important;
  padding: 0 !important;
}

:global(body.call-screen-fullscreen .app-wrapper) {
  height: 100vh !important;
}

:global(body.call-screen-fullscreen .call-number-display) {
  max-width: none;
  width: 100vw;
  height: 100vh;
  min-height: 100vh;
  margin: 0;
  border-radius: 0;
  box-shadow: none;
}

/* 头部样式 */
.header {
  background: linear-gradient(135deg, #4a90e2, #5fa3e8);
  color: white;
  padding: 20px 30px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-radius: 12px;
  margin-bottom: 20px;

  h1 {
    font-size: 2rem;
    font-weight: 600;
    letter-spacing: 1px;
    margin: 0;
  }

  .time {
    font-size: 1.5rem;
    font-weight: 500;
    background: rgba(255, 255, 255, 0.2);
    padding: 5px 15px;
    border-radius: 30px;
  }

  .header-right {
    display: flex;
    align-items: center;
    gap: 12px;
  }

  .fullscreen-btn {
    border: 1px solid rgba(255, 255, 255, 0.6);
    background: rgba(255, 255, 255, 0.15);
    color: #fff;
    padding: 6px 14px;
    border-radius: 20px;
    font-size: 14px;
    cursor: pointer;
    transition: background 0.2s ease, border-color 0.2s ease;
  }

  .fullscreen-btn:hover {
    background: rgba(255, 255, 255, 0.28);
    border-color: rgba(255, 255, 255, 0.9);
  }
}

/* 当前呼叫区 */
.current-call {
  text-align: center;
  background: #f8f9fa;
  padding: 20px;
  border-radius: 12px;
  margin-bottom: 20px;

  .call-box {
    max-width: 800px;
    margin: 0 auto;
    padding: 20px;
    background: white;
    border-radius: 12px;
    box-shadow: 0 5px 20px rgba(74, 144, 226, 0.15);
    border: 1px solid #e0e7ff;
    animation: pulse 2s infinite;

    .call-text {
      font-size: 2.2rem;
      font-weight: 700;
      color: #4a90e2;
      letter-spacing: 2px;
    }
  }
}

/* 候诊信息区 */
.waiting-area {
  flex: 1;
  padding: 0;
  margin-bottom: 20px;

  .section-title {
    font-size: 1.4rem;
    color: #555;
    margin-bottom: 20px;
    padding-left: 10px;
    border-left: 4px solid #4a90e2;
    font-weight: 600;
  }

  .table-container {
    max-height: 400px;
    overflow-y: auto;
    scroll-behavior: smooth;
    border-radius: 10px;
    border: 1px solid #eaeaea;
  }

  .waiting-table {
    width: 100%;
    border-collapse: collapse;
    background: white;

    th,
    .doctor-header td {
      background-color: #f0f7ff;
      color: #4a90e2;
      font-weight: 600;
      text-align: left;
      padding: 15px 20px;
      font-size: 1.1rem;
    }

    td {
      padding: 15px 20px;
      border-bottom: 1px solid #f0f0f0;
      font-size: 1.05rem;
    }

    tr:nth-child(even) {
      background-color: #fafcff;
    }

    tr:hover {
      background-color: #f0f7ff;
    }

    .doctor-header {
      background-color: #f0f7ff !important;
      font-weight: bold;
    }
  }

  .pagination-controls {
    display: flex;
    justify-content: center;
    margin-top: 15px;
    gap: 10px;

    button {
      padding: 8px 16px;
      border: 1px solid #eaeaea;
      border-radius: 4px;
      background: #f8f9fa;
      cursor: pointer;
      font-size: 14px;
      transition: all 0.3s;

      &:hover:not(:disabled) {
        background: #e9ecef;
        border-color: #4a90e2;
      }

      &:disabled {
        opacity: 0.5;
        cursor: not-allowed;
      }
    }

    span {
      padding: 8px 16px;
      background: #f8f9fa;
      border-radius: 4px;
      font-weight: 500;
    }
  }
}

/* 辅助信息区 */
.info-bar {
  background: #2c3e50;
  color: white;
  padding: 15px 20px;
  display: flex;
  justify-content: space-between;
  border-radius: 12px;

  .info-item {
    display: flex;
    align-items: center;
    font-size: 1.1rem;

    .icon {
      margin-right: 8px;
    }

    span {
      margin-left: 10px;
      font-weight: 500;
    }
  }
}

/* 动画效果 */
@keyframes pulse {
  0% {
    box-shadow: 0 0 0 0 rgba(74, 144, 226, 0.4);
  }
  70% {
    box-shadow: 0 0 0 15px rgba(74, 144, 226, 0);
  }
  100% {
    box-shadow: 0 0 0 0 rgba(74, 144, 226, 0);
  }
}

.highlight {
  color: #e74c3c;
  font-weight: bold;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .call-number-display {
    padding: 10px;
    margin: 0;
  }

  .header {
    flex-direction: column;
    text-align: center;
    gap: 10px;
    padding: 15px 20px;

    h1 {
      font-size: 1.5rem;
    }

    .time {
      font-size: 1.2rem;
    }
  }

  .current-call {
    padding: 15px;

    .call-box {
      padding: 15px;

      .call-text {
        font-size: 1.8rem;
      }
    }
  }

  .info-bar {
    flex-direction: column;
    gap: 10px;
    text-align: center;

    .info-item {
      justify-content: center;
    }
  }

  .waiting-table {
    th, td {
      padding: 10px 15px;
      font-size: 0.9rem;
    }
  }
}

@media (max-width: 480px) {
  .header h1 {
    font-size: 1.2rem;
  }

  .current-call .call-box .call-text {
    font-size: 1.5rem;
    letter-spacing: 1px;
  }

  .waiting-table th,
  .waiting-table td {
    padding: 8px 12px;
    font-size: 0.8rem;
  }
}
</style>