package org.xyzh.common.auth.utils;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.xyzh.common.core.domain.LoginDomain;
import org.xyzh.common.redis.service.RedisService;

import jakarta.annotation.PostConstruct;
import jakarta.servlet.http.HttpServletRequest;

/**
 * @description 登录用户工具类，从Redis获取当前登录用户信息
 * @filename LoginUtil.java
 * @author yslg
 * @copyright xyzh
 * @since 2025-12-17
 */
@Component
public class LoginUtil {

    private static final String AUTHORIZATION_HEADER = "Authorization";
    private static final String BEARER_PREFIX = "Bearer ";
    private static final String LOGIN_TOKEN_PREFIX = "login:token:";

    @Autowired
    private RedisService redisService;

    private static LoginUtil instance;

    @PostConstruct
    public void init() {
        instance = this;
    }

    /**
     * 获取当前登录用户信息
     */
    public static LoginDomain getCurrentLogin() {
        String token = getToken();
        if (!StringUtils.hasText(token)) {
            return null;
        }

        try {
            String cacheKey = LOGIN_TOKEN_PREFIX + token;
            return instance.redisService.get(cacheKey, LoginDomain.class);
        } catch (Exception e) {
            // 忽略异常
        }

        return null;
    }

    /**
     * 获取当前用户ID
     */
    public static String getCurrentUserId() {
        LoginDomain login = getCurrentLogin();
        if (login != null && login.getUser() != null) {
            return login.getUser().getUserId();
        }
        return null;
    }

    /**
     * 获取当前用户名
     */
    public static String getCurrentUserName() {
        LoginDomain login = getCurrentLogin();
        if (login != null && login.getUserInfo() != null) {
            return login.getUserInfo().getUsername();
        }
        return null;
    }

    /**
     * 判断用户是否已登录
     */
    public static boolean isLoggedIn() {
        return getCurrentLogin() != null;
    }

    /**
     * 从请求头或Dubbo RpcContext获取Token
     */
    public static String getToken() {
        // 1. 优先从HTTP请求头获取（正常Web请求）
        HttpServletRequest request = getRequest();
        if (request != null) {
            String authHeader = request.getHeader(AUTHORIZATION_HEADER);
            if (StringUtils.hasText(authHeader) && authHeader.startsWith(BEARER_PREFIX)) {
                return authHeader.substring(BEARER_PREFIX.length());
            }
        }

        // 2. 从Dubbo Provider ThreadLocal获取（跨服务调用）
        try {
            Class<?> filterClass = Class.forName("org.xyzh.common.auth.filter.DubboProviderContextFilter");
            ThreadLocal<String> tokenHolder = (ThreadLocal<String>) filterClass.getField("TOKEN_HOLDER").get(null);
            String token = tokenHolder.get();
            if (StringUtils.hasText(token)) {
                return token;
            }
        } catch (Exception e) {
            // Dubbo Filter不存在或未加载，忽略
        }

        return null;
    }

    /**
     * 获取当前请求
     */
    private static HttpServletRequest getRequest() {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (attributes != null) {
            return attributes.getRequest();
        }
        return null;
    }
}
