package com.emotion.interceptor;

import com.emotion.util.UserContextHolder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.UUID;

/**
 * 用户上下文拦截器
 * 用于在请求处理前设置用户上下文信息，请求处理后清理上下文
 * 
 * @author huazhongmin
 * @date 2025-07-23
 */
@Slf4j
@Component
public class UserContextInterceptor implements HandlerInterceptor {

    /**
     * 请求处理前
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        try {
            // 生成请求ID
            String requestId = UUID.randomUUID().toString().replace("-", "");
            
            // 获取用户信息
            String userId = getUserIdFromRequest(request);
            String username = getUsernameFromRequest(request);
            String userType = getUserTypeFromRequest(request);
            String clientIp = getClientIpFromRequest(request);
            
            // 设置用户上下文
            UserContextHolder.setUserContext(userId, username, userType, clientIp, requestId);
            
            // 设置响应头中的请求ID，便于追踪
            response.setHeader("X-Request-Id", requestId);
            
            log.debug("设置用户上下文: {}", UserContextHolder.getContextSummary());
            
            return true;
            
        } catch (Exception e) {
            log.warn("设置用户上下文失败: {}", e.getMessage());
            // 即使设置失败也不影响请求处理
            return true;
        }
    }

    /**
     * 请求处理后
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, 
                               Object handler, Exception ex) {
        try {
            log.debug("清理用户上下文: {}", UserContextHolder.getContextSummary());
            // 清理用户上下文
            UserContextHolder.clear();
            
        } catch (Exception e) {
            log.warn("清理用户上下文失败: {}", e.getMessage());
        }
    }
    
    /**
     * 从请求中获取用户ID
     *
     * @param request HTTP请求
     * @return 用户ID
     */
    private String getUserIdFromRequest(HttpServletRequest request) {
        // 1. 优先从请求属性获取（AuthInterceptor设置的）
        Object userIdAttr = request.getAttribute("userId");
        if (userIdAttr != null && StringUtils.hasText(userIdAttr.toString())) {
            return userIdAttr.toString();
        }

        // 2. 从请求头获取
        String userId = request.getHeader("X-User-Id");
        if (StringUtils.hasText(userId)) {
            return userId;
        }

        // 3. 从请求参数获取
        userId = request.getParameter("userId");
        if (StringUtils.hasText(userId)) {
            return userId;
        }

        // 4. 从Session获取
        Object sessionUserId = request.getSession().getAttribute("userId");
        if (sessionUserId != null) {
            return sessionUserId.toString();
        }

        // 5. 生成访客ID
        return "guest_" + System.currentTimeMillis();
    }
    
    /**
     * 从请求中获取用户名
     *
     * @param request HTTP请求
     * @return 用户名
     */
    private String getUsernameFromRequest(HttpServletRequest request) {
        // 1. 优先从请求属性获取（AuthInterceptor设置的）
        Object usernameAttr = request.getAttribute("username");
        if (usernameAttr != null && StringUtils.hasText(usernameAttr.toString())) {
            return usernameAttr.toString();
        }

        // 2. 从请求头获取
        String username = request.getHeader("X-Username");
        if (StringUtils.hasText(username)) {
            return username;
        }

        // 3. 从请求参数获取
        username = request.getParameter("username");
        if (StringUtils.hasText(username)) {
            return username;
        }

        // 4. 从Session获取
        Object sessionUsername = request.getSession().getAttribute("username");
        if (sessionUsername != null) {
            return sessionUsername.toString();
        }

        return "guest";
    }
    
    /**
     * 从请求中获取用户类型
     * 
     * @param request HTTP请求
     * @return 用户类型
     */
    private String getUserTypeFromRequest(HttpServletRequest request) {
        // 1. 从请求头获取
        String userType = request.getHeader("X-User-Type");
        if (StringUtils.hasText(userType)) {
            return userType;
        }
        
        // 2. 从请求参数获取
        userType = request.getParameter("userType");
        if (StringUtils.hasText(userType)) {
            return userType;
        }
        
        // 3. 从Session获取
        Object sessionUserType = request.getSession().getAttribute("userType");
        if (sessionUserType != null) {
            return sessionUserType.toString();
        }
        
        return "GUEST";
    }
    
    /**
     * 从请求中获取客户端IP
     * 
     * @param request HTTP请求
     * @return 客户端IP
     */
    private String getClientIpFromRequest(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";
    }
}
