package com.zhentao.service;

import com.zhentao.constant.ChatConstants;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * 在线用户管理服务
 */
@Service
public class OnlineUserService {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * 用户上线
     */
    public void userOnline(Long userId, String sessionId) {
        try {
            String key = ChatConstants.RedisKey.ONLINE_USER + userId;
            
            Map<String, Object> data = new HashMap<>();
            data.put("sessionId", sessionId);
            data.put("lastHeartbeat", System.currentTimeMillis());
            data.put("onlineTime", System.currentTimeMillis());
            
            // 设置过期时间为5分钟，需要心跳维持
            redisTemplate.opsForValue().set(key, data, 5, TimeUnit.MINUTES);
            
            // 将sessionId添加到用户会话集合
            String sessionKey = ChatConstants.RedisKey.USER_SESSIONS + userId;
            redisTemplate.opsForSet().add(sessionKey, sessionId);
            redisTemplate.expire(sessionKey, 5, TimeUnit.MINUTES);
            
            System.out.println("用户 " + userId + " 已上线，sessionId: " + sessionId);
        } catch (Exception e) {
            // Redis 操作失败不影响 WebSocket 连接
            System.err.println("⚠️ Redis 操作失败，但 WebSocket 连接正常: " + e.getMessage());
            System.out.println("✅ 用户 " + userId + " 已上线（Redis 不可用），sessionId: " + sessionId);
        }
    }

    /**
     * 用户离线
     */
    public void userOffline(Long userId, String sessionId) {
        try {
            String key = ChatConstants.RedisKey.ONLINE_USER + userId;
            String sessionKey = ChatConstants.RedisKey.USER_SESSIONS + userId;
            
            // 从会话集合中移除
            redisTemplate.opsForSet().remove(sessionKey, sessionId);
            
            // 如果没有其他会话，删除在线状态
            Long sessionCount = redisTemplate.opsForSet().size(sessionKey);
            if (sessionCount == null || sessionCount == 0) {
                redisTemplate.delete(key);
                redisTemplate.delete(sessionKey);
                System.out.println("用户 " + userId + " 已离线");
            } else {
                System.out.println("用户 " + userId + " 还有 " + sessionCount + " 个在线会话");
            }
        } catch (Exception e) {
            System.err.println("⚠️ Redis 操作失败: " + e.getMessage());
            System.out.println("✅ 用户 " + userId + " 已离线（Redis 不可用）");
        }
    }

    /**
     * 更新心跳时间
     */
    public void updateHeartbeat(Long userId) {
        try {
            String key = ChatConstants.RedisKey.ONLINE_USER + userId;
            
            Object obj = redisTemplate.opsForValue().get(key);
            if (obj instanceof Map) {
                @SuppressWarnings("unchecked")
                Map<String, Object> data = (Map<String, Object>) obj;
                data.put("lastHeartbeat", System.currentTimeMillis());
                
                // 刷新过期时间
                redisTemplate.opsForValue().set(key, data, 5, TimeUnit.MINUTES);
            }
        } catch (Exception e) {
            // 心跳更新失败不影响连接
            // System.err.println("心跳更新失败: " + e.getMessage());
        }
    }

    /**
     * 检查用户是否在线
     */
    public boolean isUserOnline(Long userId) {
        try {
            String key = ChatConstants.RedisKey.ONLINE_USER + userId;
            return Boolean.TRUE.equals(redisTemplate.hasKey(key));
        } catch (Exception e) {
            // Redis 不可用时默认返回 false
            return false;
        }
    }

    /**
     * 获取用户的所有会话ID
     */
    public Set<Object> getUserSessions(Long userId) {
        try {
            String sessionKey = ChatConstants.RedisKey.USER_SESSIONS + userId;
            return redisTemplate.opsForSet().members(sessionKey);
        } catch (Exception e) {
            System.err.println("⚠️ 获取用户会话失败: " + e.getMessage());
            return new java.util.HashSet<>();
        }
    }

    /**
     * 获取在线用户数量
     */
    public long getOnlineUserCount() {
        try {
            Set<String> keys = redisTemplate.keys(ChatConstants.RedisKey.ONLINE_USER + "*");
            return keys != null ? keys.size() : 0;
        } catch (Exception e) {
            System.err.println("⚠️ 获取在线用户数量失败: " + e.getMessage());
            return 0;
        }
    }
}



