package com.emotion.interceptor;

import com.emotion.service.AuthService;
import com.emotion.util.JwtUtil;
import com.emotion.util.UserContextHolder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 认证拦截器
 * 
 * @author huazhongmin
 * @date 2025-07-23
 */
@Component
public class AuthInterceptor implements HandlerInterceptor {

    private static final Logger log = LoggerFactory.getLogger(AuthInterceptor.class);

    @Autowired
    private AuthService authService;

    @Autowired
    private JwtUtil jwtUtil;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 跨域预检请求直接放行
        if ("OPTIONS".equals(request.getMethod())) {
            return true;
        }

        // 获取请求路径
        String requestURI = request.getRequestURI();
        
        // 白名单路径，不需要认证
        if (isWhiteList(requestURI)) {
            return true;
        }

        // 提取访问令牌
        String token = extractToken(request);
        if (token == null) {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            response.setContentType("application/json;charset=UTF-8");
            response.getWriter().write("{\"code\":401,\"message\":\"未提供访问令牌\",\"data\":null}");
            return false;
        }

        // 验证访问令牌 - 使用JwtUtil直接验证，支持管理员和普通用户token
        if (!jwtUtil.validateToken(token)) {
            log.warn("Token验证失败: {}", requestURI);
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            response.setContentType("application/json;charset=UTF-8");
            response.getWriter().write("{\"code\":401,\"message\":\"访问令牌无效或已过期\",\"data\":null}");
            return false;
        }

        // 从token中获取用户信息
        String userId = jwtUtil.getUserIdFromToken(token);
        String username = jwtUtil.getUsernameFromToken(token);
        String userType = jwtUtil.getUserTypeFromToken(token);

        if (userId == null) {
            log.warn("无法从Token获取用户ID: {}", requestURI);
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            response.setContentType("application/json;charset=UTF-8");
            response.getWriter().write("{\"code\":401,\"message\":\"访问令牌无效\",\"data\":null}");
            return false;
        }

        // 将用户信息存储到请求属性中，供后续使用
        request.setAttribute("userId", userId);
        request.setAttribute("username", username);
        request.setAttribute("token", token);
        request.setAttribute("userType", userType);

        // 设置用户上下文
        UserContextHolder.setCurrentUserId(userId);
        UserContextHolder.setCurrentUsername(username);
        UserContextHolder.setCurrentToken(token);

        log.debug("Token验证成功: userId={}, username={}, userType={}, uri={}", 
                userId, username, userType, requestURI);

        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        UserContextHolder.clear();
        log.debug("请求完成，已清除用户上下文");
    }

    /**
     * 检查是否为白名单路径
     */
    private boolean isWhiteList(String requestURI) {
        // 认证相关接口
        if (requestURI.startsWith("/auth/")) {
            return true;
        }
        
        // 静态资源
        if (requestURI.startsWith("/static/") || 
            requestURI.startsWith("/css/") || 
            requestURI.startsWith("/js/") || 
            requestURI.startsWith("/images/")) {
            return true;
        }
        
        // Swagger文档
        if (requestURI.startsWith("/swagger-") || 
            requestURI.startsWith("/v2/api-docs") || 
            requestURI.startsWith("/webjars/")) {
            return true;
        }
        
        // 健康检查
        if (requestURI.equals("/health") || requestURI.equals("/actuator/health")) {
            return true;
        }
        
        return false;
    }

    /**
     * 从请求中提取访问令牌
     */
    private String extractToken(HttpServletRequest request) {
        // 从Authorization头中获取
        String authHeader = request.getHeader("Authorization");
        if (authHeader != null && authHeader.startsWith("Bearer ")) {
            return authHeader.substring(7);
        }
        
        // 从请求参数中获取
        String tokenParam = request.getParameter("token");
        if (tokenParam != null && !tokenParam.trim().isEmpty()) {
            return tokenParam.trim();
        }
        
        return null;
    }
}
