const WebSocket = require('ws')
const { v4: uuidv4 } = require('uuid')

class ChatServer {
    constructor(server) {
        this.wss = new WebSocket.Server({ server })
        this.clients = new Map() // 存储所有连接的客户端
        this.messageHistory = [] // 存储消息历史
        this.setupWebSocket()
        this.setupHeartbeat()
    }

    setupWebSocket() {
        this.wss.on('connection', (ws, req) => {
            const clientId = uuidv4()
            const userInfo = { id: clientId, name: '未命名用户' }

            // 存储客户端连接
            this.clients.set(clientId, { ws, userInfo, lastPing: Date.now() })

            // 广播新用户加入
            this.broadcast({
                type: 'system',
                action: 'join',
                user: userInfo,
                users: Array.from(this.clients.values()).map(client => client.userInfo),
                timestamp: Date.now()
            })

            // 发送在线用户列表
            ws.send(JSON.stringify({
                type: 'system',
                action: 'userList',
                users: Array.from(this.clients.values()).map(client => client.userInfo),
                timestamp: Date.now()
            }))

            // 发送历史消息
            ws.send(JSON.stringify({
                type: 'system',
                action: 'history',
                messages: this.messageHistory.slice(-50), // 最近50条消息
                timestamp: Date.now()
            }))

            // 处理消息
            ws.on('message', (data) => {
                try {
                    const message = JSON.parse(data)
                    const client = this.clients.get(clientId)
                    console.log('客户端:', clientId)
                    console.log('收到消息:', message)
                    if (client) {
                        client.lastPing = Date.now() // 更新最后活动时间
                    }

                    switch (message.type) {
                        case 'chat':
                            // 处理聊天消息
                            const chatMessage = {
                                id: uuidv4(),
                                type: 'chat',
                                from: userInfo,
                                to: message.to, // null表示群发
                                content: message.content,
                                timestamp: Date.now()
                            }
                            this.messageHistory.push(chatMessage)
                            if (message.to) {
                                // 私聊消息
                                const targetClient = this.clients.get(message.to.id)
                                if (targetClient) {
                                    targetClient.ws.send(JSON.stringify(chatMessage))
                                    ws.send(JSON.stringify(chatMessage)) // 发送给自己
                                }
                            } else {
                                // 群发消息
                                this.broadcast(chatMessage)
                            }
                            break

                        case 'user':
                            // 更新用户信息
                            if (message.action === 'update') {
                                userInfo.name = message.name
                                this.broadcast({
                                    type: 'system',
                                    action: 'userUpdate',
                                    user: userInfo,
                                    users: Array.from(this.clients.values()).map(client => client.userInfo),
                                    timestamp: Date.now()
                                })
                            }
                            break

                        case 'ping':
                            // 处理心跳消息
                            ws.send(JSON.stringify({
                                type: 'pong',
                                timestamp: Date.now()
                            }))
                            break
                    }
                } catch (error) {
                    console.error('处理消息时出错:', error)
                }
            })

            // 处理连接关闭
            ws.on('close', () => {
                this.clients.delete(clientId)
                this.broadcast({
                    type: 'system',
                    action: 'leave',
                    user: userInfo,
                    users: Array.from(this.clients.values()).map(client => client.userInfo),
                    timestamp: Date.now()
                })
            })

            // 处理错误
            ws.on('error', (error) => {
                console.error('WebSocket错误:', error)
                this.clients.delete(clientId)
            })
        })
    }

    // 设置心跳检测
    setupHeartbeat() {
        const HEARTBEAT_INTERVAL = 30000 // 30秒检查一次
        const CLIENT_TIMEOUT = 60000 // 60秒超时

        setInterval(() => {
            const now = Date.now()
            this.clients.forEach((client, clientId) => {
                if (now - client.lastPing > CLIENT_TIMEOUT) {
                    console.log(`客户端 ${clientId} 超时断开`)
                    client.ws.terminate()
                    this.clients.delete(clientId)
                }
            })
        }, HEARTBEAT_INTERVAL)
    }

    // 广播消息给所有客户端
    broadcast(message) {
        const messageStr = JSON.stringify(message)
        this.clients.forEach(client => {
            if (client.ws.readyState === WebSocket.OPEN) {
                client.ws.send(messageStr)
            }
        })
    }

    // 清理历史消息
    cleanHistory() {
        const oneDay = 24 * 60 * 60 * 1000 // 一天的毫秒数
        const now = Date.now()
        this.messageHistory = this.messageHistory.filter(msg => {
            return (now - msg.timestamp) < oneDay
        })
    }
}

module.exports = ChatServer