<template>
  <div class="chat-container">
    <el-card class="chat-card">
      <div class="chat-header">
        <h2>聊天室</h2>
      </div>
      
      <div class="chat-content">
        <div class="chat-sidebar">
          <!-- 联系人列表 -->
          <el-input
            v-model="searchKeyword"
            placeholder="搜索联系人"
            prefix-icon="Search"
            clearable
            @input="filterContacts"
          />
          
          <el-scrollbar height="calc(100vh - 240px)" class="contacts-scrollbar">
            <div
              v-for="(contact, index) in filteredContacts"
              :key="index"
              class="contact-item"
              :class="{ 'contact-item-active': currentContact?.contactId === contact.contactId }"
              @click="selectContact(contact)"
            >
              <el-avatar :size="40" :src="contact.contactAvatar || defaultAvatar">
                {{ contact.contactName?.charAt(0) }}
              </el-avatar>
              <div class="contact-info">
                <div class="contact-name">{{ contact.contactName }}</div>
                <div class="contact-message" v-if="contact.lastMessage">
                  {{ contact.lastMessage.content?.substring(0, 15) }}{{ contact.lastMessage.content?.length > 15 ? '...' : '' }}
                </div>
              </div>
              <el-badge v-if="contact.unreadCount > 0" :value="contact.unreadCount" class="unread-badge" />
            </div>
            <div v-if="filteredContacts.length === 0" class="no-contacts">
              暂无联系人
            </div>
          </el-scrollbar>
        </div>
        
        <div class="chat-main">
          <!-- 聊天窗口 -->
          <div v-if="currentContact" class="chat-box">
            <div class="chat-title">
              {{ currentContact.contactName }}
              <span class="contact-role">({{ currentContact.contactType === 'doctor' ? '医生' : '患者' }})</span>
            </div>
            
            <el-scrollbar ref="messagesScrollbar" height="calc(100vh - 350px)" class="messages-scrollbar">
              <div class="messages-container">
                <div v-if="messages.length === 0" class="no-messages">
                  暂无消息记录，开始聊天吧
                </div>
                <template v-else>
                  <div
                    v-for="(message, index) in messages"
                    :key="index"
                    class="message-item"
                    :class="{ 'message-self': message.senderId === user.id && message.senderType === user.role }"
                  >
                    <el-avatar 
                      :size="36" 
                      :src="message.senderId === user.id && message.senderType === user.role ? user.avatar : currentContact.contactAvatar || defaultAvatar"
                    >
                      {{ (message.senderId === user.id && message.senderType === user.role ? user.name : currentContact.contactName)?.charAt(0) }}
                    </el-avatar>
                    <div class="message-content">
                      <div class="message-sender">
                        {{ message.senderId === user.id && message.senderType === user.role ? '我' : message.senderName || currentContact.contactName }}
                        <span class="message-time">{{ formatTime(message.sendTime) }}</span>
                      </div>
                      <div class="message-text">{{ message.content }}</div>
                    </div>
                  </div>
                </template>
              </div>
            </el-scrollbar>
            
            <div class="message-input">
              <div class="message-input-wrapper">
                <el-input
                  v-model="messageText"
                  type="textarea"
                  :rows="3"
                  placeholder="请输入消息..."
                  @keyup.enter.ctrl="sendMessage"
                  class="message-textarea"
                ></el-input>
                <div class="send-button-container">
                  <el-button 
                    type="primary" 
                    :disabled="!messageText.trim()" 
                    @click="sendMessage" 
                    class="send-button"
                    round
                  >
                    <el-icon class="send-icon"><ChatDotRound /></el-icon>
                    发送
                  </el-button>
                </div>
              </div>
              <div class="input-actions">
                <span class="hint">按Ctrl+Enter发送</span>
              </div>
            </div>
          </div>
          
          <div v-else class="no-contact-selected">
            <el-empty description="请选择一个联系人开始聊天"></el-empty>
          </div>
        </div>
      </div>
    </el-card>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted, onBeforeUnmount, nextTick, watch, computed } from 'vue';
import { ElMessage } from 'element-plus';
import request from '@/utils/request';
import { Search, ChatDotRound } from '@element-plus/icons-vue';

// 当前用户
const user = reactive(JSON.parse(localStorage.getItem('xm-user') || '{}'));
const defaultAvatar = ''; // 默认头像

// 联系人列表
const contacts = ref([]);
const filteredContacts = ref([]);
const searchKeyword = ref('');
const currentContact = ref(null);

// 消息列表
const messages = ref([]);
const messageText = ref('');
const messagesScrollbar = ref(null);

// WebSocket
let ws = null;

// 格式化时间
const formatTime = (timeStr) => {
  if (!timeStr) return '';
  const date = new Date(timeStr);
  return date.toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' });
};

// 过滤联系人
const filterContacts = () => {
  if (!searchKeyword.value) {
    filteredContacts.value = contacts.value;
    return;
  }
  
  const keyword = searchKeyword.value.toLowerCase();
  filteredContacts.value = contacts.value.filter(contact => {
    return contact.contactName.toLowerCase().includes(keyword);
  });
};

// 选择联系人
const selectContact = async (contact) => {
  currentContact.value = contact;
  messageText.value = '';
  await loadMessages();
};

// 加载联系人列表
const loadContacts = async () => {
  try {
    const res = await request.get('/chat/contacts');
    if (res.code === '200') {
      contacts.value = res.data || [];
      filterContacts();
    } else {
      ElMessage.error('获取联系人失败：' + res.msg);
    }
  } catch (error) {
    console.error('加载联系人错误', error);
    ElMessage.error('获取联系人失败，请检查网络');
  }
};

// 加载消息记录
const loadMessages = async () => {
  if (!currentContact.value) return;
  
  try {
    const res = await request.get('/chat/history', {
      params: {
        contactId: currentContact.value.contactId,
        contactType: currentContact.value.contactType
      }
    });
    
    if (res.code === '200') {
      messages.value = res.data || [];
      
      // 更新已读状态
      if (currentContact.value.unreadCount > 0) {
        currentContact.value.unreadCount = 0;
      }
      
      // 滚动到底部
      await nextTick();
      scrollToBottom();
    } else {
      ElMessage.error('获取消息记录失败：' + res.msg);
    }
  } catch (error) {
    console.error('加载消息错误', error);
    ElMessage.error('获取消息记录失败，请检查网络');
  }
};

// 发送消息
const sendMessage = async () => {
  if (!messageText.value.trim() || !currentContact.value) return;
  
  // 生成一个临时ID用于标识本地消息
  const tempId = `${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
  
  const message = {
    receiverId: currentContact.value.contactId,
    receiverType: currentContact.value.contactType,
    content: messageText.value.trim(),
    tempId: tempId
  };
  
  // 如果WebSocket连接正常，则通过WebSocket发送
  if (ws && ws.readyState === WebSocket.OPEN) {
    // 先在本地显示消息
    const localMessage = {
      senderId: user.id,
      senderType: user.role,
      senderName: user.name,
      receiverId: currentContact.value.contactId,
      receiverType: currentContact.value.contactType,
      content: messageText.value.trim(),
      sendTime: new Date().toISOString(),
      tempId: tempId // 添加临时ID
    };
    
    console.log('发送本地临时消息:', localMessage); // 添加日志
    
    // 添加到本地消息列表
    messages.value.push(localMessage);
    
    // 清空输入框并滚动到底部
    messageText.value = '';
    nextTick(() => scrollToBottom());
    
    // 发送消息到服务器
    console.log('通过WebSocket发送消息:', message); // 添加日志
    ws.send(JSON.stringify(message));
  } else {
    // 否则通过HTTP发送
    try {
      // 先在本地显示消息，提供即时反馈
      const localMessage = {
        senderId: user.id,
        senderType: user.role,
        senderName: user.name,
        receiverId: currentContact.value.contactId,
        receiverType: currentContact.value.contactType,
        content: messageText.value.trim(),
        sendTime: new Date().toISOString()
      };
      
      // 添加到本地消息列表
      messages.value.push(localMessage);
      
      // 清空输入框并滚动到底部
      messageText.value = '';
      nextTick(() => scrollToBottom());
      
      // 发送到服务器
      const res = await request.post('/chat/send', message);
      if (res.code !== '200') {
        ElMessage.error('发送消息失败：' + res.msg);
        // 如果失败，从消息列表中移除本地消息
        const index = messages.value.findIndex(m => m === localMessage);
        if (index !== -1) {
          messages.value.splice(index, 1);
        }
      }
    } catch (error) {
      console.error('发送消息错误', error);
      ElMessage.error('发送消息失败，请检查网络');
      // 发生错误时，从消息列表中移除本地消息
      const index = messages.value.findIndex(m => 
        m.senderId === user.id && 
        m.content === message.content && 
        !m.id // 没有id表示是本地消息
      );
      if (index !== -1) {
        messages.value.splice(index, 1);
      }
    }
  }
};

// 滚动到底部
const scrollToBottom = () => {
  if (messagesScrollbar.value) {
    const scrollbar = messagesScrollbar.value.wrap;
    if (scrollbar) {
      scrollbar.scrollTop = scrollbar.scrollHeight;
    }
  }
};

// 连接WebSocket
const connectWebSocket = () => {
  if (!user.id || !user.role) return;
  
  // 使用完整后端地址，确保连接正确
  const backendUrl = 'localhost:9090'; // 根据实际后端地址调整
  const wsUrl = `ws://${backendUrl}/ws/chat/${user.id}/${user.role}`;
  
  console.log('尝试连接WebSocket:', wsUrl);
  
  // 如果已经有WebSocket连接，先关闭
  if (ws) {
    ws.close();
  }
  
  try {
    ws = new WebSocket(wsUrl);
    
    // 连接超时检测
    const connectionTimeout = setTimeout(() => {
      if (ws && ws.readyState !== WebSocket.OPEN) {
        console.error('WebSocket连接超时');
        ElMessage.error('聊天连接超时，请刷新页面重试');
      }
    }, 5000);
    
    ws.onopen = () => {
      clearTimeout(connectionTimeout);
      console.log('WebSocket连接已建立');
      // 设置一个小延迟，确保连接完全建立
      setTimeout(() => {
        ElMessage.success('实时聊天连接已建立');
      }, 100);
    };
    
    ws.onmessage = (event) => {
      try {
        const message = JSON.parse(event.data);
        console.log('收到WebSocket消息:', message); // 添加日志
        
        // 如果消息是当前联系人发送的，则添加到消息列表
        if (currentContact.value && 
            ((message.senderId === currentContact.value.contactId && message.senderType === currentContact.value.contactType) ||
             (message.receiverId === currentContact.value.contactId && message.receiverType === currentContact.value.contactType))) {
          
          // 检查这个消息是否已经在列表中（防止重复）
          const isDuplicate = messages.value.some(m => 
            m.id === message.id || 
            (m.tempId && m.tempId === message.tempId) || 
            (message.tempId && messages.value.some(existingMsg => existingMsg.tempId === message.tempId)) ||
            (m.senderId === message.senderId && 
             m.content === message.content && 
             m.sendTime === message.sendTime)
          );
          
          // 如果服务器返回的消息包含ID和tempId，尝试替换本地临时消息
          if (message.id && message.tempId) {
            const tempIndex = messages.value.findIndex(m => m.tempId === message.tempId);
            if (tempIndex !== -1) {
              console.log('替换临时消息:', messages.value[tempIndex], '->', message);
              messages.value[tempIndex] = message;
              nextTick(() => scrollToBottom());
              return; // 替换完成后直接返回，不再添加新消息
            }
          }
  
          if (!isDuplicate) {
            messages.value.push(message);
            nextTick(() => scrollToBottom());
          }
        } 
        // 否则更新联系人的未读消息数
        else {
          const contactIndex = contacts.value.findIndex(c => 
            c.contactId === message.senderId && c.contactType === message.senderType);
          
          if (contactIndex >= 0) {
            contacts.value[contactIndex].unreadCount = (contacts.value[contactIndex].unreadCount || 0) + 1;
            contacts.value[contactIndex].lastMessage = message;
            filterContacts();
            
            // 播放提示音
            playNotificationSound();
          } else {
            // 如果是新联系人，则重新加载联系人列表
            loadContacts();
          }
        }
      } catch (error) {
        console.error('WebSocket消息处理错误', error);
      }
    };
    
    ws.onclose = (event) => {
      clearTimeout(connectionTimeout);
      console.log('WebSocket连接已关闭', event.code, event.reason);
      if (!event.wasClean) {
        ElMessage.warning('聊天连接已断开，正在尝试重新连接...');
      }
      // 尝试重新连接
      setTimeout(connectWebSocket, 5000);
    };
    
    ws.onerror = (error) => {
      clearTimeout(connectionTimeout);
      console.error('WebSocket错误', error);
      ElMessage.error('聊天连接出错，请刷新页面重试');
    };
  } catch (error) {
    console.error('创建WebSocket连接失败', error);
    ElMessage.error('创建聊天连接失败，请刷新页面重试');
    // 延迟重试
    setTimeout(connectWebSocket, 5000);
  }
};

// 播放通知声音
const playNotificationSound = () => {
  try {
    const audio = new Audio('/notification.mp3');
    audio.play();
  } catch (error) {
    console.error('播放通知声音失败', error);
  }
};

// 监听联系人变化，自动滚动到底部
watch(messages, () => {
  nextTick(() => scrollToBottom());
});

// 在组件销毁时关闭WebSocket连接
onBeforeUnmount(() => {
  if (ws) {
    ws.close();
    ws = null;
  }
  // 清除定时器
  clearInterval(contactsRefreshInterval);
});

// 初始化
let contactsRefreshInterval;
onMounted(async () => {
  await loadContacts();
  
  // 延迟连接WebSocket，确保页面完全加载和渲染
  setTimeout(() => {
    // 连接WebSocket
    connectWebSocket();
  }, 500);
  
  // 如果有联系人，默认选择第一个
  if (contacts.value.length > 0) {
    selectContact(contacts.value[0]);
  }
  
  // 定期刷新联系人列表
  contactsRefreshInterval = setInterval(loadContacts, 60000); // 每分钟刷新一次
  
  // 添加页面可见性监听，在页面重新获得焦点时重新连接WebSocket
  document.addEventListener('visibilitychange', () => {
    if (document.visibilityState === 'visible' && (!ws || ws.readyState !== WebSocket.OPEN)) {
      console.log('页面重新获得焦点，重新连接WebSocket');
      connectWebSocket();
    }
  });
});
</script>

<style scoped>
.chat-container {
  height: 100%;
  padding: 20px;
}

.chat-card {
  height: calc(100vh - 120px);
  display: flex;
  flex-direction: column;
}

.chat-header {
  margin-bottom: 20px;
  border-bottom: 1px solid #eee;
  padding-bottom: 10px;
}

.chat-header h2 {
  margin: 0;
  color: #409eff;
}

.chat-content {
  display: flex;
  flex: 1;
  height: calc(100% - 60px);
  overflow: hidden;
}

.chat-sidebar {
  width: 280px;
  border-right: 1px solid #eee;
  padding-right: 15px;
  display: flex;
  flex-direction: column;
}

.contacts-scrollbar {
  margin-top: 15px;
  flex: 1;
}

.contact-item {
  display: flex;
  align-items: center;
  padding: 12px;
  border-radius: 8px;
  margin-bottom: 5px;
  cursor: pointer;
  position: relative;
}

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

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

.contact-info {
  margin-left: 12px;
  flex: 1;
}

.contact-name {
  font-weight: 500;
  margin-bottom: 4px;
}

.contact-message {
  font-size: 12px;
  color: #909399;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.unread-badge {
  position: absolute;
  top: 10px;
  right: 10px;
}

.no-contacts {
  text-align: center;
  color: #909399;
  margin-top: 50px;
}

.chat-main {
  flex: 1;
  padding-left: 15px;
  display: flex;
  flex-direction: column;
}

.chat-box {
  display: flex;
  flex-direction: column;
  height: 100%;
}

.chat-title {
  font-size: 18px;
  font-weight: 500;
  padding: 15px 0;
  border-bottom: 1px solid #eee;
}

.contact-role {
  font-size: 13px;
  color: #909399;
  font-weight: normal;
  margin-left: 5px;
}

.messages-scrollbar {
  flex: 1;
}

.messages-container {
  padding: 20px;
}

.no-messages {
  text-align: center;
  color: #909399;
  margin-top: 100px;
}

.message-item {
  display: flex;
  margin-bottom: 20px;
}

.message-self {
  flex-direction: row-reverse;
}

.message-content {
  margin: 0 12px;
  max-width: 70%;
}

.message-self .message-content {
  text-align: right;
}

.message-sender {
  font-size: 12px;
  color: #909399;
  margin-bottom: 4px;
}

.message-time {
  margin-left: 8px;
}

.message-text {
  padding: 10px 15px;
  border-radius: 8px;
  background-color: #f5f7fa;
  display: inline-block;
  word-break: break-word;
}

.message-self .message-text {
  background-color: #ecf5ff;
  color: #409eff;
}

.message-input {
  padding: 15px;
  border-top: 1px solid #eee;
  position: relative;
  margin-bottom: 10px;
}

.message-input-wrapper {
  display: flex;
  align-items: flex-start;
  width: 100%;
  margin-bottom: 8px;
}

.message-textarea {
  flex: 1;
}

.send-button-container {
  margin-left: 15px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  height: 100%;
}

.input-actions {
  display: flex;
  justify-content: flex-start;
  align-items: center;
}

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

.send-button {
  min-width: 90px;
  font-weight: bold;
  box-shadow: 0 2px 8px rgba(64, 158, 255, 0.3);
  height: 50px;
  padding: 0 20px;
  font-size: 16px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.3s;
  background-color: #409eff;
  border-color: #409eff;
}

.send-button:hover:not(:disabled) {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(64, 158, 255, 0.4);
  background-color: #66b1ff;
  border-color: #66b1ff;
}

.send-button:active:not(:disabled) {
  transform: translateY(0);
}

.send-icon {
  margin-right: 5px;
  font-size: 18px;
}

.no-contact-selected {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100%;
}
</style> 