<script setup>
import {computed, nextTick, onMounted, ref, watch} from 'vue'
import {Bell, Check, CheckCheck, ChevronDown, MessageCircle, Search, Send, X} from 'lucide-vue-next'
import request from "@/utils/request.js";
import {ElMessage, ElNotification} from "element-plus";
import useUserStore from "@/store/modules/user.js";

const userStore = useUserStore()
const userId = computed(() => userStore.id)

// 响应式数据
const searchQuery = ref('')
const selectedCustomer = ref(null)
const newMessage = ref('')
const currentMessages = ref([]) // 当前选中客户的消息列表
const loadingMessages = ref(false) // 消息加载状态
const loadingMoreMessages = ref(false) // 加载更多消息状态
const hasMoreMessages = ref(true) // 是否还有更多消息
const currentPage = ref(1)
const pageSize = ref(20) // 每页消息数量

// 滚动相关的响应式数据
const messagesContainer = ref(null) // 消息容器的引用
const isUserScrolled = ref(false) // 用户是否手动滚动了
const newMessageCount = ref(0) // 新消息数量
const showNewMessageTip = ref(false) // 是否显示新消息提示
const lastMessageCount = ref(0) // 添加上次消息数量追踪

// 新增：通知相关
const hasNewCustomerMessage = ref(false) // 是否有新客户消息
const newCustomerCount = ref(0) // 新客户数量
const notificationPermission = ref(Notification.permission) // 浏览器通知权限

let heartbeatTimer = null
let ws = null

const BASE_WS_URL = import.meta.env.VITE_APP_BASE_WS_URL

// 客户数据结构（不包含messages字段）
const customers = ref([])

// 计算属性
const filteredCustomers = computed(() => {
  if (!searchQuery.value) {
    return customers.value
  }
  return customers.value.filter(customer =>
      customer.name.toLowerCase().includes(searchQuery.value.toLowerCase())
  )
})

// 新增：请求通知权限
const requestNotificationPermission = async () => {
  if ('Notification' in window && Notification.permission === 'default') {
    const permission = await Notification.requestPermission()
    notificationPermission.value = permission
  }
}

// 新增：显示浏览器通知
const showBrowserNotification = (title, body, icon = null) => {
  if (notificationPermission.value === 'granted') {
    const notification = new Notification(title, {
      body,
      icon: icon || '/logo.png',
      tag: 'chat-message' // 防止重复通知
    })

    // 点击通知时聚焦窗口
    notification.onclick = () => {
      window.focus()
      notification.close()
    }

    // 3秒后自动关闭
    setTimeout(() => notification.close(), 3000)
  }
}

// 新增：播放提示音
const playNotificationSound = () => {
  try {
    // 创建音频上下文播放提示音
    const audioContext = new (window.AudioContext || window.webkitAudioContext)()
    const oscillator = audioContext.createOscillator()
    const gainNode = audioContext.createGain()

    oscillator.connect(gainNode)
    gainNode.connect(audioContext.destination)

    oscillator.frequency.setValueAtTime(800, audioContext.currentTime)
    oscillator.frequency.setValueAtTime(600, audioContext.currentTime + 0.1)

    gainNode.gain.setValueAtTime(0.3, audioContext.currentTime)
    gainNode.gain.exponentialRampToValueAtTime(0.01, audioContext.currentTime + 0.3)

    oscillator.start(audioContext.currentTime)
    oscillator.stop(audioContext.currentTime + 0.3)
  } catch (error) {
    console.log('无法播放提示音:', error)
  }
}

// 新增：创建新客户记录
const createNewCustomer = (wsData) => {
  const newCustomer = {
    id: wsData.sessionId || wsData.from,
    name: wsData.from,
    isOnline: true,
    isTyping: false,
    lastMessage: wsData.content,
    lastMessageTime: formatTime(wsData.timestamp || new Date().toISOString()),
    unreadCount: 0,
    isNewCustomer: true // 标记为新客户
  }

  // 添加到客户列表顶部
  customers.value.unshift(newCustomer)

  console.log('[v0] 创建新客户:', newCustomer)
  return newCustomer
}

// 滚动到底部的方法
const scrollToBottom = (smooth = true) => {
  nextTick(() => {
    if (messagesContainer.value) {
      // 使用 scrollTop 以兼容性更好
      try {
        messagesContainer.value.scrollTo({
          top: messagesContainer.value.scrollHeight,
          behavior: smooth ? 'smooth' : 'auto'
        })
      } catch (e) {
        messagesContainer.value.scrollTop = messagesContainer.value.scrollHeight
      }
    }
  })
}

// 检查是否在底部 - 修复判断逻辑
const isAtBottom = () => {
  if (!messagesContainer.value) return true
  const { scrollTop, scrollHeight, clientHeight } = messagesContainer.value
  // 减少容差值，提高判断精度
  const atBottom = scrollHeight - scrollTop - clientHeight < 10
  console.log("[v0] 检查是否在底部:", atBottom, { scrollTop, scrollHeight, clientHeight })
  return atBottom
}

// 发送未读消息的已读回执
const markUnreadMessagesAsRead = () => {
  if (!selectedCustomer.value) return

  const unreadMessages = currentMessages.value.filter(msg =>
      msg.sender === 'customer' && msg.status !== 'read'
  )
  if (unreadMessages.length > 0) {

    const unreadMsgIds = unreadMessages.map(msg => msg.id)

    sendReadReceipt(selectedCustomer.value.id, unreadMsgIds)

    // 前端立即更新状态
    unreadMessages.forEach(msg => {
      msg.status = 'read'
    })

    console.log("[v0] 标记消息为已读:", unreadMsgIds)
  }
}

// 处理滚动事件 - 修复已读回执发送
const handleScroll = () => {
  if (!messagesContainer.value) return

  const atBottom = isAtBottom()

  if (atBottom) {
    isUserScrolled.value = false
    showNewMessageTip.value = false
    newMessageCount.value = 0

    // 当用户滑动到底部时，发送已读回执
    markUnreadMessagesAsRead()

    console.log("[v0] 用户回到底部，重置状态并发送已读回执")
  } else {
    isUserScrolled.value = true
    console.log("[v0] 用户滚动离开底部")
  }
}

// 回到底部按钮点击事件
const goToBottom = () => {
  console.log("[v0] 点击回到底部")
  scrollToBottom()
  showNewMessageTip.value = false
  newMessageCount.value = 0
  isUserScrolled.value = false

  // 发送已读回执
  markUnreadMessagesAsRead()
}

watch(currentMessages, (newMessages, oldMessages) => {
  console.log("[v0] 消息列表变化", {
    newCount: newMessages.length,
    oldCount: oldMessages?.length || 0,
    isUserScrolled: isUserScrolled.value
  })

  if (!oldMessages || oldMessages.length === 0) {
    // 初始加载消息时，直接滚动到底部
    console.log("[v0] 初始加载消息，滚动到底部")
    lastMessageCount.value = newMessages.length
    scrollToBottom(false)
    return
  }
  if (newMessages.length > oldMessages.length) {
    // 有新消息（从其他地方添加也会进来）
    const newMsgCount = newMessages.length - oldMessages.length
    console.log("[v0] 检测到新消息", newMsgCount, "条")

    if (isUserScrolled.value) {
      // 用户已滚动，显示新消息提示
      if(!loadingMoreMessages){
        newMessageCount.value += newMsgCount
        showNewMessageTip.value = true
      }
    } else {
      // 用户未滚动，自动滚动到底部
      console.log("[v0] 用户未滚动，自动滚动到底部")
      scrollToBottom()
    }
  }

  lastMessageCount.value = newMessages.length
}, {deep: true, immediate: false})

// 格式化时间
const formatTime = (createdAt) => {
  const date = new Date(createdAt)
  const now = new Date()
  const today = new Date(now.getFullYear(), now.getMonth(), now.getDate())
  const messageDate = new Date(date.getFullYear(), date.getMonth(), date.getDate())

  if (messageDate.getTime() === today.getTime()) {
    // 今天的消息只显示时间
    return date.toLocaleTimeString('zh-CN', {
      hour: '2-digit',
      minute: '2-digit'
    })
  } else {
    // 其他日期显示月日
    return date.toLocaleDateString('zh-CN', {
      month: '2-digit',
      day: '2-digit'
    })
  }
}

// 转换消息数据格式（用于 API 返回）- 修改为优先使用服务器messageId
const transformMessage = (apiMessage) => {
  return {
    // <CHANGE> 优先使用服务器返回的messageId，fallback到原有的id字段
    id: apiMessage.messageId || apiMessage.id,
    sessionId: apiMessage.sessionId,
    sender: apiMessage.fromRole === 'admin' ? 'agent' : 'customer',
    fromId: apiMessage.fromId,
    fromRole: apiMessage.fromRole,
    toId: apiMessage.toId,
    content: apiMessage.content,
    time: formatTime(apiMessage.createdAt),
    status: apiMessage.status,
    createdAt: apiMessage.createdAt
  }
}

// 如果 websocket 消息的字段不固定，尝试从多个字段取 sessionId
const resolveSessionId = (wsMsg) => {
  return wsMsg.sessionId ?? wsMsg.session ?? wsMsg.from ?? wsMsg.to ?? null
}

// 统一处理收到的 websocket 聊天消息（关键函数）- 修改为优先使用messageId
const handleIncomingMessage = async (wsData) => {
  console.log(wsData);
  console.log(formatTime(wsData.timestamp ?? new Date().toISOString()));
  try {
    // 构造前端消息对象（优先使用服务器字段）
    const msg = {
      // <CHANGE> 优先使用服务器返回的messageId，如果没有则使用id字段，最后才使用时间戳生成
      id: wsData.messageId || wsData.id || (Date.now() + Math.floor(Math.random() * 10000)),
      sessionId: resolveSessionId(wsData),
      sender: wsData.role === 'admin' ? 'agent' : 'customer',
      fromId: wsData.from,
      fromRole: wsData.role,
      toId: wsData.to,
      content: wsData.content,
      time: formatTime(wsData.timestamp ?? new Date().toISOString()),
      status: wsData.status ?? 'sent', // 默认为sent，而不是read
      // 格式化一下
      createdAt: formatTime(wsData.timestamp ?? new Date().toISOString())
    }

    // 判定是否属于当前选中会话（优先用 sessionId，再用 id/name 兜底）
    const belongToCurrent = selectedCustomer.value &&
        (
            (msg.sessionId != null && String(msg.sessionId) === String(selectedCustomer.value.id)) ||
            (String(msg.fromId) === String(selectedCustomer.value.name)) ||
            (String(msg.toId) === String(selectedCustomer.value.name))
        )

    // 找到目标会话
    let target = customers.value.find(c =>
        String(c.id) === String(msg.sessionId) ||
        String(c.name) === String(msg.fromId) ||
        String(c.name) === String(msg.toId)
    )

    // 新增：如果找不到目标客户且是客户发送的消息，创建新客户
    if (!target && msg.sender === 'customer') {
      target = createNewCustomer(wsData)

      // 显示新客户消息通知
      ElNotification({
        title: '新客户消息',
        message: `来自 ${wsData.from} 的消息：${wsData.content}`,
        type: 'info',
        duration: 5000,
        position: 'top-right'
      })

      // 浏览器通知
      showBrowserNotification(
          '新客户消息',
          `${wsData.from}: ${wsData.content}`
      )

      // 播放提示音
      playNotificationSound()

      // 更新新客户计数
      newCustomerCount.value += 1
      hasNewCustomerMessage.value = true

      console.log('[v0] 收到新客户消息，已创建客户记录并发送通知')
    }

    if (target) {
      target.lastMessage = msg.content
      target.lastMessageTime = msg.createdAt
      if (!belongToCurrent && msg.sender === 'customer') {
        // 只有在非当前会话才累加未读数
        target.unreadCount = (target.unreadCount || 0) + 1

        // 如果不是当前选中的客户，显示消息通知
        if (!belongToCurrent) {
          ElMessage({
            message: `${target.name} 发来新消息`,
            type: 'info',
            duration: 3000
          })

          // 浏览器通知（仅对现有客户的新消息）
          if (!target.isNewCustomer) {
            showBrowserNotification(
                `${target.name} 的新消息`,
                msg.content
            )
          }
        }
      }

      // 清除新客户标记
      if (target.isNewCustomer) {
        target.isNewCustomer = false
      }
    } else {
      console.warn('[v0] 收到属于未知会话的消息，sessionId:', msg.sessionId)
    }

    if (belongToCurrent) {
      // 添加到当前对话
      currentMessages.value.push(msg)

      // 等待 DOM 更新后决定滚动或显示提示
      await nextTick()

      // 检查用户是否在底部
      const userAtBottom = isAtBottom()

      if (userAtBottom) {
        scrollToBottom()
        showNewMessageTip.value = false
        newMessageCount.value = 0
        isUserScrolled.value = false

        // 如果是客户消息且用户在底部，立即发送已读回执
        if (msg.sender === 'customer') {
          sendReadReceipt(msg.sessionId, [msg.id])
          msg.status = 'read'
        }
      } else {
        // 用户不在底部，显示新消息提示
        newMessageCount.value += 1
        showNewMessageTip.value = true
        isUserScrolled.value = true
      }
    }

  } catch (e) {
    console.error('[v0] handleIncomingMessage 错误', e)
  }
}

// 新增：清除新客户消息提示
const clearNewCustomerNotification = () => {
  hasNewCustomerMessage.value = false
  newCustomerCount.value = 0
}

// 获取指定客户的消息列表（支持分页）
const getChatMessageListBySessionId = async (sessionId, pageNum = 1, isLoadMore = false) => {
  if (isLoadMore) {
    loadingMoreMessages.value = true
  } else {
    loadingMessages.value = true
  }

  try {
    const res = await request.get("chat/getChatMessageListBySessionId", {
      params: {
        sessionId: sessionId,
        pageNum: pageNum,
        pageSize: pageSize.value
      }
    })

    if (res.code !== 200) {
      ElMessage.error(res.msg);
      return { messages: [], total: 0 }
    }

    // 处理新的返回结构：{ messages: [], total: number }
    const responseData = res.data || {}
    const apiMessages = responseData.messages || []
    const total = responseData.total || 0

    // 转换消息格式
    const messages = apiMessages.map(transformMessage)

    // 检查是否还有更多消息 - 根据当前页数和总数计算
    const totalPages = Math.ceil(total / pageSize.value)
    hasMoreMessages.value = pageNum < totalPages

    return { messages, total }
  } catch (error) {
    ElMessage.error('获取消息失败');
    console.error('获取消息失败:', error)
    return { messages: [], total: 0 }
  } finally {
    if (isLoadMore) {
      loadingMoreMessages.value = false
    } else {
      loadingMessages.value = false
    }
  }
}

// 加载更多历史消息
const loadMoreMessages = async () => {
  if (!selectedCustomer.value || !hasMoreMessages.value || loadingMoreMessages.value) {
    return
  }

  // 加载下一页
  const nextPage = currentPage.value + 1

  const result = await getChatMessageListBySessionId(
      selectedCustomer.value.id,
      nextPage,
      true
  )

  if (result.messages.length > 0) {
    // 先反转新获取的消息，保持与初始加载时的处理逻辑一致
    const reversedMessages = [...result.messages].reverse()

    // 将反转后的历史消息添加到列表开头
    currentMessages.value = [...reversedMessages, ...currentMessages.value]
    // 更新当前页码
    currentPage.value = nextPage
  }
}

// 选择客户方法 - 修改为处理新的返回结构
const selectCustomer = async (customer) => {
  selectedCustomer.value = customer
  // 标记消息为已读
  customer.unreadCount = 0
  // 清除新客户标记
  if (customer.isNewCustomer) {
    customer.isNewCustomer = false
  }
  console.log('[v0] 选择客户:', customer.name)

  // 重置滚动状态
  isUserScrolled.value = false
  showNewMessageTip.value = false
  newMessageCount.value = 0

  // 重置分页状态
  hasMoreMessages.value = true
  currentPage.value = 1 // 重置页码为1

  // 获取该客户的最新消息列表（第一页）
  const result = await getChatMessageListBySessionId(customer.id, 1)
  currentMessages.value = result.messages

  // 消息列表需要反转，因为后端按时间降序返回，前端需要按时间升序显示
  currentMessages.value.reverse()

  // 确保滚到底部（立即）
  await nextTick()
  scrollToBottom(false)

  // 收集未读消息ID并发已读回执
  const unreadMsgIds = currentMessages.value
      .filter(m => m.sender === 'customer' && m.status !== 'read')
      .map(m => m.id)

  if (unreadMsgIds.length > 0) {
    sendReadReceipt(customer.id, unreadMsgIds)
    // 前端立即更新 UI
    currentMessages.value.forEach(m => {
      if (unreadMsgIds.includes(m.id)) m.status = 'read'
    })
  }
}

// 发送消息 - 修改为优先使用服务器返回的messageId
const sendMessage = async () => {
  if (!newMessage.value.trim() || !selectedCustomer.value) return

  // <CHANGE> 创建临时消息对象，等待服务器返回真实的messageId
  const tempMessage = {
    id: `temp_${Date.now()}`, // 临时ID，等待服务器返回真实messageId
    sessionId: selectedCustomer.value.id,
    sender: 'agent',
    fromRole: 'admin',
    content: newMessage.value.trim(),
    time: new Date().toLocaleTimeString('zh-CN', {
      hour: '2-digit',
      minute: '2-digit'
    }),
    status: 'sending', // 发送中状态
    createdAt: new Date().toISOString()
  }

  console.log("[v0] 发送消息，添加到消息列表")
  currentMessages.value.push(tempMessage)

  // 立刻滚动到底部，保证用户看到自己刚发的消息
  await nextTick()
  scrollToBottom()

  // 更新客户的最后消息信息
  selectedCustomer.value.lastMessage = tempMessage.content
  selectedCustomer.value.lastMessageTime = tempMessage.time

  console.log('[v0] 发送消息:', tempMessage)

  // 发送消息到服务器
  try {
    ws.send(JSON.stringify({
      from: userId.value,
      to: selectedCustomer.value.name,
      content: tempMessage.content,
      type: "chat",
      role: "admin"
    }))
    tempMessage.status = 'sent'
  } catch (error) {
    ElMessage.error('发送消息失败');
    console.error('发送消息失败:', error)
    tempMessage.status = 'failed'
  }

  newMessage.value = ''

  // 模拟消息状态更新（如果发送成功）
  if (tempMessage.status !== 'failed') {
    setTimeout(() => {
      tempMessage.status = 'read'
    }, 2000)
  }
}

//建立WS连接
const connectWs = async () => {
  const res = await request.get("chat/getToken")
  if (res.code !== 200) {
    ElMessage.error(res.msg);
    return
  }
  const token = res.data
  const customInfo = {
    token: token
  };
  const queryParams = new URLSearchParams();
  Object.entries(customInfo).forEach(([key, value]) => {
    queryParams.append(key, value);
  });
  const url = BASE_WS_URL + '?' + queryParams.toString();
  ws = new WebSocket(url)
  ws.onopen = () => {
    console.log('WS连接已建立')
    ws.send(JSON.stringify({from: userId.value, type: "login", role: "admin"}))
    // 启动心跳：每 30 秒发送一次
    heartbeatTimer = setInterval(() => {
      if (ws.readyState === WebSocket.OPEN) {
        ws.send(JSON.stringify({from: userId.value, type: "heartbeat", role: "admin"}))
      }
      //保持后台登录状态
      request.get("/getInfo")
    }, 30000)
  }
  ws.onclose = () => {
    if (heartbeatTimer) {
      clearInterval(heartbeatTimer)
      heartbeatTimer = null
    }
    ElMessage.info("连接已经关闭可能的原因如下：1.超时、2.服务器异常、3.网络问题、4.没有权限访问")
    console.log('WS连接已关闭')
  }

  ws.onmessage = (event) => {
    try {
      const data = JSON.parse(event.data)
      console.log('[v0] 收到WebSocket消息:', data)

      if (data.type === 'chat') {
        // 不再直接 push，而交给统一处理函数
        handleIncomingMessage(data)
      } else if (data.type === 'clientOnline') {
        // 处理客户上线消息 data.from 是上线用户ID
        console.log('[v0] 客户上线:', data.from)

        // 查找对应的客户并更新在线状态
        const customer = customers.value.find(c =>
            String(c.id) === String(data.from) ||
            String(c.name) === String(data.from)
        )

        if (customer) {
          customer.isOnline = true
          console.log('[v0] 已更新客户在线状态:', customer.name, '-> 在线')

          // 如果当前选中的就是这个客户，更新界面显示
          if (selectedCustomer.value &&
              (String(selectedCustomer.value.id) === String(data.from) ||
                  String(selectedCustomer.value.name) === String(data.from))) {
            selectedCustomer.value.isOnline = true
          }
        } else {
          console.warn('[v0] 收到未知客户的上线消息:', data.from)
        }

      } else if (data.type === 'clientOffline') {
        // 处理客户下线消息 data.from 是下线用户ID
        console.log('[v0] 客户下线:', data.from)

        // 查找对应的客户并更新在线状态
        const customer = customers.value.find(c =>
            String(c.id) === String(data.from) ||
            String(c.name) === String(data.from)
        )

        if (customer) {
          customer.isOnline = false
          customer.isTyping = false // 下线时清除输入状态
          console.log('[v0] 已更新客户在线状态:', customer.name, '-> 离线')

          // 如果当前选中的就是这个客户，更新界面显示
          if (selectedCustomer.value &&
              (String(selectedCustomer.value.id) === String(data.from) ||
                  String(selectedCustomer.value.name) === String(data.from))) {
            selectedCustomer.value.isOnline = false
            selectedCustomer.value.isTyping = false
          }
        } else {
          console.warn('[v0] 收到未知客户的下线消息:', data.from)
        }

      } else if (data.type === 'typing') {
        // 处理客户输入状态消息 data.from 是输入用户ID
        console.log('[v0] 客户输入中:', data.from)

        // 查找对应的客户并更新输入状态
        const customer = customers.value.find(c =>
            String(c.id) === String(data.from) ||
            String(c.name) === String(data.from)
        )

        if (customer) {
          customer.isTyping = true
          console.log('[v0] 已更新客户输入状态:', customer.name, '-> 正在输入')

          // 如果当前选中的就是这个客户，更新界面显示
          if (selectedCustomer.value &&
              (String(selectedCustomer.value.id) === String(data.from) ||
                  String(selectedCustomer.value.name) === String(data.from))) {
            selectedCustomer.value.isTyping = true
          }
        } else {
          console.warn('[v0] 收到未知客户的输入消息:', data.from)
        }

      } else if (data.type === 'typingStop') {
        // 处理客户输入状态消息 data.from 是输入用户ID
        console.log('[v0] 客户输入结束:', data.from)

        // 查找对应的客户并更新输入状态
        const customer = customers.value.find(c =>
            String(c.id) === String(data.from) ||
            String(c.name) === String(data.from)
        )

        if (customer) {
          customer.isTyping = false
          console.log('[v0] 已更新客户输入状态:', customer.name, '-> 输入结束')

          // 如果当前选中的就是这个客户，更新界面显示
          if (selectedCustomer.value &&
              (String(selectedCustomer.value.id) === String(data.from) ||
                  String(selectedCustomer.value.name) === String(data.from))) {
            selectedCustomer.value.isTyping = false
          }
        } else {
          console.warn('[v0] 收到未知客户的输入结束消息:', data.from)
        }

      } else {
        // 处理其他类型（login/status/typing/read 等），按需扩展
        console.log('[v0] 非 chat 类型消息:', data.type)
      }
    } catch (error) {
      console.error('解析WebSocket消息失败:', error)
    }
  }
}

const sendReadReceipt = (sessionId, messageIds, toId = null) => {

  if (!sessionId || !messageIds || messageIds.length === 0) return
  if (!ws || ws.readyState !== WebSocket.OPEN) return

  const payload = {
    type: 'read',
    role: 'admin',
    from: userId.value,
    to: toId,
    sessionId: sessionId,
    messageIds: messageIds
  }

  ws.send(JSON.stringify(payload))
  console.log('[v0] 已发送已读回执:', payload)
}

const getSessionList = async () => {
  const res = await request.get("chat/getSessionListByUserId", {
    params: {
      adminId: userId.value
    }
  })
  if (res.code !== 200) {
    ElMessage.error(res.msg);
    return
  }

  // 更新客户列表，不包含messages字段
  customers.value = res.data.map(item => {
    return {
      id: item.id,
      name: item.userId,
      isOnline: item.isOnline,
      isTyping: item.isTyping,
      lastMessage: item.lastMessage,
      lastMessageTime: item.lastMessageTime,
      unreadCount: item.unreadCount,
      isNewCustomer: false // 现有客户不是新客户
    }
  })
  console.log('客户列表:', customers.value);
}

// 生命周期
onMounted(() => {
  connectWs()
  getSessionList()
  // 请求通知权限
  requestNotificationPermission()
})
</script>

<template>
  <div class="h-[calc(100vh-6rem)] flex bg-gray-50">
    <div class="w-80 bg-white border-r border-gray-200 flex flex-col">
      <div class="p-4 border-b border-gray-200">
        <div class="flex items-center justify-between mb-3">
          <h2 class="text-lg font-semibold text-gray-900">客户列表</h2>
          <div v-if="hasNewCustomerMessage" class="flex items-center space-x-2">
            <Bell class="w-4 h-4 text-orange-500 animate-pulse"/>
            <span class="text-xs text-orange-600 font-medium">
              {{ newCustomerCount }} 个新客户
            </span>
            <button
                @click="clearNewCustomerNotification"
                class="text-xs text-gray-400 hover:text-gray-600"
            >
              ×
            </button>
          </div>
        </div>
        <el-input
            v-model="searchQuery"
            placeholder="搜索客户..."
            :prefix-icon="Search"
            clearable
        />
      </div>

      <div class="flex-1 overflow-y-auto">
        <div
            v-for="customer in filteredCustomers"
            :key="customer.id"
            @click="selectCustomer(customer)"
            :class="[
            'p-4 border-b border-gray-100 cursor-pointer hover:bg-gray-50 transition-colors relative',
            selectedCustomer?.id === customer.id ? 'bg-blue-50 border-blue-200' : '',
            customer.isNewCustomer ? 'bg-orange-50 border-orange-200' : ''
          ]"
        >
          <div v-if="customer.isNewCustomer" class="absolute top-2 right-2">
            <span
                class="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-orange-100 text-orange-800">
              新客户
            </span>
          </div>

          <div class="flex items-center justify-between">
            <div class="flex items-center space-x-3 flex-1 min-w-0">
              <div class="flex-shrink-0">
                <div
                    :class="[
                    'w-3 h-3 rounded-full',
                    customer.isOnline ? 'bg-green-500' : 'bg-gray-400'
                  ]"
                ></div>
              </div>

              <div class="flex-1 min-w-0">
                <div class="flex items-center justify-between">
                  <h3 class="text-sm font-medium text-gray-900 truncate">
                    {{ customer.name }}
                  </h3>
                  <span class="text-xs text-gray-500 flex-shrink-0 ml-2">
                    {{ customer.lastMessageTime }}
                  </span>
                </div>
                <p class="text-sm text-gray-500 truncate mt-1">
                  {{ customer.lastMessage }}
                </p>
              </div>
            </div>

            <div v-if="customer.unreadCount > 0" class="flex-shrink-0 ml-2">
              <span
                  :class="[
                  'inline-flex items-center justify-center w-5 h-5 text-xs font-medium text-white rounded-full',
                  customer.isNewCustomer ? 'bg-orange-500' : 'bg-red-500'
                ]">
                {{ customer.unreadCount }}
              </span>
            </div>
          </div>
        </div>
      </div>
    </div>

    <div class="flex-1 flex flex-col">
      <div v-if="selectedCustomer" class="flex flex-col h-full">
        <div class="p-4 bg-white border-b border-gray-200">
          <div class="flex items-center justify-between">
            <div class="flex items-center space-x-3">
              <div
                  :class="[
                  'w-3 h-3 rounded-full',
                  selectedCustomer.isOnline ? 'bg-green-500' : 'bg-gray-400'
                ]"
              ></div>
              <div>
                <h2 class="text-lg font-semibold text-gray-900">
                  {{ selectedCustomer.name }}
                  <span v-if="selectedCustomer.isNewCustomer"
                        class="ml-2 inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-orange-100 text-orange-800">
                    新客户
                  </span>
                </h2>
                <p class="text-sm text-gray-500">
                  {{ selectedCustomer.isOnline ? '在线' : '离线' }}
                  <span v-if="selectedCustomer.isTyping && selectedCustomer.isOnline">
                    · 正在输入...
                  </span>
                </p>
              </div>
            </div>
          </div>
        </div>

        <div
            ref="messagesContainer"
            class="flex-1 overflow-y-auto p-4 space-y-4 relative"
            @scroll="handleScroll"
        >
          <div v-if="hasMoreMessages && currentMessages.length > 0" class="flex justify-center">
            <el-button
                @click="loadMoreMessages"
                :loading="loadingMoreMessages"
                size="small"
                type="text"
            >
              {{ loadingMoreMessages ? '加载中...' : '加载更多历史消息' }}
            </el-button>
          </div>

          <div v-if="loadingMessages" class="flex justify-center items-center py-8">
            <span class="ml-2 text-gray-500">加载消息中...</span>
          </div>

          <div
              v-for="message in currentMessages"
              :key="message.id"
              :class="[
              'flex',
              message.sender === 'customer' ? 'justify-start' : 'justify-end'
            ]"
          >
            <div
                :class="[
                'max-w-[85%] sm:max-w-[55%] px-3 py-2 sm:px-4 sm:py-2.5 rounded-2xl text-sm sm:text-base break-words whitespace-pre-wrap leading-relaxed',
                message.sender === 'customer'
                  ? 'bg-gray-200 text-gray-900'
                  : 'bg-blue-500 text-white'
              ]"
            >
              <p class="text-sm">{{ message.content }}</p>
              <div class="flex items-center justify-between mt-1">
                <span class="text-xs opacity-70">{{ message.time }}</span>
                <div v-if="message.sender === 'agent'" class="flex items-center space-x-1 ml-2">
                  <Check
                      v-if="message.status === 'sent'"
                      class="w-3 h-3 opacity-70"
                  />
                  <CheckCheck
                      v-else-if="message.status === 'read'"
                      class="w-3 h-3 text-blue-200"
                  />
                  <X
                      v-else-if="message.status === 'failed'"
                      class="w-3 h-3 text-red-300"
                  />
                </div>
              </div>
            </div>
          </div>

          <div
              v-if="showNewMessageTip"
              class="fixed bottom-20 left-1/2 transform -translate-x-1/2 z-10"
          >
            <div
                @click="goToBottom"
                class="bg-blue-500 text-white px-4 py-2 rounded-full shadow-lg cursor-pointer hover:bg-blue-600 transition-colors flex items-center space-x-2"
            >
              <span class="text-sm">{{ newMessageCount }} 条新消息</span>
              <ChevronDown class="w-4 h-4"/>
            </div>
          </div>

          <div
              v-if="isUserScrolled && !showNewMessageTip"
              class="fixed bottom-20 right-8 z-10"
          >
            <div
                @click="goToBottom"
                class="bg-gray-500 text-white p-2 rounded-full shadow-lg cursor-pointer hover:bg-gray-600 transition-colors"
            >
              <ChevronDown class="w-5 h-5"/>
            </div>
          </div>
        </div>

        <div class="p-4 bg-white border-t border-gray-200">
          <div class="flex items-end space-x-2">
            <div class="flex-1">
              <el-input
                  v-model="newMessage"
                  type="textarea"
                  :rows="1"
                  placeholder="输入消息..."
                  @keydown.enter.prevent="sendMessage"
                  resize="none"
              />
            </div>
            <el-button
                type="primary"
                @click="sendMessage"
                :disabled="!newMessage.trim()"
                class="flex-shrink-0"
            >
              <Send class="w-4 h-4"/>
            </el-button>
          </div>
        </div>
      </div>

      <div v-else class="flex-1 flex items-center justify-center bg-gray-50">
        <div class="text-center">
          <MessageCircle class="w-16 h-16 text-gray-400 mx-auto mb-4"/>
          <h3 class="text-lg font-medium text-gray-900 mb-2">选择一个客户开始聊天</h3>
          <p class="text-gray-500">从左侧客户列表中选择一个客户来查看聊天记录</p>

          <div v-if="hasNewCustomerMessage" class="mt-4 p-4 bg-orange-50 rounded-lg border border-orange-200">
            <div class="flex items-center justify-center space-x-2 text-orange-600">
              <Bell class="w-5 h-5 animate-pulse"/>
              <span class="font-medium">有 {{ newCustomerCount }} 个新客户发来消息</span>
            </div>
            <p class="text-sm text-orange-500 mt-1">请查看左侧客户列表中的新客户</p>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped>
/* 自定义滚动条样式 */
::-webkit-scrollbar {
  width: 6px;
}

::-webkit-scrollbar-track {
  background: #f1f1f1;
}

::-webkit-scrollbar-thumb {
  background: #c1c1c1;
  border-radius: 3px;
}

::-webkit-scrollbar-thumb:hover {
  background: #a8a8a8;
}

/* 新增：新客户动画效果 */
@keyframes pulse {
  0%, 100% {
    opacity: 1;
  }
  50% {
    opacity: 0.5;
  }
}

.animate-pulse {
  animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
</style>