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());
            
            // 设置过期时间为80秒，需要心跳维持
            redisTemplate.opsForValue().set(key, data, 80, TimeUnit.SECONDS);
            
            // 将sessionId添加到用户会话集合
            String sessionKey = ChatConstants.RedisKey.USER_SESSIONS + userId;
            redisTemplate.opsForSet().add(sessionKey, sessionId);
            redisTemplate.expire(sessionKey, 80, TimeUnit.SECONDS);
            
            System.out.println("用户 " + userId + " 已上线，sessionId: " + sessionId + "，过期时间: 80秒");
        } 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;
            
            System.out.println("🔄 ========== 更新心跳 ==========");
            System.out.println("🔄 用户ID: " + userId);
            System.out.println("🔄 Redis Key: " + key);
            
            // 直接刷新过期时间为80秒,返回值表示key是否存在
            System.out.println("🔄 执行 EXPIRE 命令,设置过期时间为80秒...");
            Boolean success = redisTemplate.expire(key, 80, TimeUnit.SECONDS);
            
            System.out.println("🔄 EXPIRE 命令返回结果: " + success);
            
            if (Boolean.FALSE.equals(success)) {
                // key不存在(已过期),重新创建
                System.out.println("⚠️ key不存在,重新创建...");
                Map<String, Object> data = new HashMap<>();
                data.put("lastHeartbeat", System.currentTimeMillis());
                data.put("onlineTime", System.currentTimeMillis());
                redisTemplate.opsForValue().set(key, data, 80, TimeUnit.SECONDS);
                
                System.out.println("✅ 用户 " + userId + " 在线状态已重新创建(80秒过期)");
            } else {
                System.out.println("✅ 用户 " + userId + " 过期时间已更新为80秒");
            }
            
            System.out.println("🔄 ================================");
        } catch (Exception e) {
            // 心跳更新失败,打印日志
            System.err.println("❌ ========== 心跳更新失败 ==========");
            System.err.println("❌ 用户ID: " + userId);
            System.err.println("❌ 错误信息: " + e.getMessage());
            e.printStackTrace();
            System.err.println("❌ ===================================");
        }
    }

    /**
     * 检查用户是否在线
     */
    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;
        }
    }
}



