<template>
  <div class="chat-room">
    <Navbar />
    <h2>聊天室</h2>
    <div class="chat-messages" ref="messagesRef">
      <div v-for="(msg, idx) in messages" :key="idx" class="chat-message">
        <span class="chat-user">{{ msg.username || '匿名' }}：</span>
        <span class="chat-content">{{ msg.content }}</span>
        <span class="chat-time" v-if="msg.timestamp">({{ formatTime(msg.timestamp) }})</span>
      </div>
    </div>
    <div class="chat-input">
      <el-input v-model="input" placeholder="输入消息..." @keyup.enter="sendMessage" />
      <el-button type="primary" @click="sendMessage">发送</el-button>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, onBeforeUnmount, nextTick } from 'vue'
import { useStore } from 'vuex'
import axios from 'axios'
import Navbar from "@/components/Navbar.vue";

const store = useStore()
const wsUrl = 'ws://localhost:8081/api/ws/chat'
const ws = ref(null)
const messages = ref([])
const input = ref('')
const messagesRef = ref(null)

function getToken() {
  return localStorage.getItem('token')
}

function setCookie(name, value, days = 7) {
  const expires = new Date()
  expires.setTime(expires.getTime() + (days * 24 * 60 * 60 * 1000))
  document.cookie = `${name}=${value};expires=${expires.toUTCString()};path=/`
}

// 获取聊天历史记录
async function loadChatHistory() {
  try {
    const token = getToken()
    if (!token) return

    console.log('🔄 获取聊天历史记录...')
    const response = await axios.get('http://localhost:8081/api/chat/history', {
      params: { roomId: 1 },
      headers: { 'sapling-token': token }
    })
    
    if (response.data && Array.isArray(response.data)) {
      messages.value = response.data
      console.log('📚 获取到', response.data.length, '条历史消息')
      
      // 滚动到底部
      nextTick(() => {
        if (messagesRef.value) {
          messagesRef.value.scrollTop = messagesRef.value.scrollHeight
        }
      })
    }
  } catch (error) {
    console.error('❌ 获取聊天历史失败:', error)
  }
}

function connect() {
  const token = getToken()
  if (!token) {
    console.error('无法连接WebSocket：未找到token')
    return
  }

  // 设置cookie，这样WebSocket握手时后端可以从cookie获取token
  setCookie('sapling-token', token)
  
  console.log('尝试连接WebSocket:', wsUrl)
  console.log('已设置cookie: sapling-token =', token)
  
  ws.value = new WebSocket(wsUrl)
  
  ws.value.onopen = async () => {
    console.log('✅ WebSocket连接成功')
    // 连接成功后立即获取聊天历史
    await loadChatHistory()
  }
  
  ws.value.onmessage = (event) => {
    console.log('📥 收到消息:', event.data)
    try {
      const msg = JSON.parse(event.data)
      console.log('📥 解析后的消息:', msg)
      messages.value.push(msg)
      nextTick(() => {
        if (messagesRef.value) {
          messagesRef.value.scrollTop = messagesRef.value.scrollHeight
        }
      })
    } catch (e) {
      console.error('❌ 消息解析失败:', e, event.data)
    }
  }
  
  ws.value.onerror = (err) => {
    console.error('❌ WebSocket错误:', err)
  }
  
  ws.value.onclose = (event) => {
    console.log('❌ WebSocket已断开, 代码:', event.code, '原因:', event.reason)
    setTimeout(() => {
      console.log('🔄 尝试重连...')
      connect()
    }, 2000)
  }
}

function sendMessage() {
  if (!input.value.trim()) return
  
  if (!ws.value || ws.value.readyState !== WebSocket.OPEN) {
    console.error('❌ WebSocket未连接')
    return
  }

  const message = {
    roomId: 1, // 默认房间ID为1
    content: input.value.trim()
  }
  
  console.log('📤 发送消息:', message)
  ws.value.send(JSON.stringify(message))
  input.value = ''
}

function formatTime(timestamp) {
  return new Date(timestamp).toLocaleTimeString()
}

onMounted(() => {
  console.log('🚀 聊天室组件已挂载')
  connect()
})

onBeforeUnmount(() => {
  console.log('🔌 组件卸载，关闭WebSocket连接')
  if (ws.value) {
    ws.value.close()
  }
})
</script>

<style scoped>
.chat-room {
  max-width: 600px;
  margin: 40px auto;
  border: 1px solid #eee;
  border-radius: 8px;
  padding: 24px;
  background: #fff;
}
.chat-messages {
  height: 320px;
  overflow-y: auto;
  border: 1px solid #f0f0f0;
  border-radius: 4px;
  padding: 12px;
  margin-bottom: 16px;
  background: #fafbfc;
}
.chat-message {
  margin-bottom: 8px;
}
.chat-user {
  font-weight: bold;
  color: #409eff;
}
.chat-time {
  color: #999;
  font-size: 12px;
  margin-left: 8px;
}
.chat-input {
  display: flex;
  gap: 8px;
}
</style> 