package org.xyzh.system.utils;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.xyzh.common.core.domain.LoginDomain;
import org.xyzh.common.core.security.TokenParser;
import org.xyzh.common.dto.user.TbSysUser;
import org.xyzh.common.dto.user.TbSysUserInfo;
import org.xyzh.common.redis.service.RedisService;
import org.xyzh.common.utils.NonUtils;
import org.xyzh.common.utils.ServletUtil;

/**
 * @description LoginUtil.java文件描述 登录信息工具类
 * @filename LoginUtil.java
 * @author yslg
 * @copyright xyzh
 * @since 2025-10-07
 */
@Component
public class LoginUtil {

    private static final String REDIS_LOGIN_PREFIX = "login:token:";

    private static TokenParser tokenParser;
    private static RedisService redisService;

    @Autowired
    public void setTokenParser(TokenParser tokenParser) {
        LoginUtil.tokenParser = tokenParser;
    }

    @Autowired
    public void setRedisService(RedisService redisService) {
        LoginUtil.redisService = redisService;
    }

    /**
     * @description 获取当前请求的LoginDomain（无参方法）
     * @return LoginDomain 当前登录用户信息，未登录或登录过期返回null
     * @author yslg
     * @since 2025-10-07
     */
    public static LoginDomain getCurrentLoginDomain() {
        try {
            // 从当前请求获取token
            String token = ServletUtil.getToken();
            if (NonUtils.isEmpty(token)) {
                return null;
            }

            // 验证token
            String userId = tokenParser.getUserIdFromToken(token);
            if (NonUtils.isEmpty(userId) || !tokenParser.validateToken(token, userId)) {
                return null;
            }

            // 从Redis获取LoginDomain
            String redisKey = REDIS_LOGIN_PREFIX + userId;
            LoginDomain loginDomain = (LoginDomain) redisService.get(redisKey);
            
            if (loginDomain != null) {
                // 更新token信息
                loginDomain.setToken(token);
            }
            
            return loginDomain;
            
        } catch (Exception e) {
            // 记录日志但不抛出异常，返回null表示未登录
            return null;
        }
    }

    /**
     * @description 获取当前登录用户
     * @return TbSysUser 当前登录用户，未登录返回null
     * @author yslg
     * @since 2025-10-07
     */
    public static TbSysUser getCurrentUser() {
        LoginDomain loginDomain = getCurrentLoginDomain();
        return loginDomain != null ? loginDomain.getUser() : null;
    }

    /**
     * @description 获取当前登录用户详细信息
     * @return TbSysUserInfo 当前登录用户详细信息，未登录返回null
     * @author yslg
     * @since 2025-10-07
     */
    public static TbSysUserInfo getCurrentUserInfo() {
        LoginDomain loginDomain = getCurrentLoginDomain();
        return loginDomain != null ? loginDomain.getUserInfo() : null;
    }

    /**
     * @description 获取当前登录用户ID
     * @return String 用户ID，未登录返回null
     * @author yslg
     * @since 2025-10-07
     */
    public static String getCurrentUserId() {
        TbSysUser user = getCurrentUser();
        return user != null ? user.getID() : null;
    }

    /**
     * @description 获取当前登录用户名
     * @return String 用户名，未登录返回null
     * @author yslg
     * @since 2025-10-07
     */
    public static String getCurrentUsername() {
        TbSysUser user = getCurrentUser();
        return user != null ? user.getUsername() : null;
    }

    /**
     * @description 获取当前登录用户邮箱
     * @return String 邮箱，未登录返回null
     * @author yslg
     * @since 2025-10-07
     */
    public static String getCurrentUserEmail() {
        TbSysUser user = getCurrentUser();
        return user != null ? user.getEmail() : null;
    }

    /**
     * @description 获取当前登录用户手机号
     * @return String 手机号，未登录返回null
     * @author yslg
     * @since 2025-10-07
     */
    public static String getCurrentUserPhone() {
        TbSysUser user = getCurrentUser();
        return user != null ? user.getPhone() : null;
    }

    /**
     * @description 检查当前用户是否已登录
     * @return boolean true-已登录，false-未登录
     * @author yslg
     * @since 2025-10-07
     */
    public static boolean isLoggedIn() {
        return getCurrentLoginDomain() != null;
    }

    /**
     * @description 检查当前用户是否具有指定权限
     * @param permissionCode 权限编码
     * @return boolean true-有权限，false-无权限
     * @author yslg
     * @since 2025-10-07
     */
    public static boolean hasPermission(String permissionCode) {
        LoginDomain loginDomain = getCurrentLoginDomain();
        if (loginDomain == null || loginDomain.getPermissions() == null) {
            return false;
        }
        
        return loginDomain.getPermissions().stream()
                .anyMatch(permission -> permissionCode.equals(permission.getCode()));
    }

    /**
     * @description 检查当前用户是否具有任意一个指定权限
     * @param permissionCodes 权限编码数组
     * @return boolean true-有任意一个权限，false-无权限
     * @author yslg
     * @since 2025-10-07
     */
    public static boolean hasAnyPermission(String... permissionCodes) {
        if (permissionCodes == null || permissionCodes.length == 0) {
            return false;
        }
        
        for (String permissionCode : permissionCodes) {
            if (hasPermission(permissionCode)) {
                return true;
            }
        }
        
        return false;
    }

    /**
     * @description 检查当前用户是否具有所有指定权限
     * @param permissionCodes 权限编码数组
     * @return boolean true-有所有权限，false-缺少权限
     * @author yslg
     * @since 2025-10-07
     */
    public static boolean hasAllPermissions(String... permissionCodes) {
        if (permissionCodes == null || permissionCodes.length == 0) {
            return true;
        }
        
        for (String permissionCode : permissionCodes) {
            if (!hasPermission(permissionCode)) {
                return false;
            }
        }
        
        return true;
    }

    /**
     * @description 获取当前用户的JWT令牌
     * @return String JWT令牌，未登录返回null
     * @author yslg
     * @since 2025-10-07
     */
    public static String getCurrentToken() {
        return ServletUtil.getToken();
    }
}
