package com.chinaweal.aiccs.org.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.chinaweal.aiccs.common.base.controller.BaseController;
import com.chinaweal.aiccs.common.constant.CommonConstants;
import com.chinaweal.aiccs.common.util.OAuthTokenUtils;
import com.chinaweal.aiccs.common.util.SM4Utils;
import com.chinaweal.aiccs.common.util.StringUtils;
import com.chinaweal.aiccs.org.entity.*;
import com.chinaweal.aiccs.org.entity.dto.*;
import com.chinaweal.aiccs.org.entity.vo.UserLoginSelectionVO;
import com.chinaweal.aiccs.org.service.*;
import com.chinaweal.aiccs.redis.RedisService;
import com.chinaweal.aicorg.model.AICUser;
import com.chinaweal.aicorg.services.OrgUM;
import com.chinaweal.youfool.framework.springboot.rest.RestResult;
import com.chinaweal.youfool.framework.springboot.rest.ResultCode;
import com.chinaweal.youfool.framework.sso.util.SSOUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * Oauth登录控制器
 *
 * @author lroyia
 * @since 2025/11/21 14:26
 **/
@Slf4j
@Api(tags = "Oauth2登录接口")
@RestController
@RequestMapping("oauth2")
public class OAuth2Controller extends BaseController {

    @Value("${oauth2.sm4.key}")
    private String sm4Key;
    @Autowired
    private IOauthClientService oauthClientService;
    @Autowired
    private IOauthAuthorizationCodeService authorizationCodeService;
    @Autowired
    private IOauthAccessTokenService oauthTokenService;
    @Autowired
    private IImsUserService iImsUserService;
    @Autowired
    private IUserSupInfoService userSupInfoService;
    @Autowired
    private OrgUM orgUM;
    @Autowired
    private IUnifiedAuthService unifiedAuthService;
    @Autowired
    private UserBaseService userBaseService;
    @Autowired
    private TUsersService usersService;
    @Autowired
    private RedisService redisService;

    private final static String USER_LOGIN_SELECTION = "USER_LOGIN_SELECTION:";

    /**
     * OAuth授权端点
     */
    @GetMapping("/authorize")
    public ResponseEntity<?> authorize(
            @RequestParam("response_type") String responseType,
            @RequestParam("redirect_uri") String redirectUri,
            @RequestParam("client_id") String clientId,
            @RequestParam(value = "state", required = false) String state,
            @RequestParam(value = "scope", required = false) String scope,
            HttpServletRequest request) {

        AuthorizationRequestDTO authorizationRequest = new AuthorizationRequestDTO();
        authorizationRequest.setResponseType(responseType);
        authorizationRequest.setRedirectUri(redirectUri);
        authorizationRequest.setClientId(clientId);
        authorizationRequest.setState(state);
        authorizationRequest.setScope(scope);

        try {
            // 验证响应类型
            if (!OAuthTokenUtils.isValidResponseType(authorizationRequest.getResponseType())) {
                return buildErrorRedirect(authorizationRequest, "unsupported_response_type",
                        "不支持的响应类型");
            }

            // 验证客户端
            if (!OAuthTokenUtils.isValidClientId(authorizationRequest.getClientId())) {
                return buildErrorRedirect(authorizationRequest, "invalid_request",
                        "无效的客户端ID");
            }

            // 获取客户端信息
            OauthClient client = oauthClientService.getByClientId(authorizationRequest.getClientId());
            if (client == null || !"1".equals(client.getIsActive())) {
                return buildErrorRedirect(authorizationRequest, "invalid_client",
                        "客户端不存在或已禁用");
            }

            // 验证重定向URI
            if (StringUtils.isNotBlank(authorizationRequest.getRedirectUri()) &&
                    !OAuthTokenUtils.isValidRedirectUri(authorizationRequest.getRedirectUri())) {
                return buildErrorRedirect(authorizationRequest, "invalid_request",
                        "无效的重定向URI");
            }

            // 验证授权范围
            if (StringUtils.isNotBlank(authorizationRequest.getScope()) &&
                    !OAuthTokenUtils.isValidScope(authorizationRequest.getScope())) {
                return buildErrorRedirect(authorizationRequest, "invalid_scope",
                        "无效的授权范围");
            }

            // 检查用户是否已登录（这里简化处理，实际应该检查session）
            AICUser currentUser = getLoginUser(request);
            String userId = currentUser.getPrimaryKey();
            String userName = currentUser.getName();

            if (StringUtils.isBlank(userId)) {
                // 用户未登录，重定向到登录页面
                String loginRedirect = String.format("https://www.chinaweal.com.cn/pms-api/oauth/authorize?response_type=%s&redirect_uri=%s&client_id=%s&state=%s&scope=%s",
                        StringUtils.trimToEmpty(responseType),
                        URLEncoder.encode(StringUtils.trimToEmpty(redirectUri), "UTF-8"),
                        StringUtils.trimToEmpty(clientId), StringUtils.trimToEmpty(state), StringUtils.trimToEmpty(scope));
                return ResponseEntity.status(HttpStatus.FOUND)
                        .location(java.net.URI.create(String.format("https://www.chinaweal.com.cn/pms/#/login?redirect=%s",
                                URLEncoder.encode(loginRedirect, "UTF-8")))).build();
            }

            // 根据响应类型处理
            if ("code".equals(authorizationRequest.getResponseType())) {
                // 授权码模式
                String code = authorizationCodeService.createAuthorizationCode(
                        authorizationRequest, userId, userName);

                redirectUri = buildRedirectUri(authorizationRequest,
                        "code=" + URLEncoder.encode(code, "UTF-8"));
                return ResponseEntity.status(HttpStatus.FOUND)
                        .location(java.net.URI.create(redirectUri))
                        .build();

            } else if ("token".equals(authorizationRequest.getResponseType())) {
                // 简化模式（不推荐，但为了完整性实现）
                TokenRequestDTO tokenRequest = new TokenRequestDTO();
                tokenRequest.setGrantType("implicit");
                tokenRequest.setClientId(authorizationRequest.getClientId());
                tokenRequest.setScope(authorizationRequest.getScope());

                TokenResponseDTO tokenResponse = oauthTokenService.createAccessToken(
                        tokenRequest, userId, userName);

                String fragment = "access_token=" + URLEncoder.encode(tokenResponse.getAccessToken(), "UTF-8") +
                        "&token_type=" + tokenResponse.getTokenType() +
                        "&expires_in=" + tokenResponse.getExpiresIn();
                if (StringUtils.isNotBlank(tokenResponse.getScope())) {
                    fragment += "&scope=" + URLEncoder.encode(tokenResponse.getScope(), "UTF-8");
                }
                if (StringUtils.isNotBlank(authorizationRequest.getState())) {
                    fragment += "&state=" + URLEncoder.encode(authorizationRequest.getState(), "UTF-8");
                }

                redirectUri = authorizationRequest.getRedirectUri() + "#" + fragment;
                return ResponseEntity.status(HttpStatus.FOUND)
                        .location(java.net.URI.create(redirectUri))
                        .build();
            }

            return buildErrorRedirect(authorizationRequest, "unsupported_response_type",
                    "不支持的响应类型");

        } catch (Exception e) {
            return buildErrorRedirect(authorizationRequest, "server_error",
                    "服务器内部错误: " + e.getMessage());
        }
    }

    /**
     * OAuth令牌端点
     */
    @PostMapping("/token")
    public ResponseEntity<?> token(
            @RequestParam("grant_type") String grantType,
            @RequestParam(value = "code", required = false) String code,
            @RequestParam(value = "redirect_uri", required = false) String redirectUri,
            @RequestParam(value = "refresh_token", required = false) String refreshToken,
            @RequestParam("client_id") String clientId,
            @RequestParam(value = "client_secret", required = false) String clientSecret,
            @RequestParam(value = "scope", required = false) String scope,
            @RequestParam(value = "username", required = false) String username,
            @RequestParam(value = "password", required = false) String password,
            HttpServletRequest request) {

        try {
            // 验证授权类型
            if (!OAuthTokenUtils.isValidGrantType(grantType)) {
                OAuthErrorResponseDTO error = new OAuthErrorResponseDTO(
                        "unsupported_grant_type", "不支持的授权类型");
                return ResponseEntity.badRequest().body(error);
            }

            // 验证客户端
            if (!OAuthTokenUtils.isValidClientId(clientId) ||
                    !oauthClientService.validateClient(clientId, clientSecret)) {
                OAuthErrorResponseDTO error = new OAuthErrorResponseDTO(
                        "invalid_client", "客户端认证失败");
                return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(error);
            }

            TokenResponseDTO tokenResponse;

            switch (grantType) {
                case "authorization_code":
                    // 授权码模式
                    if (StringUtils.isBlank(code)) {
                        OAuthErrorResponseDTO error = new OAuthErrorResponseDTO(
                                "invalid_request", "授权码不能为空");
                        return ResponseEntity.badRequest().body(error);
                    }

                    final OauthAuthorizationCode authCode = authorizationCodeService.validateAuthorizationCode(
                            code, clientId);
                    if (authCode == null) {
                        OAuthErrorResponseDTO error = new OAuthErrorResponseDTO(
                                "invalid_grant", "无效的授权码");
                        return ResponseEntity.badRequest().body(error);
                    }

                    // 创建TokenRequestDTO用于服务层调用
                    TokenRequestDTO tokenRequest = new TokenRequestDTO();
                    tokenRequest.setGrantType(grantType);
                    tokenRequest.setClientId(clientId);
                    tokenRequest.setClientSecret(clientSecret);
                    tokenRequest.setCode(code);
                    tokenRequest.setRedirectUri(redirectUri);
                    tokenRequest.setScope(scope);

                    tokenResponse = oauthTokenService.createAccessToken(
                            tokenRequest, authCode.getUserId(), authCode.getUserName());

                    // 消费授权码
                    authorizationCodeService.consumeAuthorizationCode(code, clientId);
                    break;

                case "refresh_token":
                    // 刷新令牌模式
                    if (StringUtils.isBlank(refreshToken)) {
                        OAuthErrorResponseDTO error = new OAuthErrorResponseDTO(
                                "invalid_request", "刷新令牌不能为空");
                        return ResponseEntity.badRequest().body(error);
                    }

                    tokenResponse = oauthTokenService.refreshAccessToken(
                            refreshToken, clientId);
                    if (tokenResponse == null) {
                        OAuthErrorResponseDTO error = new OAuthErrorResponseDTO(
                                "invalid_grant", "无效的刷新令牌");
                        return ResponseEntity.badRequest().body(error);
                    }
                    break;

                case "client_credentials":
                    // 客户端凭证模式
                    TokenRequestDTO clientCredentialsRequest = new TokenRequestDTO();
                    clientCredentialsRequest.setGrantType(grantType);
                    clientCredentialsRequest.setClientId(clientId);
                    clientCredentialsRequest.setClientSecret(clientSecret);
                    clientCredentialsRequest.setScope(scope);

                    tokenResponse = oauthTokenService.createAccessToken(
                            clientCredentialsRequest, null, null);
                    break;

                case "password":
                    // 密码模式（不推荐，但为了完整性实现）
                    if (StringUtils.isBlank(username) || StringUtils.isBlank(password)) {
                        OAuthErrorResponseDTO error = new OAuthErrorResponseDTO(
                                "invalid_request", "用户名和密码不能为空");
                        return ResponseEntity.badRequest().body(error);
                    }

                    // 这里应该验证用户凭据（简化处理）
                    if (!validateUserCredentials(username, password)) {
                        OAuthErrorResponseDTO error = new OAuthErrorResponseDTO(
                                "invalid_grant", "用户名或密码错误");
                        return ResponseEntity.badRequest().body(error);
                    }

                    TokenRequestDTO passwordRequest = new TokenRequestDTO();
                    passwordRequest.setGrantType(grantType);
                    passwordRequest.setClientId(clientId);
                    passwordRequest.setClientSecret(clientSecret);
                    passwordRequest.setUsername(username);
                    passwordRequest.setPassword(password);
                    passwordRequest.setScope(scope);

                    tokenResponse = oauthTokenService.createAccessToken(
                            passwordRequest, username, username);
                    break;

                default:
                    OAuthErrorResponseDTO error = new OAuthErrorResponseDTO(
                            "unsupported_grant_type", "不支持的授权类型");
                    return ResponseEntity.badRequest().body(error);
            }

            return ResponseEntity.ok(tokenResponse);

        } catch (Exception e) {
            OAuthErrorResponseDTO error = new OAuthErrorResponseDTO(
                    "server_error", "服务器内部错误: " + e.getMessage());
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(error);
        }
    }

    /**
     * OAuth令牌撤销端点
     */
    @PostMapping("/revoke")
    public ResponseEntity<?> revoke(
            @RequestParam("token") String token,
            @RequestParam(value = "token_type_hint", required = false) String tokenTypeHint,
            @RequestParam(value = "client_id") String clientId,
            @RequestParam(value = "client_secret", required = false) String clientSecret,
            HttpServletRequest request) {

        try {
            // 验证客户端（简化处理，实际应该验证）
            if (StringUtils.isBlank(clientId)) {
                OAuthErrorResponseDTO error = new OAuthErrorResponseDTO(
                        "invalid_client", "客户端ID不能为空");
                return ResponseEntity.badRequest().body(error);
            }

            // 撤销令牌
            boolean revoked = oauthTokenService.revokeToken(token, tokenTypeHint);

            // 根据OAuth规范，撤销成功时返回200 OK
            return ResponseEntity.ok().build();

        } catch (Exception e) {
            OAuthErrorResponseDTO error = new OAuthErrorResponseDTO(
                    "server_error", "服务器内部错误: " + e.getMessage());
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(error);
        }
    }

    /**
     * OAuth令牌验证端点（可选）
     */
    @GetMapping("/introspect")
    public ResponseEntity<?> introspect(
            @RequestParam("token") String token,
            @RequestParam(value = "client_id") String clientId,
            @RequestParam(value = "client_secret", required = false) String clientSecret) {

        try {
            // 验证客户端
            if (StringUtils.isBlank(clientId)) {
                OAuthErrorResponseDTO error = new OAuthErrorResponseDTO(
                        "invalid_client", "客户端ID不能为空");
                return ResponseEntity.badRequest().body(error);
            }

            // 验证令牌
            OauthAccessToken accessToken = oauthTokenService.validateAccessToken(token);
            if (accessToken != null && "1".equals(accessToken.getIsActive())) {
                // 令牌有效
                return ResponseEntity.ok("令牌有效");
            } else {
                // 令牌无效
                return ResponseEntity.status(400).body("令牌无效或已过期");
            }

        } catch (Exception e) {
            OAuthErrorResponseDTO error = new OAuthErrorResponseDTO(
                    "server_error", "服务器内部错误: " + e.getMessage());
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(error);
        }
    }

    /**
     * OAuth用户信息端点
     */
    @RequestMapping(value = "/userinfo", method = {RequestMethod.GET, RequestMethod.POST})
    public ResponseEntity<?> userinfo(HttpServletRequest request) {
        try {
            // 从Authorization Header中获取Bearer Token
            String authorizationHeader = request.getHeader("Authorization");
            if (StringUtils.isBlank(authorizationHeader) || !authorizationHeader.startsWith("Bearer ")) {
                OAuthErrorResponseDTO error = new OAuthErrorResponseDTO(
                        "invalid_request", "缺少或无效的Authorization header");
                return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(error);
            }

            String accessToken = authorizationHeader.substring(7); // 移除 "Bearer " 前缀

            // 验证访问令牌
            OauthAccessToken tokenInfo = oauthTokenService.validateAccessToken(accessToken);
            if (tokenInfo == null || !"1".equals(tokenInfo.getIsActive())) {
                OAuthErrorResponseDTO error = new OAuthErrorResponseDTO(
                        "invalid_token", "访问令牌无效或已过期");
                return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(error);
            }

            // 检查令牌是否过期
            if (tokenInfo.getExpiresIn() != null && OAuthTokenUtils.isTokenExpired(tokenInfo.getExpiresIn())) {
                OAuthErrorResponseDTO error = new OAuthErrorResponseDTO(
                        "invalid_token", "访问令牌已过期");
                return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(error);
            }

            // 根据授权范围决定返回的用户信息详细程度
            UserinfoResponseDTO userinfo;
            String scope = tokenInfo.getScope();

            if (StringUtils.isNotBlank(scope) && scope.contains("profile")) {
                // 如果授权范围包含profile，返回完整用户信息
                userinfo = getUserinfoByUserId(tokenInfo.getUserId(), scope);
            } else {
                // 否则只返回基本信息
                userinfo = UserinfoResponseDTO.createBasicUserInfo(
                        tokenInfo.getUserId(),
                        tokenInfo.getUserName(),
                        tokenInfo.getUserName() // 简化处理，使用用户名作为姓名
                );
            }
            log.info("OAuth2获取用户消息：{}", JSON.toJSONString(userinfo));
            return ResponseEntity.ok(userinfo);

        } catch (Exception e) {
            OAuthErrorResponseDTO error = new OAuthErrorResponseDTO(
                    "server_error", "服务器内部错误: " + e.getMessage());
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(error);
        }
    }

    // 私有辅助方法

    /**
     * 构建错误重定向URL
     */
    private ResponseEntity<?> buildErrorRedirect(AuthorizationRequestDTO request, String error, String description) {
        try {
            String redirectUri = request.getRedirectUri();
            if (StringUtils.isNotBlank(redirectUri)) {
                String errorParams = "error=" + URLEncoder.encode(error, "UTF-8") +
                        "&error_description=" + URLEncoder.encode(description, "UTF-8");

                if (StringUtils.isNotBlank(request.getState())) {
                    errorParams += "&state=" + URLEncoder.encode(request.getState(), "UTF-8");
                }

                String fullRedirectUri;
                if (redirectUri.contains("?")) {
                    fullRedirectUri = redirectUri + "&" + errorParams;
                } else {
                    fullRedirectUri = redirectUri + "?" + errorParams;
                }

                return ResponseEntity.status(HttpStatus.FOUND)
                        .location(java.net.URI.create(fullRedirectUri))
                        .build();
            } else {
                // 如果没有重定向URI，返回错误响应
                OAuthErrorResponseDTO errorResponse = new OAuthErrorResponseDTO(error, description, request.getState());
                return ResponseEntity.badRequest().body(errorResponse);
            }
        } catch (Exception e) {
            OAuthErrorResponseDTO errorResponse = new OAuthErrorResponseDTO(error, description, request.getState());
            return ResponseEntity.badRequest().body(errorResponse);
        }
    }

    /**
     * 构建重定向URI
     */
    private String buildRedirectUri(AuthorizationRequestDTO request, String params) {
        String redirectUri = request.getRedirectUri();
        if (StringUtils.isNotBlank(redirectUri)) {
            if (redirectUri.contains("?")) {
                redirectUri += "&" + params;
            } else {
                redirectUri += "?" + params;
            }

            if (StringUtils.isNotBlank(request.getState())) {
                redirectUri += "&state=" + URLEncoder.encode(request.getState());
            }
        }
        return redirectUri;
    }

    /**
     * 验证用户凭据（简化处理）
     */
    private boolean validateUserCredentials(String username, String password) {
        // 这里应该实现真正的用户凭据验证
        // 暂时简单验证用于测试
        return "admin".equals(username) && "password".equals(password);
    }

    /**
     * 根据用户ID获取用户信息（简化处理）
     */
    private UserinfoResponseDTO getUserinfoByUserId(String userId, String scope) {
        // 这里应该从数据库或其他服务获取真实的用户信息
        // 暂时返回模拟数据用于测试
        AICUser byId = orgUM.findUserByPrimaryKey(userId);
        final UserinfoResponseDTO fullUserInfo = UserinfoResponseDTO.createFullUserInfo(
                byId.getPrimaryKey(),
                byId.getPrimaryKey(),
                byId.getName(),
                null,
                null,
                null,
                null
        );
        fullUserInfo.setPicture(null);
        return fullUserInfo;
    }

    /**
     * 获取一个加密登录的登录用数据串
     *
     * @param request 请求，用户获取当前登录信息
     * @return 加密串
     */
    @ApiOperation("获取一个加密登录的登录用数据串")
    @GetMapping("sm4/encrypted/data")
    public RestResult<String> getSm4EncryptedData(HttpServletRequest request) {
        AICUser loginUser = getLoginUser(request);
        if (loginUser == null) {
            return RestResult.error(ResultCode.USER_NOT_LOGGED_IN);
        }
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("userId", loginUser.getPrimaryKey());
        jsonObject.put("username", loginUser.getEname());
        jsonObject.put("nickname", loginUser.getName());
        jsonObject.put("expired", System.currentTimeMillis() + 1000 * 60 * 5);// 增加有效期
        return RestResult.ok(SM4Utils.encrypt(jsonObject.toJSONString(), sm4Key));
    }

    // ==================== 统一认证平台相关接口 ====================

    /**
     * 跳转到统一认证平台登录页面
     *
     * @param state 状态参数，用于防止CSRF攻击
     * @return 登录URL
     */
    @ApiOperation("跳转到统一认证平台登录页面")
    @GetMapping("/unified/login")
    public ResponseEntity<?> unifiedLogin(
            @RequestParam(value = "state", required = false) String state) {
        try {
            String loginUrl = unifiedAuthService.buildLoginUrl(state);
            log.info("跳转到统一认证平台登录页面: {}", loginUrl);
            return ResponseEntity.status(HttpStatus.FOUND)
                    .location(java.net.URI.create(loginUrl))
                    .build();
        } catch (Exception e) {
            log.error("跳转到统一认证平台登录页面失败", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body("跳转失败: " + e.getMessage());
        }
    }

    /**
     * 统一认证平台OAuth2回调接口
     *
     * @param code  授权码
     * @param state 状态参数
     * @return 登录结果
     */
    @ApiOperation("统一认证平台OAuth2回调接口")
    @GetMapping("/callback")
    public ResponseEntity<?> callback(
            @RequestParam(value = "code", required = false) String code,
            @RequestParam(value = "state", required = false) String state,
            @RequestParam(value = "error", required = false) String error,
            @RequestParam(value = "error_description", required = false) String errorDescription,
            HttpServletRequest request) {

        try {
            // 检查是否有错误
            if (StringUtils.isNotBlank(error)) {
                log.error("统一认证平台返回错误: {} - {}", error, errorDescription);
                // 重定向到错误页面或首页
                return ResponseEntity.status(HttpStatus.FOUND)
                        .location(java.net.URI.create("/integration/#/login?error=" + URLEncoder.encode(error + ":" + errorDescription, "UTF-8")))
                        .build();
            }

            // 检查授权码
            if (StringUtils.isBlank(code)) {
                log.error("未收到授权码");
                return ResponseEntity.status(HttpStatus.FOUND)
                        .location(java.net.URI.create("/integration/#/login?error=no_code"))
                        .build();
            }

            String requestId = StringUtils.getUUID();
            log.info("收到统一认证平台回调，code: {}, state: {}", code, state);

            // 使用授权码获取访问令牌
            UnifiedAuthDTO.TokenResponse tokenResponse = unifiedAuthService.getAccessToken(code);
            if (StringUtils.isNotBlank(tokenResponse.getError())) {
                log.error("requestId：{}，获取访问令牌失败: {} - {}", requestId, tokenResponse.getError(), tokenResponse.getError_description());
                return ResponseEntity.status(HttpStatus.FOUND)
                        .location(java.net.URI.create("/integration/#/login?requestId=" + requestId + "&error=" + URLEncoder.encode(tokenResponse.getError_description(), "UTF-8")))
                        .build();
            }

            // 使用访问令牌获取用户信息
            UnifiedAuthDTO.UserInfoResponse userInfo = unifiedAuthService.getUserInfo(tokenResponse.getAccess_token());
            if (StringUtils.isNotBlank(userInfo.getError())) {
                log.error("requestId：{}，获取用户信息失败: {} - {}", requestId, userInfo.getError(), userInfo.getError_description());
                return ResponseEntity.status(HttpStatus.FOUND)
                        .location(java.net.URI.create("/integration/#/login?requestId=" + requestId + "&error=" + URLEncoder.encode(userInfo.getError_description(), "UTF-8")))
                        .build();
            }

            // 获取到用户信息，进行本地登录处理
            userInfo.setIdCard(StringUtils.trimToEmpty(userInfo.getIdCard()));
            log.info("统一认证平台OAuth2回调接口，获取到用户信息，requestId：{}，用户信息：{}", requestId, JSON.toJSONString(userInfo));

            // 根据证件号查询IMS用户信息
            if (StringUtils.isBlank(userInfo.getIdCard())) {
                return ResponseEntity.status(HttpStatus.FOUND)
                        .location(java.net.URI.create("/integration/#/login?requestId=" + requestId + "&error=" + URLEncoder.encode("统一身份认证回调信息不足以支持登录，请联系系统管理员", "UTF-8")))
                        .build();
            }

            // 处理身份证末尾x的大小写兼容
            Set<String> idCardList = new HashSet<>(2);
            String idCard = userInfo.getIdCard();
            idCardList.add(DigestUtils.md5DigestAsHex(idCard.toUpperCase().getBytes(StandardCharsets.UTF_8)));
            idCardList.add(DigestUtils.md5DigestAsHex(idCard.toLowerCase().getBytes(StandardCharsets.UTF_8)));

            List<UserSupInfo> supList = userSupInfoService.lambdaQuery().in(UserSupInfo::getIdcardAbstr, idCardList).list();
            if (CollectionUtils.isEmpty(supList)) {
                return ResponseEntity.status(HttpStatus.FOUND)
                        .location(java.net.URI.create("/integration/#/login?requestId=" + requestId + "&error=" + URLEncoder.encode("无匹配的综合监管用户，请联系系统管理员", "UTF-8")))
                        .build();
            }
            List<TUsers> list = usersService.lambdaQuery().in(TUsers::getUserid, supList.stream().map(UserSupInfo::getUserid).collect(Collectors.toList()))
                    .eq(TUsers::getDeleted, CommonConstants.FALSE_0).list();
            if (CollectionUtils.isEmpty(list)) {
                return ResponseEntity.status(HttpStatus.FOUND)
                        .location(java.net.URI.create("/integration/#/login?requestId=" + requestId + "&error=" + URLEncoder.encode("无匹配的综合监管用户，请联系系统管理员", "UTF-8")))
                        .build();
            }
            // 存储候选
            if (list.size() > 1) {
                redisService.set(USER_LOGIN_SELECTION + code, JSON.toJSONString(list), 900);
                return ResponseEntity.status(HttpStatus.FOUND)
                        .location(java.net.URI.create("/integration/#/oauth2?requestId=" + requestId + "&code=" + code))
                        .build();
            }

            TUsers tuser = list.get(0);

            RestResult<AICUser> loginResult = userBaseService.login(tuser.getUsername(), "ChinaWeal_2026");
            AICUser user = loginResult.getData();
            // 将登录了的用户信息存至Session
            request.getSession().setAttribute(DRUID_SESSION_KEY, String.format("%s(%s)", user.getName(), user.getEname()));
            redisService.remove(tuser.getUsername());
            SSOUtil.login(user);

            // 跳转到首页
            return ResponseEntity.status(HttpStatus.FOUND)
                    .location(java.net.URI.create("/integration/#/"))
                    .build();

        } catch (Exception e) {
            log.error("统一认证平台回调处理失败", e);
            try {
                return ResponseEntity.status(HttpStatus.FOUND)
                        .location(java.net.URI.create("/integration/#/login?error=" + URLEncoder.encode("系统错误: " + e.getMessage(), "UTF-8")))
                        .build();
            } catch (UnsupportedEncodingException ex) {
                throw new RuntimeException(ex);
            }
        }
    }

    /**
     * 根据登录编码获取候选登录用户
     *
     * @param code 查询编码
     * @return 查询结果
     */
    @ApiOperation("根据登录编码获取候选登录用户")
    @GetMapping("/unified/selection")
    public RestResult<List<UserLoginSelectionVO>> getLoginSelection(@ApiParam("查询编码") @RequestParam String code) {
        String json = redisService.get(USER_LOGIN_SELECTION + code);
        if (StringUtils.isBlank(json)) {
            return RestResult.error(ResultCode.DATA_NONE);
        }
        List<TUsers> list = JSONArray.parseArray(json, TUsers.class);
        if (CollectionUtils.isEmpty(list)) {
            return RestResult.error(ResultCode.DATA_NONE);
        }
        List<UserLoginSelectionVO> loginSelectionList = new ArrayList<>(list.size());
        for (TUsers each : list) {
            UserLoginSelectionVO atom = new UserLoginSelectionVO();
            atom.setUserId(each.getUserid());
            atom.setUsername(each.getUsername());
            atom.setRealname(each.getRealname());
            loginSelectionList.add(atom);
        }
        return RestResult.ok(loginSelectionList);
    }

    /**
     * 根据登录编码获取候选登录用户
     *
     * @param code 查询编码
     * @return 查询结果
     */
    @ApiOperation("根据登录编码获取候选登录用户")
    @PostMapping("/unified/select/login")
    public RestResult<?> selectLogin(@ApiParam("查询编码") @RequestParam String code, @ApiParam("用户id") @RequestParam String userId,
                                     HttpServletRequest request) {
        String json = redisService.get(USER_LOGIN_SELECTION + code);
        if (StringUtils.isBlank(json)) {
            return RestResult.error(ResultCode.DATA_NONE);
        }
        List<TUsers> list = JSONArray.parseArray(json, TUsers.class);
        if (CollectionUtils.isEmpty(list)) {
            return RestResult.error(ResultCode.DATA_NONE);
        }
        TUsers tuser = list.stream().filter(each -> StringUtils.equals(each.getUserid(), userId)).findFirst().orElse(null);
        if (tuser == null) {
            return RestResult.error(ResultCode.DATA_NONE);
        }

        RestResult<AICUser> loginResult = userBaseService.login(tuser.getUsername(), "ChinaWeal_2026");
        AICUser user = loginResult.getData();
        // 将登录了的用户信息存至Session
        request.getSession().setAttribute(DRUID_SESSION_KEY, String.format("%s(%s)", user.getName(), user.getEname()));
        redisService.remove(tuser.getUsername());
        SSOUtil.login(user);
        if (StringUtils.notEquals(code, "test")) {
            redisService.remove(USER_LOGIN_SELECTION + code);
        }
        return RestResult.ok();
    }

    /**
     * 统一认证平台单点登出
     *
     * @param request HTTP请求
     * @return 登出结果
     */
    @ApiOperation("统一认证平台单点登出")
    @GetMapping("/unified/logout")
    public ResponseEntity<?> unifiedLogout(HttpServletRequest request) {
        try {
            // 获取当前用户的访问令牌（需要从session或其他存储中获取）
            // 这里简化处理，实际需要根据系统现有的会话管理机制实现
            String accessToken = request.getParameter("access_token");

            if (StringUtils.isBlank(accessToken)) {
                return ResponseEntity.ok(RestResult.error(ResultCode.PARAM_IS_BLANK, "访问令牌不能为空"));
            }

            // 调用统一认证平台登出接口
            UnifiedAuthDTO.LogoutResponse response = unifiedAuthService.logout(accessToken);

            if ("0".equals(response.getCode())) {
                // 清除本地会话
                // 这里需要根据系统现有的会话管理机制实现
                return ResponseEntity.ok(RestResult.ok("登出成功"));
            } else {
                return ResponseEntity.ok(RestResult.error(ResultCode.BUSINESS_LOGIC_ERROR, response.getMessage()));
            }

        } catch (Exception e) {
            log.error("统一认证平台单点登出失败", e);
            return ResponseEntity.ok(RestResult.error(ResultCode.BUSINESS_LOGIC_ERROR, "登出失败: " + e.getMessage()));
        }
    }
}
