<template>
  <div class="chat-container">
    <!-- 左侧工单列表 -->
    <div class="ticket-list">
      <div class="list-header">
        <el-input placeholder="搜索工单" v-model="searchKeyword" prefix-icon="Search" clearable @input="handleSearch" />
      </div>
      
      <div class="ticket-stats">
        <div class="stat-item" :class="{ active: activeStatus === '' }" @click="filterByStatus('')">
          全部 ({{ stats.total }})
        </div>
        <div class="stat-item" :class="{ active: activeStatus === 'pending' }" @click="filterByStatus('pending')">
          待处理 ({{ stats.pending }})
        </div>
        <div class="stat-item" :class="{ active: activeStatus === 'processing' }" @click="filterByStatus('processing')">
          处理中 ({{ stats.processing }})
        </div>
        <div class="stat-item" :class="{ active: activeStatus === 'replied' }" @click="filterByStatus('replied')">
          已回复 ({{ stats.replied }})
        </div>
        <div class="stat-item" :class="{ active: activeStatus === 'completed' }" @click="filterByStatus('completed')">
          已完成 ({{ stats.completed }})
        </div>
      </div>
      
      <div class="ticket-items" @scroll="handleScroll">
        <div
          v-for="ticket in filteredTickets"
          :key="ticket.id"
          class="ticket-item"
          :class="{ active: currentTicket && currentTicket.id === ticket.id }"
          @click="selectTicket(ticket)"
        >
          <div class="ticket-avatar">
            <el-avatar :size="40" :src="ticket.avatar">{{ ticket.username.charAt(0) }}</el-avatar>
          </div>
          <div class="ticket-content">
            <div class="ticket-top">
              <div class="ticket-name">{{ ticket.username }}</div>
              <div class="ticket-time">{{ formatTime(ticket.lastReplyTime || ticket.createTime) }}</div>
            </div>
            <div class="ticket-bottom">
              <div class="ticket-message">{{ ticket.title }}</div>
              <div class="ticket-badge" v-if="ticket.status === 'pending'">
                <el-badge value="新" type="danger" />
              </div>
            </div>
          </div>
        </div>
        <div v-if="isLoading" class="loading-more">
          <el-icon class="is-loading"><Loading /></el-icon>
          <span>加载中...</span>
        </div>
        <div v-if="!hasMore && ticketList.length > 0" class="no-more">
          没有更多工单了
        </div>
      </div>
    </div>
    
    <!-- 右侧聊天内容 -->
    <div class="chat-content" v-if="currentTicket">
      <div class="chat-header">
        <div class="ticket-info">
          <div class="ticket-title">{{ currentTicket.title }}</div>
          <div class="ticket-id">工单号: {{ currentTicket.id }}</div>
        </div>
        <div class="ticket-actions">
          <el-tag :type="getStatusType(currentTicket.status)" size="small">
            {{ getStatusText(currentTicket.status) }}
          </el-tag>
          <el-button
            v-if="currentTicket.status !== 'completed'"
            type="success"
            size="small"
            @click="handleComplete(currentTicket)"
          >
            结束工单
          </el-button>
        </div>
      </div>
      
      <div class="chat-messages" ref="messagesContainer">
        <div class="chat-date">{{ formatDate(currentTicket.createTime) }}</div>
        
        <!-- 显示加载中 -->
        <div v-if="isLoadingMessages" class="messages-loading">
          <el-icon class="is-loading"><Loading /></el-icon>
          <span>聊天记录加载中...</span>
        </div>
        
        <div
          v-else
          v-for="(message, index) in currentMessages"
          :key="index"
          :class="['message-item', message.isAdmin ? 'message-admin' : message.isSystem ? 'message-system' : 'message-user']"
        >
          <div class="message-avatar" v-if="!message.isAdmin && !message.isSystem">
            <el-avatar :size="36" :src="message.avatar">
              {{ message.userId === currentTicket.userId ? currentTicket.username.charAt(0) : 'U' }}
            </el-avatar>
          </div>
          <div class="message-content">
            <div class="message-text" v-if="message.content">
              {{ message.content }}
              <i class="el-icon-loading" v-if="message.isLoading"></i>
            </div>
            <div class="message-images" v-if="message.images && message.images.length">
              <img 
                v-for="(img, imgIndex) in message.images" 
                :key="imgIndex" 
                :src="img" 
                class="message-image" 
                @click="openImage(img)" 
              />
            </div>
            <div class="message-time">{{ formatMessageTime(message.time) }}</div>
          </div>
          <div class="message-avatar" v-if="message.isAdmin && !message.isSystem">
            <el-avatar :size="36" :src="message.avatar">A</el-avatar>
          </div>
        </div>
      </div>
      
      <div class="chat-input-container">
        <div class="upload-preview" v-if="selectedImages.length > 0">
          <div class="preview-item" v-for="(image, index) in selectedImages" :key="index">
            <img :src="image" alt="预览图片" />
            <div class="delete-preview" @click="removeImage(index)">×</div>
          </div>
        </div>
        
        <div class="quick-replies" v-if="currentTicket.status !== 'completed'">
          <el-button
            v-for="(reply, index) in quickReplies"
            :key="index"
            size="small"
            @click="useQuickReply(reply)"
          >
            {{ reply.title }}
          </el-button>
        </div>
        
        <div class="input-area">
          <el-input
            v-model="messageInput"
            :disabled="currentTicket.status === 'completed'"
            type="textarea"
            :rows="3"
            placeholder="请输入回复内容..."
            @keyup.ctrl.enter="sendMessage"
          />
          
          <div class="input-actions">
            <div class="left-actions">
              <el-upload
                action="#"
                :auto-upload="false"
                :show-file-list="false"
                :on-change="handleFileChange"
                multiple
                accept="image/*"
              >
                <el-button class="upload-btn" type="primary" plain icon="Plus" :disabled="currentTicket.status === 'completed'">
                  图片
                </el-button>
              </el-upload>
            </div>
            <span class="hint-text">Ctrl + Enter 发送</span>
            <el-button
              type="primary"
              :disabled="currentTicket.status === 'completed' || (!messageInput.trim() && selectedImages.length === 0)"
              @click="sendMessage"
            >
              发送
            </el-button>
          </div>
        </div>
      </div>
    </div>
    
    <!-- 未选择工单时的默认界面 -->
    <div class="chat-placeholder" v-else>
      <el-empty description="请选择一个工单进行处理" />
    </div>
    
    <!-- 图片查看器 -->
    <el-dialog v-model="imageViewerVisible" :show-close="true" width="auto" destroy-on-close class="image-viewer-dialog">
      <div class="image-viewer-container">
        <img :src="currentViewImage" class="viewer-image" />
      </div>
      <template #footer>
        <div class="image-viewer-footer">
          <el-button @click="imageViewerVisible = false">关闭</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, reactive, computed, onMounted, nextTick, watch, onBeforeUnmount, onActivated, onDeactivated } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Search, Plus, Loading } from '@element-plus/icons-vue'
import { useRoute, useRouter } from 'vue-router'
import { 
  getTickerList,
  getTicketDetail, 
  replyTicket, 
  closeTicket, 
  getUserAvatar,
  getFileImage,
  parseFilesToImages,
  getTicketCount
} from '@/api/ticket'
import notificationSound from '@/assets/7.wav'
import { useUserStore } from '@/store/userStore'

// 路由相关
const route = useRoute()
const router = useRouter()

// 用户 store
const userStore = useUserStore()

// 头像
const adminAvatar = ref('')
const userAvatar = ref('')

// 分页和加载更多
const currentPage = ref(1)
const pageSize = ref(10)
const isLoading = ref(false)
const hasMore = ref(true)

// 定时刷新的定时器
const refreshTimer = ref(null)
const refreshInterval = 5000 // 5秒刷新一次

// 页面可见性状态
const isPageVisible = ref(true)
// 当前路由路径，用于检测路由变化
const currentRoutePath = ref(route.path)

// 工单数据
const ticketList = ref([])
const currentTicket = ref(null)
const selectedTicketId = ref('')

// 消息输入
const messageInput = ref('')
const messagesContainer = ref(null)

// 图片相关
const selectedImages = ref([])
const imageViewerVisible = ref(false)
const currentViewImage = ref('')

// 搜索与过滤
const searchKeyword = ref('')
const activeStatus = ref('')

// 当前工单的消息列表
const currentMessages = ref([])
const isLoadingMessages = ref(false) // 添加消息加载状态

// 统计数据
const stats = reactive({
  pending: 0,
  processing: 0,
  replied: 0,
  completed: 0,
  total: 0,
  isLoadingStats: false
})

// 上一次的待处理数量，用于判断是否有新工单
const previousPendingCount = ref(0)
// 音频对象
const audio = new Audio(notificationSound)

// 快捷回复选项
const quickReplies = ref([
  { title: '您好，有什么可以帮助您的？', content: '您好，有什么可以帮助您的？' },
  { title: '正在处理中', content: '您的问题正在处理中，请稍等片刻，我们会尽快给您答复。' },
  { title: '需要更多信息', content: '为了更好地解决您的问题，请您提供更多相关信息。' },
  { title: '问题已解决', content: '您的问题已解决，感谢您的反馈。如有其他问题，请随时联系我们。' },
  { title: '稍后回复', content: '我们需要一些时间核实相关信息，稍后会给您详细回复。' }
])

// 处理图片上传
const handleFileChange = (file) => {
  if (!file) return
  
  // 使用FileReader读取文件为base64
  const reader = new FileReader()
  reader.onload = (e) => {
    selectedImages.value.push(e.target.result)
  }
  reader.readAsDataURL(file.raw)
}

// 移除选择的图片
const removeImage = (index) => {
  selectedImages.value.splice(index, 1)
}

// 查看大图
const openImage = (img) => {
  currentViewImage.value = img
  imageViewerVisible.value = true
}

// 获取工单列表
const fetchTicketList = async (append = false) => {
  if (isLoading.value) return
  
  try {
    isLoading.value = true
    // 使用当前选中的状态值
    let statusParam = ''
    if (activeStatus.value) {
      if (activeStatus.value === 'pending') statusParam = '0'
      else if (activeStatus.value === 'processing') statusParam = '1'
      else if (activeStatus.value === 'replied') statusParam = '2'
      else if (activeStatus.value === 'completed') statusParam = '3'
    }
    
    const res = await getTickerList(pageSize.value, currentPage.value, statusParam)
    
    if (res.code === 200) {
      const tickets = res.data.data || []
      
      // 转换API返回的数据到需要的格式
      const mappedTickets = tickets.map(item => ({
        id: item.work_id,
        title: item.name,
        username: item.user?.userName || `用户${item.user?.userId || 'Unknown'}`,
        userId: item.user?.userId,
        avatar: item.user?.coverUrl || '',
        createTime: new Date(item.created_at).toLocaleString(),
        lastReplyTime: new Date(item.update_time).toLocaleString(),
        status: convertStatusToString(item.status),
        content: item.name
      }))
      
      if (append) {
        // 翻页时：合并列表，使用work_id去重，然后按work_id从大到小排序
        const existingIds = new Set(ticketList.value.map(t => t.id))
        const newTickets = mappedTickets.filter(t => !existingIds.has(t.id))
        const mergedTickets = [...ticketList.value, ...newTickets]
        
        // 按work_id从大到小排序
        ticketList.value = mergedTickets.sort((a, b) => {
          const idA = typeof a.id === 'string' ? parseInt(a.id) || 0 : a.id
          const idB = typeof b.id === 'string' ? parseInt(b.id) || 0 : b.id
          return idB - idA
        })
      } else {
        // 首次加载或切换类别：直接使用新数据，按work_id从大到小排序
        ticketList.value = mappedTickets.sort((a, b) => {
          const idA = typeof a.id === 'string' ? parseInt(a.id) || 0 : a.id
          const idB = typeof b.id === 'string' ? parseInt(b.id) || 0 : b.id
          return idB - idA
        })
      }
      
      hasMore.value = ticketList.value.length < res.data.all_count
    } else {
      ElMessage.error(res.message || '获取工单列表失败')
    }
  } catch (error) {
    console.error('获取工单列表出错:', error)
    ElMessage.error('网络错误，请稍后重试')
  } finally {
    isLoading.value = false
  }
}

// 获取所有状态的工单数量
const fetchAllStats = async () => {
  stats.isLoadingStats = true
  try {
    const res = await getTicketCount()
    if (res.code === 200) {
      const data = res.data
      
      // 检查是否有新工单（待处理数量增加）
      if (data.wait_count > previousPendingCount.value && previousPendingCount.value !== 0) {
        try {
          audio.play().catch(e => console.error('播放提示音失败:', e))
        } catch (e) {
          console.error('播放提示音出错:', e)
        }
      }
      
      // 更新上一次的数量
      previousPendingCount.value = data.wait_count

      stats.total = data.all_count
      stats.pending = data.wait_count
      stats.replied = data.reply_count
      stats.completed = data.close_count
      // 计算处理中的数量：总数 - 待处理 - 已回复 - 已完成
      stats.processing = data.all_count - data.wait_count - data.reply_count - data.close_count
    } else {
      console.error('获取工单统计失败:', res.message)
    }
  } catch (error) {
    console.error('获取工单统计数据出错:', error)
  } finally {
    stats.isLoadingStats = false
  }
}

// 刷新统计数据（用于定时刷新）
const fetchCurrentStatusStat = async () => {
  await fetchAllStats()
}


// 加载更多工单
const loadMoreTickets = () => {
  if (!hasMore.value || isLoading.value) return
  
  currentPage.value++
  fetchTicketList(true)
}

// 状态码转换为字符串
const convertStatusToString = (status) => {
  const statusMap = {
    0: 'pending',
    1: 'processing',
    2: 'replied',
    3: 'completed'
  }
  return statusMap[status] || 'processing'
}

// 过滤后的工单列表
const filteredTickets = computed(() => {
  let result = [...ticketList.value]
  
  // 按状态过滤
  if (activeStatus.value) {
    result = result.filter(ticket => ticket.status === activeStatus.value)
  }
  
  // 按关键词搜索
  if (searchKeyword.value) {
    const keyword = searchKeyword.value.toLowerCase()
    result = result.filter(ticket => 
      ticket.title.toLowerCase().includes(keyword) || 
      ticket.username.toLowerCase().includes(keyword) || 
      String(ticket.id).toLowerCase().includes(keyword)
    )
  }
  
  // 按work_id从大到小排序（优先显示待处理）
  return result.sort((a, b) => {
    // 优先显示待处理
    if (a.status === 'pending' && b.status !== 'pending') return -1
    if (a.status !== 'pending' && b.status === 'pending') return 1
    
    // 然后按work_id从大到小排序
    const idA = typeof a.id === 'string' ? parseInt(a.id) || 0 : a.id
    const idB = typeof b.id === 'string' ? parseInt(b.id) || 0 : b.id
    return idB - idA
  })
})

// 判断是否是当前登录的管理员
const isAdmin = (userId) => {
  return userId === userStore.userInfo?.user_id
}

// 状态转换
const getStatusText = (status) => {
  const statusMap = {
    'pending': '待处理',
    'processing': '处理中',
    'replied': '已回复',
    'completed': '已完成'
  }
  return statusMap[status] || status
}

const getStatusType = (status) => {
  const typeMap = {
    'pending': 'warning',
    'processing': 'primary',
    'replied': 'info',
    'completed': 'success'
  }
  return typeMap[status] || ''
}

// 选择工单
const selectTicket = async (ticket) => {
  if (selectedTicketId.value === ticket.id && currentTicket.value) {
    return // 如果点击的是当前已选中工单，不做处理
  }
  
  currentTicket.value = ticket
  selectedTicketId.value = ticket.id
  
  // 获取工单的聊天记录
  await fetchTicketMessages(ticket.id)
  
  // 滚动到底部
  nextTick(() => {
    scrollToBottom()
  })
}

// 获取工单的聊天记录
const fetchTicketMessages = async (workId) => {
  try {
    isLoadingMessages.value = true // 设置消息加载状态为true
    currentMessages.value = [] // 清空当前消息列表
    
    const res = await getTicketDetail(workId)
    
    if (res.code === 200) {
      const detail = res.data
      
      // 更新当前工单信息，但不改变待处理状态
      if (currentTicket.value) {
        // 只有非待处理状态才直接更新，待处理状态保持不变，等待回复后再更新
        if (currentTicket.value.status !== 'pending') {
          currentTicket.value.status = convertStatusToString(detail.Status)
        }
      }
      
      // 处理消息列表
      if (detail.content && detail.content.length > 0) {
        // 处理所有消息
        const messages = detail.content.map((msg) => {
          const isAdminMsg = isAdmin(msg.user?.userId)
          // 从 flies 数组中提取图片 URL
          const images = msg.flies ? msg.flies.map(file => file.url) : []
          
          return {
            id: msg.id,
            content: msg.content !== 'empty' ? msg.content : null,
            images: images,
            time: msg.created_at || msg.updated_at || new Date().toLocaleString(),
            isAdmin: isAdminMsg,
            isSystem: false,
            userId: msg.user?.userId,
            avatar: msg.user?.coverUrl || ''
          }
        })
        
        currentMessages.value = messages
      }
    } else {
      ElMessage.error(res.message || '获取工单详情失败')
    }
  } catch (error) {
    console.error('获取工单详情出错:', error)
    ElMessage.error('网络错误，请稍后重试')
  } finally {
    isLoadingMessages.value = false // 设置消息加载状态为false
    isLoading.value = false
  }
}

// 发送消息
const sendMessage = async () => {
  if ((!messageInput.value.trim() && selectedImages.value.length === 0) || 
      !currentTicket.value || 
      currentTicket.value.status === 'completed') {
    return
  }
  
  const workId = currentTicket.value.id
  const content = messageInput.value.trim() || 'empty'
  
  // 这里需要处理上传图片，暂时用模拟数据
  // 实际情况中应该上传图片获取fileIds
  const fileIds = []
  
  try {
    // 保存输入内容
    const inputMsg = messageInput.value.trim()
    const inputImages = [...selectedImages.value]
    
    // 清空输入和已选图片
    messageInput.value = ''
    selectedImages.value = []
    
    // 立即添加消息到界面（不显示 loading）
    const tempMsg = {
      id: Date.now(), // 临时 ID
      content: inputMsg || null,
      images: inputImages.length > 0 ? inputImages : [],
      time: new Date().toLocaleString(),
      isAdmin: true,
      isSystem: false,
      userId: userStore.userInfo?.user_id,
      avatar: userStore.userInfo?.cover_url || '',
      isTempMessage: true
    }
    
    currentMessages.value.push(tempMsg)
    
    // 滚动到底部
    await nextTick()
    scrollToBottom()
    
    // 发送消息
    const res = await replyTicket(workId, content, fileIds.join(','))
    
    if (res.code === 200) {
      // 移除临时消息
      currentMessages.value = currentMessages.value.filter(msg => !msg.isTempMessage)
      
      // 重新获取消息列表，确保显示最新数据
      await fetchTicketMessages(workId)
      
      // 更新工单状态和最后回复时间
      if (currentTicket.value && currentTicket.value.status === 'pending') {
        currentTicket.value.status = 'processing'
        updateTicketStats()
      }
      
      currentTicket.value.lastReplyTime = new Date().toLocaleString()
    } else {
      // 移除临时消息
      currentMessages.value = currentMessages.value.filter(msg => !msg.isTempMessage)
      
      // 恢复输入内容
      messageInput.value = inputMsg
      selectedImages.value = inputImages
      
      ElMessage.error(res.message || '发送失败')
    }
  } catch (error) {
    console.error('发送消息出错:', error)
    ElMessage.error('网络错误，请稍后重试')
    
    // 移除临时消息
    currentMessages.value = currentMessages.value.filter(msg => !msg.isTempMessage)
  }
}

// 使用快捷回复
const useQuickReply = (reply) => {
  messageInput.value = reply.content
}

// 滚动聊天区域到底部
const scrollToBottom = () => {
  if (messagesContainer.value) {
    messagesContainer.value.scrollTop = messagesContainer.value.scrollHeight
  }
}

// 结束工单
const handleComplete = (ticket) => {
  ElMessageBox.confirm(
    '确定要结束此工单吗？结束后将无法继续回复。',
    '确认操作',
    {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    }
  )
    .then(async () => {
      try {
        const res = await closeTicket(ticket.id)
        
        if (res.code === 200) {
          ticket.status = 'completed'
          
          // 添加系统消息
          currentMessages.value.push({
            content: '工单已结束，感谢您的使用！',
            time: new Date().toLocaleString(),
            isAdmin: true,
            isSystem: true
          })
          
          // 更新统计
          updateTicketStats()
          
          ElMessage.success('工单已成功结束')
          
          // 滚动到底部
          nextTick(() => {
            scrollToBottom()
          })
        } else {
          ElMessage.error(res.message || '结束工单失败')
        }
      } catch (error) {
        console.error('结束工单出错:', error)
        ElMessage.error('网络错误，请稍后重试')
      }
    })
    .catch(() => {
      // 用户取消操作
    })
}

// 按状态过滤
const filterByStatus = (status) => {
  if (activeStatus.value === status) return; // 如果点击当前已选标签，不做处理
  
  activeStatus.value = status
  currentPage.value = 1 // 切换状态后重置页码
  hasMore.value = true // 重置加载更多标志
  ticketList.value = [] // 清空列表，不缓存
  fetchTicketList(false) // 从头重新获取数据，不追加
}

// 搜索处理
const handleSearch = () => {
  // 过滤已经由计算属性处理
}

// 更新工单统计
const updateTicketStats = () => {
  // 重新获取所有统计数据
  fetchAllStats()
}

// 格式化消息时间
const formatMessageTime = (timeStr) => {
  if (!timeStr) return ''
  
  try {
    const date = new Date(timeStr)
    if (isNaN(date.getTime())) return ''
    
    // 格式化为 HH:MM
    const hours = String(date.getHours()).padStart(2, '0')
    const minutes = String(date.getMinutes()).padStart(2, '0')
    return `${hours}:${minutes}`
  } catch (e) {
    console.error('时间格式化失败:', e)
    return ''
  }
}

// 格式化列表项时间
const formatTime = (timeStr) => {
  if (!timeStr) return ''; // 空值兜底

  // 步骤1：解析中文时间字符串（核心适配点）
  let date;
  try {
    // 先尝试原生解析（兼容ISO格式）
    date = new Date(timeStr);
    // 若原生解析失败（返回Invalid Date），解析中文格式
    if (isNaN(date.getTime())) {
      // 正则提取中文时间的年、月、日、时、分、秒
      const cnTimeMatch = timeStr.match(
        /(\d{4})年(\d{1,2})月(\d{1,2})日\s*(上午|下午)\s*(\d{1,2}):(\d{1,2}):(\d{1,2})/
      );
      if (cnTimeMatch) {
        const [, year, month, day, period, hour, minute, second] = cnTimeMatch;
        // 处理下午/上午的小时转换（12小时制转24小时制）
        let hour24 = parseInt(hour, 10);
        if (period === '下午' && hour24 !== 12) {
          hour24 += 12;
        }
        if (period === '上午' && hour24 === 12) {
          hour24 = 0; // 上午12点转为0点
        }
        // 构造日期（月份从0开始，需-1）
        date = new Date(
          parseInt(year, 10),
          parseInt(month, 10) - 1,
          parseInt(day, 10),
          hour24,
          parseInt(minute, 10),
          parseInt(second, 10)
        );
      } else {
        return '无效时间'; // 既不是ISO也不是中文格式
      }
    }
  } catch (e) {
    console.error('时间解析失败：', e);
    return '无效时间';
  }

  const now = new Date();
  const dateTime = date.getTime();
  const nowTime = now.getTime();
  const diff = nowTime - dateTime;

  // 步骤2：判断“今天”（年/月/日完全一致）
  const isToday = date.getFullYear() === now.getFullYear() &&
                  date.getMonth() === now.getMonth() &&
                  date.getDate() === now.getDate();
  
  if (isToday) {
    // 格式化今天的时间（24小时制，补零）
    const hour = String(date.getHours()).padStart(2, '0');
    const minute = String(date.getMinutes()).padStart(2, '0');
    return `${hour}:${minute}`;
  }

  // 步骤3：判断“一周内”
  const oneWeek = 7 * 24 * 60 * 60 * 1000;
  if (diff < oneWeek) {
    const weekdays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
    return weekdays[date.getDay()];
  }

  // 步骤4：格式化其他日期（补零，统一格式：YYYY/MM/DD）
  const year = date.getFullYear();
  const month = String(date.getMonth() + 1).padStart(2, '0');
  const day = String(date.getDate()).padStart(2, '0');
  return `${year}/${month}/${day}`;
};

// 格式化日期显示
const formatDate = (timeStr) => {
  console.log("原始时间字符串：", timeStr);
  if (!timeStr) return ''; // 空值兜底

  let date;
  // 1. 先尝试原生解析（兼容ISO等标准格式）
  date = new Date(timeStr);

  // 2. 若原生解析失败，专门解析中文时间格式
  if (isNaN(date.getTime())) {
    // 正则匹配：xxxx年xx月xx日 上午/下午 xx:xx:xx
    const cnTimeReg = /(\d{4})年(\d{1,2})月(\d{1,2})日\s*(上午|下午)\s*(\d{1,2}):(\d{1,2}):(\d{1,2})/;
    const match = timeStr.match(cnTimeReg);

    if (match) {
      const [, year, month, day, period, hour, minute, second] = match;
      // 处理12小时制转24小时制（关键适配）
      let hour24 = parseInt(hour, 10);
      if (period === '下午') {
        hour24 = hour24 === 12 ? 12 : hour24 + 12; // 下午12点=12点，下午1-11点+12
      } else { // 上午
        hour24 = hour24 === 12 ? 0 : hour24; // 上午12点=0点，上午1-11点不变
      }
      // 手动构造合法的Date对象（月份从0开始，需-1）
      date = new Date(
        parseInt(year, 10),
        parseInt(month, 10) - 1,
        parseInt(day, 10),
        hour24,
        parseInt(minute, 10),
        parseInt(second, 10)
      );
    } else {
      return '无效时间'; // 非目标格式，返回兜底
    }
  }

  const now = new Date();
  // 3. 对比“今天”（按日期维度，忽略时分秒）
  const isToday = date.getFullYear() === now.getFullYear() &&
                  date.getMonth() === now.getMonth() &&
                  date.getDate() === now.getDate();

  if (isToday) {
    return '今天';
  }

  // 4. 格式化非今天的日期（统一格式，避免环境差异）
  const formattedDate = `${date.getFullYear()}/${String(date.getMonth() + 1).padStart(2, '0')}/${String(date.getDate()).padStart(2, '0')}`;
 
  return formattedDate;
};

// 监听显示工单变化，更新消息和滚动
watch(currentTicket, (newVal) => {
  if (newVal) {
    nextTick(() => {
      scrollToBottom()
    })
  }
})

// 监听列表底部，加载更多
const handleScroll = (e) => {
  const element = e.target
  if (element.scrollHeight - element.scrollTop - element.clientHeight < 50 && hasMore.value && !isLoading.value) {
    loadMoreTickets()
  }
}

// 开始定时刷新
const startAutoRefresh = () => {
  // 避免创建多个定时器
  stopAutoRefresh()
  
  refreshTimer.value = setInterval(() => {
    // 检查页面可见性和路由是否还在当前页面
    if (!isPageVisible.value || route.path !== currentRoutePath.value) {
      return
    }
    
    // 如果当前有工单选中，则刷新聊天记录
    if (currentTicket.value && selectedTicketId.value) {
      // 静默刷新聊天记录，不显示loading状态
      refreshTicketMessages(selectedTicketId.value)
    }
    
    // 静默刷新工单列表，保持当前页码
    refreshTicketList()
    
    // 只刷新当前分类的统计数据，减少请求数量
    fetchCurrentStatusStat()
  }, refreshInterval)
}

// 停止定时刷新
const stopAutoRefresh = () => {
  if (refreshTimer.value) {
    clearInterval(refreshTimer.value)
    refreshTimer.value = null
  }
}

// 静默刷新工单列表（不显示loading状态）
const refreshTicketList = async () => {
  try {
    // 使用当前选中的状态值
    let statusParam = ''
    if (activeStatus.value) {
      if (activeStatus.value === 'pending') statusParam = '0'
      else if (activeStatus.value === 'processing') statusParam = '1'
      else if (activeStatus.value === 'replied') statusParam = '2'
      else if (activeStatus.value === 'completed') statusParam = '3'
    }
    
    // 刷新时只获取第一页数据，用于更新最新数据
    const res = await getTickerList(pageSize.value, 1, statusParam)
    
    if (res.code === 200) {
      const tickets = res.data.data || []
      
      // 转换API返回的数据到需要的格式
      const mappedTickets = tickets.map(item => ({
        id: item.work_id,
        title: item.name,
        username: item.user?.userName || `用户${item.user?.userId || 'Unknown'}`,
        userId: item.user?.userId,
        avatar: item.user?.coverUrl || '',
        createTime: new Date(item.created_at).toLocaleString(),
        lastReplyTime: new Date(item.update_time).toLocaleString(),
        status: convertStatusToString(item.status),
        content: item.name
      }))
      
      // 合并到现有列表，去重并按work_id从大到小排序
      // 使用Map来更新已存在的工单信息，添加新的工单
      const ticketMap = new Map()
      // 先添加现有列表
      ticketList.value.forEach(ticket => {
        ticketMap.set(ticket.id, ticket)
      })
      // 更新或添加新数据（新数据会覆盖旧数据）
      mappedTickets.forEach(ticket => {
        ticketMap.set(ticket.id, ticket)
      })
      
      // 转换为数组并按work_id从大到小排序
      ticketList.value = Array.from(ticketMap.values()).sort((a, b) => {
        const idA = typeof a.id === 'string' ? parseInt(a.id) || 0 : a.id
        const idB = typeof b.id === 'string' ? parseInt(b.id) || 0 : b.id
        return idB - idA
      })
      
      // 不重置页码，保持用户当前的浏览位置
      // 更新加载更多标志
      hasMore.value = ticketList.value.length < res.data.all_count
    }
  } catch (error) {
    console.error('刷新工单列表出错:', error)
  }
}

// 辅助函数：去除 URL 中的查询参数
const normalizeUrl = (url) => {
  if (!url) return ''
  return url.split('?')[0]
}

// 辅助函数：比较两个消息数组是否相同（忽略 URL 查询参数）
const areMessagesEqual = (messages1, messages2) => {
  if (messages1.length !== messages2.length) return false
  
  for (let i = 0; i < messages1.length; i++) {
    const msg1 = messages1[i]
    const msg2 = messages2[i]
    
    // 比较消息 ID 和内容
    if (msg1.id !== msg2.id || msg1.content !== msg2.content) return false
    
    // 比较图片数量
    if ((msg1.images?.length || 0) !== (msg2.images?.length || 0)) return false
    
    // 比较图片 URL（去除查询参数）
    if (msg1.images && msg2.images) {
      for (let j = 0; j < msg1.images.length; j++) {
        if (normalizeUrl(msg1.images[j]) !== normalizeUrl(msg2.images[j])) {
          return false
        }
      }
    }
  }
  
  return true
}

// 静默刷新聊天记录（不显示loading状态）
const refreshTicketMessages = async (workId) => {
  try {
    const res = await getTicketDetail(workId)
    
    if (res.code === 200) {
      const detail = res.data
      
      // 更新当前工单信息，但不改变待处理状态
      if (currentTicket.value) {
        // 只有非待处理状态才直接更新，待处理状态保持不变，等待回复后再更新
        if (currentTicket.value.status !== 'pending') {
          currentTicket.value.status = convertStatusToString(detail.status)
        }
      }
      
      // 处理消息列表
      if (detail.content && detail.content.length > 0) {
        // 构建新消息列表
        const newMessages = detail.content.map((msg) => {
          const isAdminMsg = isAdmin(msg.user?.userId)
          // 从 flies 数组中提取图片 URL
          const images = msg.flies ? msg.flies.map(file => file.url) : []
          
          return {
            id: msg.id,
            content: msg.content !== 'empty' ? msg.content : null,
            images: images,
            time: msg.created_at || msg.updated_at || new Date().toLocaleString(),
            isAdmin: isAdminMsg,
            isSystem: false,
            userId: msg.user?.userId,
            avatar: msg.user?.coverUrl || ''
          }
        })
        
        // 只有在消息真正发生变化时才更新（忽略 URL 查询参数的变化）
        if (!areMessagesEqual(currentMessages.value, newMessages)) {
          currentMessages.value = newMessages
          
          // 如果有新消息，滚动到底部
          nextTick(() => {
            scrollToBottom()
          })
        }
      }
    }
  } catch (error) {
    console.error('刷新聊天记录出错:', error)
  }
}

// 处理页面可见性变化
const handleVisibilityChange = () => {
  isPageVisible.value = !document.hidden
  
  if (isPageVisible.value && route.path === currentRoutePath.value) {
    // 页面变为可见且还在当前路由时，重新启动定时器
    startAutoRefresh()
  } else {
    // 页面不可见或路由已改变时，停止定时器
    stopAutoRefresh()
  }
}

// 监听路由变化
watch(() => route.path, (newPath, oldPath) => {
  if (newPath !== currentRoutePath.value) {
    // 路由已经离开当前页面，立即停止所有请求
    console.log('路由变化：从', oldPath, '到', newPath, '，停止工单数据请求')
    stopAutoRefresh()
    isPageVisible.value = false
  } else if (newPath === currentRoutePath.value) {
    // 路由返回到当前页面，重新启动请求
    console.log('路由返回到工单页面，重新启动数据请求')
    isPageVisible.value = true
    startAutoRefresh()
  }
}, { immediate: false })

onMounted(() => {
  // 记录当前路由路径
  currentRoutePath.value = route.path
  
  // 获取工单列表
  fetchTicketList()
  
  // 独立获取所有统计数据
  fetchAllStats()
  
  // 添加滚动监听
  const listElement = document.querySelector('.ticket-items')
  if (listElement) {
    listElement.addEventListener('scroll', handleScroll)
  }
  
  // 监听页面可见性变化
  document.addEventListener('visibilitychange', handleVisibilityChange)
  
  // 启动自动刷新
  startAutoRefresh()
})

onBeforeUnmount(() => {
  // 组件销毁前停止定时器
  stopAutoRefresh()
  
  // 移除滚动监听
  const listElement = document.querySelector('.ticket-items')
  if (listElement) {
    listElement.removeEventListener('scroll', handleScroll)
  }
  
  // 移除页面可见性监听
  document.removeEventListener('visibilitychange', handleVisibilityChange)
})

// 组件激活时（keep-alive场景）
onActivated(() => {
  console.log('组件激活，重新启动工单数据请求')
  currentRoutePath.value = route.path
  isPageVisible.value = true
  startAutoRefresh()
})

// 组件失活时（keep-alive场景）
onDeactivated(() => {
  console.log('组件失活，停止工单数据请求')
  isPageVisible.value = false
  stopAutoRefresh()
})
</script>

<style scoped>
.chat-container {
  display: flex;
  height: calc(100vh - 100px);
  background-color: #f7f7f7;
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 4px 20px 0 rgba(0, 0, 0, 0.08);
}

/* 左侧工单列表 */
.ticket-list {
  width: 320px;
  background-color: #fff;
  border-right: 1px solid #eaeaea;
  display: flex;
  flex-direction: column;
}

.list-header {
  padding: 16px;
  border-bottom: 1px solid #eaeaea;
  background-color: #fafafa;
}

.ticket-stats {
  display: flex;
  border-bottom: 1px solid #eaeaea;
  background-color: #f9f9f9;
  padding: 2px 0;
}

.stat-item {
  flex: 1;
  padding: 10px 4px;
  text-align: center;
  font-size: 13px;
  color: #606266;
  cursor: pointer;
  transition: all 0.3s;
  position: relative;
}

.stat-item:hover {
  color: #409EFF;
  background-color: rgba(64, 158, 255, 0.05);
}

.stat-item.active {
  color: #409EFF;
  font-weight: bold;
}

.stat-item.active:after {
  content: '';
  position: absolute;
  bottom: 0;
  left: 50%;
  transform: translateX(-50%);
  width: 40%;
  height: 3px;
  background-color: #409EFF;
  border-radius: 2px;
}

.ticket-items {
  flex: 1;
  overflow-y: auto;
  scrollbar-width: thin;
}

.ticket-items::-webkit-scrollbar {
  width: 4px;
}

.ticket-items::-webkit-scrollbar-thumb {
  background-color: rgba(0, 0, 0, 0.2);
  border-radius: 4px;
}

.ticket-item {
  display: flex;
  padding: 16px;
  border-bottom: 1px solid #f0f0f0;
  cursor: pointer;
  transition: all 0.3s;
}

.ticket-item:hover {
  background-color: #f5f7fa;
}

.ticket-item.active {
  background-color: #ecf5ff;
}

.ticket-avatar {
  margin-right: 12px;
}

.ticket-content {
  flex: 1;
  overflow: hidden;
}

.ticket-top {
  display: flex;
  justify-content: space-between;
  margin-bottom: 6px;
}

.ticket-name {
  font-weight: 500;
  color: #303133;
  font-size: 15px;
}

.ticket-time {
  color: #909399;
  font-size: 12px;
}

.ticket-bottom {
  display: flex;
  justify-content: space-between;
}

.ticket-message {
  color: #606266;
  font-size: 13px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 180px;
}

/* 右侧聊天内容 */
.chat-content, .chat-placeholder {
  flex: 1;
  display: flex;
  flex-direction: column;
  background-color: #f5f7fa;
}

.chat-placeholder {
  justify-content: center;
  align-items: center;
  background-color: #F1F1F1;
  background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4QceDiok7ULvrQAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAANElEQVQ4y2NgGAVDAHyz8v9TNujtnD9qIE0M/EcLA1FDKQ/+09LA0VAc4Ab+o6WBo2AIAQBbtS1tCcO9TAAAAABJRU5ErkJggg==');
}

.chat-header {
  padding: 16px 20px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  background-color: #fff;
  border-bottom: 1px solid #eaeaea;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.03);
}

.ticket-info {
  display: flex;
  flex-direction: column;
}

.ticket-title {
  font-size: 16px;
  font-weight: bold;
  color: #303133;
  margin-bottom: 4px;
}

.ticket-id {
  font-size: 12px;
  color: #909399;
}

.ticket-actions {
  display: flex;
  gap: 12px;
  align-items: center;
}

.chat-messages {
  flex: 1;
  overflow-y: auto;
  padding: 20px;
  background-color: #F1F1F1;
  background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4QceDiok7ULvrQAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAANElEQVQ4y2NgGAVDAHyz8v9TNujtnD9qIE0M/EcLA1FDKQ/+09LA0VAc4Ab+o6WBo2AIAQBbtS1tCcO9TAAAAABJRU5ErkJggg==');
  scrollbar-width: thin;
}

.chat-messages::-webkit-scrollbar {
  width: 6px;
}

.chat-messages::-webkit-scrollbar-thumb {
  background-color: rgba(0, 0, 0, 0.2);
  border-radius: 6px;
}

.chat-date {
  text-align: center;
  margin: 16px 0;
  color: #909399;
  font-size: 12px;
  background-color: rgba(245, 247, 250, 0.8);
  padding: 6px 16px;
  border-radius: 16px;
  display: inline-block;
  margin: 16px auto;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
}

.message-item {
  display: flex;
  margin-bottom: 24px;
  align-items: flex-start;
  animation: fadeIn 0.3s ease-in-out;
}

.message-user {
  justify-content: flex-start;
}

.message-admin {
  justify-content: flex-end;
}

.message-avatar {
  margin: 0 12px;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
  border-radius: 50%;
}

.message-content {
  max-width: 70%;
  border-radius: 4px;
  padding: 12px 16px;
  position: relative;
  word-break: break-word;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.06);
}

.message-images {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 8px 0;
}

.message-image {
  max-width: 200px;
  max-height: 150px;
  border-radius: 8px;
  cursor: pointer;
  transition: transform 0.2s, box-shadow 0.2s;
  object-fit: cover;
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
}

.message-image:hover {
  transform: scale(1.03);
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
}

.message-user .message-content {
  background-color: #fff;
  margin-right: auto;
  border-radius: 0px 12px 12px 12px;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
}

.message-user .message-content:before {
  content: '';
  position: absolute;
  top: 0;
  left: -8px;
  width: 0;
  height: 0;
  border-top: 8px solid #fff;
  border-left: 8px solid transparent;
}

.message-admin .message-content {
  background-color: #95ec69;
  margin-left: auto;
  border-radius: 12px 0px 12px 12px;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
}

.message-admin .message-content:before {
  content: '';
  position: absolute;
  top: 0;
  right: -8px;
  width: 0;
  height: 0;
  border-top: 8px solid #95ec69;
  border-right: 8px solid transparent;
}

.message-text {
  word-break: break-word;
  line-height: 1.6;
  font-size: 14px;
}

.message-time {
  text-align: right;
  font-size: 11px;
  color: #909399;
  margin-top: 6px;
}

.chat-input-container {
  padding: 16px 20px;
  background-color: #fff;
  border-top: 1px solid #eaeaea;
  box-shadow: 0 -2px 6px rgba(0, 0, 0, 0.03);
}

.upload-preview {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-bottom: 12px;
  padding: 10px;
  background-color: #f9f9f9;
  border-radius: 8px;
  border: 1px dashed #dcdfe6;
}

.preview-item {
  position: relative;
  width: 80px;
  height: 80px;
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  transition: transform 0.2s;
}

.preview-item:hover {
  transform: scale(1.05);
}

.preview-item img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.delete-preview {
  position: absolute;
  top: 4px;
  right: 4px;
  width: 20px;
  height: 20px;
  background-color: rgba(0, 0, 0, 0.6);
  color: #fff;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  font-size: 14px;
  transition: background-color 0.2s;
}

.delete-preview:hover {
  background-color: rgba(255, 0, 0, 0.7);
}

.quick-replies {
  margin-bottom: 12px;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.quick-replies .el-button {
  transition: all 0.3s;
}

.quick-replies .el-button:hover {
  transform: translateY(-2px);
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
}

.input-area {
  display: flex;
  flex-direction: column;
}

.input-area .el-textarea__inner {
  border-radius: 8px;
  padding: 12px 14px;
  resize: none;
  transition: all 0.3s;
  border: 1px solid #dcdfe6;
  font-size: 14px;
}

.input-area .el-textarea__inner:focus {
  border-color: #409EFF;
  box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2);
}

.input-actions {
  margin-top: 12px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.left-actions {
  display: flex;
  gap: 10px;
}

.upload-btn {
  margin-right: 10px;
  position: relative;
  overflow: hidden;
}

.upload-btn:hover {
  transform: translateY(-2px);
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
}

.hint-text {
  color: #909399;
  font-size: 12px;
  background-color: #f5f7fa;
  padding: 4px 10px;
  border-radius: 4px;
}

.input-actions .el-button {
  padding: 10px 20px;
  font-weight: 500;
  transition: all 0.3s ease;
}

.input-actions .el-button:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(64, 158, 255, 0.3);
}

/* 响应式调整 */
@media (max-width: 768px) {
  .chat-container {
    flex-direction: column;
    height: auto;
  }
  
  .ticket-list {
    width: 100%;
    height: 300px;
  }
  
  .chat-content, .chat-placeholder {
    height: calc(100vh - 400px);
  }
}

/* 图片查看器样式 */
:deep(.image-viewer-dialog .el-dialog__body) {
  padding: 0;
  background-color: rgba(0, 0, 0, 0.9);
  border-radius: 8px;
  overflow: hidden;
}

:deep(.image-viewer-dialog .el-dialog__header) {
  padding: 12px 20px;
  margin: 0;
  background-color: rgba(0, 0, 0, 0.9);
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}

:deep(.image-viewer-dialog .el-dialog__headerbtn .el-dialog__close) {
  color: #ffffff;
  font-size: 18px;
}

:deep(.image-viewer-dialog .el-dialog__footer) {
  padding: 12px 20px;
  margin: 0;
  background-color: rgba(0, 0, 0, 0.9);
  border-top: 1px solid rgba(255, 255, 255, 0.1);
}

.image-viewer-container {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 200px;
  max-height: 80vh;
  overflow: auto;
}

.viewer-image {
  max-width: 100%;
  max-height: 70vh;
  object-fit: contain;
  transition: transform 0.3s;
}

.image-viewer-footer {
  display: flex;
  justify-content: center;
}

/* 美化消息气泡 */
.message-user .message-content {
  position: relative;
  margin-left: 6px;
}

.message-admin .message-content {
  position: relative;
  margin-right: 6px;
}

/* 添加更多动画效果 */
@keyframes fadeIn {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* 美化工单状态标签 */
:deep(.el-tag) {
  padding: 4px 10px;
  font-weight: 500;
  border-radius: 12px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
  transition: all 0.3s;
}

:deep(.el-tag:hover) {
  transform: translateY(-2px);
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}

/* 美化输入框获取焦点效果 */
:deep(.el-input__inner:focus),
:deep(.el-textarea__inner:focus) {
  border-color: #409EFF;
  box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2);
}

/* 美化头像 */
:deep(.el-avatar) {
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
  border: 2px solid #fff;
  transition: all 0.3s;
}

.ticket-avatar :deep(.el-avatar) {
  background: linear-gradient(135deg, #42b983, #33a3dc);
}

.message-admin .message-avatar :deep(.el-avatar) {
  background: linear-gradient(135deg, #36d1dc, #5b86e5);
}

.message-user .message-avatar :deep(.el-avatar) {
  background: linear-gradient(135deg, #ff9a9e, #fad0c4);
}

/* 美化按钮效果 */
.ticket-actions :deep(.el-button) {
  transition: all 0.3s;
  border-radius: 6px;
}

.ticket-actions :deep(.el-button:hover) {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

/* 系统消息样式 */
.message-item.message-system {
  justify-content: center;
  margin: 16px 0;
}

.message-system .message-content {
  background-color: rgba(255, 255, 255, 0.7);
  padding: 6px 16px;
  border-radius: 16px;
  max-width: 60%;
  text-align: center;
  color: #606266;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
  border: 1px solid rgba(0, 0, 0, 0.05);
}

.message-system .message-time {
  text-align: center;
  margin-top: 4px;
}

/* 滚动条美化 */
.chat-container *::-webkit-scrollbar {
  width: 6px;
  height: 6px;
}

.chat-container *::-webkit-scrollbar-thumb {
  background-color: rgba(0, 0, 0, 0.2);
  border-radius: 6px;
}

.chat-container *::-webkit-scrollbar-track {
  background-color: rgba(0, 0, 0, 0.05);
  border-radius: 6px;
}

.loading-more, .no-more {
  text-align: center;
  padding: 10px;
  color: #909399;
  font-size: 12px;
}

.loading-more {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
}

/* 聊天记录加载中样式 */
.messages-loading {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 30px 0;
  color: #909399;
  font-size: 14px;
  flex-direction: column;
  gap: 10px;
  background-color: rgba(255, 255, 255, 0.7);
  border-radius: 8px;
  margin: 20px 0;
}

.messages-loading .el-icon {
  font-size: 24px;
  color: #409EFF;
}
</style> 