package com.emotion.util;

import com.emotion.util.UserContextHolder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;

/**
 * 用户上下文工具类
 * 提供便捷的方法操作用户上下文信息
 * 
 * @author huazhongmin
 * @date 2025-07-25
 */
@Slf4j
public class UserContextUtils {

    /**
     * 获取当前用户ID
     * 
     * @return 当前用户ID，如果未登录则返回null
     */
    public static String getCurrentUserId() {
        return UserContextHolder.getCurrentUserId();
    }

    /**
     * 获取当前用户名
     * 
     * @return 当前用户名，如果未登录则返回null
     */
    public static String getCurrentUsername() {
        return UserContextHolder.getCurrentUsername();
    }

    /**
     * 获取当前用户类型
     * 
     * @return 当前用户类型，如果未登录则返回null
     */
    public static String getCurrentUserType() {
        return UserContextHolder.getCurrentUserType();
    }

    /**
     * 获取客户端IP
     * 
     * @return 客户端IP
     */
    public static String getClientIp() {
        return UserContextHolder.getClientIp();
    }

    /**
     * 获取请求ID
     * 
     * @return 请求ID
     */
    public static String getRequestId() {
        return UserContextHolder.getRequestId();
    }

    /**
     * 获取当前用户ID，如果未登录则抛出异常
     * 
     * @return 当前用户ID
     * @throws IllegalStateException 如果用户未登录
     */
    public static String requireCurrentUserId() {
        String userId = getCurrentUserId();
        if (userId == null || userId.trim().isEmpty()) {
            throw new IllegalStateException("用户未登录或认证失败");
        }
        return userId;
    }

    /**
     * 获取当前用户名，如果未登录则抛出异常
     * 
     * @return 当前用户名
     * @throws IllegalStateException 如果用户未登录
     */
    public static String requireCurrentUsername() {
        String username = getCurrentUsername();
        if (username == null || username.trim().isEmpty()) {
            throw new IllegalStateException("用户未登录或认证失败");
        }
        return username;
    }

    /**
     * 获取当前用户类型，如果为空则返回默认值
     * 
     * @param defaultValue 默认值
     * @return 用户类型
     */
    public static String getCurrentUserTypeOrDefault(String defaultValue) {
        String userType = UserContextHolder.getCurrentUserType();
        return userType != null ? userType : defaultValue;
    }

    /**
     * 获取当前用户类型，如果为空则返回"GUEST"
     * 
     * @return 用户类型
     */
    public static String getCurrentUserTypeOrGuest() {
        return getCurrentUserTypeOrDefault("GUEST");
    }

    /**
     * 获取客户端IP，如果为空则返回默认值
     * 
     * @param defaultValue 默认值
     * @return 客户端IP
     */
    public static String getClientIpOrDefault(String defaultValue) {
        String clientIp = UserContextHolder.getClientIp();
        return clientIp != null ? clientIp : defaultValue;
    }

    /**
     * 获取客户端IP，如果为空则返回"unknown"
     * 
     * @return 客户端IP
     */
    public static String getClientIpOrUnknown() {
        return getClientIpOrDefault("unknown");
    }

    /**
     * 获取请求ID，如果为空则返回默认值
     * 
     * @param defaultValue 默认值
     * @return 请求ID
     */
    public static String getRequestIdOrDefault(String defaultValue) {
        String requestId = UserContextHolder.getRequestId();
        return requestId != null ? requestId : defaultValue;
    }

    /**
     * 获取请求ID，如果为空则返回随机UUID
     * 
     * @return 请求ID
     */
    public static String getRequestIdOrRandom() {
        String requestId = UserContextHolder.getRequestId();
        if (requestId != null) {
            return requestId;
        }
        return java.util.UUID.randomUUID().toString().replace("-", "");
    }

    /**
     * 执行带有临时上下文的操作
     * 
     * @param userId    用户ID
     * @param username  用户名
     * @param userType  用户类型
     * @param operation 要执行的操作
     */
    public static void executeWithTempContext(String userId, String username, String userType, Runnable operation) {
        // 保存当前上下文
        String originalUserId = UserContextHolder.getCurrentUserId();
        String originalUsername = UserContextHolder.getCurrentUsername();
        String originalUserType = UserContextHolder.getCurrentUserType();
        String originalClientIp = UserContextHolder.getClientIp();
        String originalRequestId = UserContextHolder.getRequestId();
        
        try {
            // 设置临时上下文
            UserContextHolder.setUserContext(userId, username, userType, 
                    originalClientIp != null ? originalClientIp : "127.0.0.1",
                    originalRequestId != null ? originalRequestId : "temp");
            
            // 执行操作
            operation.run();
            
        } finally {
            // 恢复原始上下文
            if (originalUserId != null || originalUsername != null) {
                UserContextHolder.setUserContext(originalUserId, originalUsername, originalUserType, 
                        originalClientIp, originalRequestId);
            } else {
                UserContextHolder.clear();
            }
        }
    }

    /**
     * 从HTTP请求中获取客户端真实IP地址
     * 
     * @param request HTTP请求
     * @return 客户端IP地址
     */
    public static String getClientIpAddress(HttpServletRequest request) {
        String ip = null;

        // 1. 从X-Forwarded-For获取（经过代理的情况）
        ip = request.getHeader("X-Forwarded-For");
        if (StringUtils.hasText(ip) && !"unknown".equalsIgnoreCase(ip)) {
            // 多个IP的情况，取第一个
            int index = ip.indexOf(',');
            if (index != -1) {
                ip = ip.substring(0, index);
            }
            return ip.trim();
        }

        // 2. 从X-Real-IP获取
        ip = request.getHeader("X-Real-IP");
        if (StringUtils.hasText(ip) && !"unknown".equalsIgnoreCase(ip)) {
            return ip.trim();
        }

        // 3. 从Proxy-Client-IP获取
        ip = request.getHeader("Proxy-Client-IP");
        if (StringUtils.hasText(ip) && !"unknown".equalsIgnoreCase(ip)) {
            return ip.trim();
        }

        // 4. 从WL-Proxy-Client-IP获取
        ip = request.getHeader("WL-Proxy-Client-IP");
        if (StringUtils.hasText(ip) && !"unknown".equalsIgnoreCase(ip)) {
            return ip.trim();
        }

        // 5. 从HTTP_CLIENT_IP获取
        ip = request.getHeader("HTTP_CLIENT_IP");
        if (StringUtils.hasText(ip) && !"unknown".equalsIgnoreCase(ip)) {
            return ip.trim();
        }

        // 6. 从HTTP_X_FORWARDED_FOR获取
        ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        if (StringUtils.hasText(ip) && !"unknown".equalsIgnoreCase(ip)) {
            return ip.trim();
        }

        // 7. 最后从getRemoteAddr获取
        ip = request.getRemoteAddr();
        return StringUtils.hasText(ip) ? ip.trim() : "unknown";
    }
}