package com.qqchen.deploy.backend.deploy.config;

import com.qqchen.deploy.backend.framework.security.CustomUserDetails;
import com.qqchen.deploy.backend.framework.security.util.JwtTokenUtil;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.HandshakeInterceptor;

import java.util.Map;

/**
 * WebSocket认证拦截器
 * 在WebSocket握手时验证JWT Token
 */
@Slf4j
@Component
public class WebSocketAuthInterceptor implements HandshakeInterceptor {

    @Resource
    private JwtTokenUtil jwtTokenUtil;

    @Resource
    private UserDetailsService userDetailsService;

    @Override
    public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response,
                                    WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
        
        log.debug("WebSocket握手认证开始: {}", request.getURI());

        try {
            // 1. 从请求中提取Token
            String token = extractToken(request);
            if (token == null || token.isEmpty()) {
                log.warn("WebSocket连接缺少Token");
                return false;
            }

            // 2. 解析Token获取用户名
            String username = jwtTokenUtil.getUsernameFromToken(token);
            if (username == null) {
                log.warn("无效的Token");
                return false;
            }

            // 3. 加载用户信息
            UserDetails userDetails = userDetailsService.loadUserByUsername(username);
            if (userDetails == null) {
                log.warn("用户不存在: {}", username);
                return false;
            }

            // 4. 验证Token
            if (!jwtTokenUtil.validateToken(token, userDetails)) {
                log.warn("Token验证失败: {}", username);
                return false;
            }

            // 5. 将用户信息存入attributes，供Handler使用
            if (userDetails instanceof CustomUserDetails) {
                CustomUserDetails customUserDetails = (CustomUserDetails) userDetails;
                attributes.put("userId", customUserDetails.getUserId());
                attributes.put("username", customUserDetails.getUsername());
                
                log.info("WebSocket认证成功: userId={}, username={}", 
                         customUserDetails.getUserId(), customUserDetails.getUsername());
            }

            // 6. 提取客户端信息
            if (request instanceof ServletServerHttpRequest) {
                ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request;
                String clientIp = getClientIp(servletRequest);
                String userAgent = servletRequest.getServletRequest().getHeader("User-Agent");
                
                attributes.put("clientIp", clientIp);
                attributes.put("userAgent", userAgent);
            }

            return true;

        } catch (Exception e) {
            log.error("WebSocket认证异常", e);
            return false;
        }
    }

    @Override
    public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response,
                                WebSocketHandler wsHandler, Exception exception) {
        // 握手后处理（可选）
    }

    /**
     * 从请求中提取Token
     * 支持两种方式：
     * 1. URL参数: ?token=xxx
     * 2. Header: Authorization: Bearer xxx
     */
    private String extractToken(ServerHttpRequest request) {
        // 1. 尝试从URL参数获取
        String query = request.getURI().getQuery();
        if (query != null && query.contains("token=")) {
            String[] params = query.split("&");
            for (String param : params) {
                if (param.startsWith("token=")) {
                    return param.substring(6);
                }
            }
        }

        // 2. 尝试从Header获取
        if (request instanceof ServletServerHttpRequest) {
            ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request;
            String authHeader = servletRequest.getServletRequest().getHeader("Authorization");
            if (authHeader != null && authHeader.startsWith("Bearer ")) {
                return authHeader.substring(7);
            }
        }

        return null;
    }

    /**
     * 获取客户端真实IP
     */
    private String getClientIp(ServletServerHttpRequest request) {
        String ip = request.getServletRequest().getHeader("X-Forwarded-For");
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getServletRequest().getHeader("X-Real-IP");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getServletRequest().getRemoteAddr();
        }
        // 如果是多级代理，取第一个IP
        if (ip != null && ip.contains(",")) {
            ip = ip.split(",")[0].trim();
        }
        return ip;
    }
}
