package cn.meowrain.aioj.backend.auth.oauth2.controller;

import cn.hutool.core.util.StrUtil;
import cn.meowrain.aioj.backend.auth.clients.UserClient;
import cn.meowrain.aioj.backend.auth.dto.resp.UserAuthRespDTO;
import cn.meowrain.aioj.backend.auth.oauth2.dto.UserInfoResponse;
import cn.meowrain.aioj.backend.auth.oauth2.exception.OAuth2Exception;
import cn.meowrain.aioj.backend.framework.security.utils.JwtUtil;

import cn.meowrain.aioj.backend.framework.core.web.Result;
import io.jsonwebtoken.Claims;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * OAuth2 UserInfo 端点（OIDC） 返回当前用户的信息
 *
 * @author meowrain
 * @since 2025-12-14
 */
@Slf4j
@RestController
@RequestMapping("/oauth2/userinfo")
@RequiredArgsConstructor
@Tag(name = "OAuth2 UserInfo 端点", description = "OIDC UserInfo 相关接口")
public class OAuth2UserInfoController {

	private final JwtUtil jwtUtil;

	private final UserClient userClient;

	/**
	 * UserInfo 端点
	 * @param authorization Authorization Header（Bearer Token）
	 * @return 用户信息
	 */
	@GetMapping
	@Operation(summary = "获取用户信息", description = "根据 Access Token 返回用户信息（OIDC）")
	public UserInfoResponse userInfo(@RequestHeader("Authorization") String authorization) {
		log.info("收到 UserInfo 请求");

		// 1. 提取 Access Token
		String accessToken = extractBearerToken(authorization);

		// 2. 验证 Token
		if (!jwtUtil.isTokenValid(accessToken)) {
			log.warn("Access Token 无效或已过期");
			throw new OAuth2Exception("invalid_token", "Access Token 无效或已过期", 401);
		}

		// 3. 解析 Token 获取用户 ID
		Claims claims = jwtUtil.parseClaims(accessToken);
		String userIdStr = claims.get("userId", String.class);
		if (userIdStr == null) {
			userIdStr = claims.getSubject();
		}

		Long userId = Long.parseLong(userIdStr);

		// 4. 调用 user-service 获取用户信息
		Result<UserAuthRespDTO> userResult = userClient.getUserById(userId);
		if (userResult == null || userResult.getData() == null) {
			log.error("获取用户信息失败: userId={}", userId);
			throw new OAuth2Exception("server_error", "获取用户信息失败", 500);
		}

		UserAuthRespDTO user = userResult.getData();

		// 5. 构造 UserInfo 响应
		// 注意：根据 scope 返回不同的字段，这里简化处理返回所有字段
		UserInfoResponse response = UserInfoResponse.builder()
			.sub(String.valueOf(user.getId())) // Subject（用户唯一标识）
			.name(user.getUserName()) // 用户全名
			.preferredUsername(user.getUserAccount()) // 用户名
			.email(null) // TODO: 从用户信息中获取邮箱
			.emailVerified(false) // TODO: 从用户信息中获取邮箱验证状态
			.picture(null) // 用户头像
			.role(user.getUserRole()) // 用户角色
			.build();

		log.info("返回 UserInfo: userId={}, username={}", userId, user.getUserAccount());

		return response;
	}

	/**
	 * 从 Authorization Header 中提取 Bearer Token
	 * @param authorization Authorization Header
	 * @return Access Token
	 */
	private String extractBearerToken(String authorization) {
		if (StrUtil.isBlank(authorization)) {
			throw new OAuth2Exception("invalid_request", "缺少 Authorization Header", 401);
		}

		if (!authorization.startsWith("Bearer ")) {
			throw new OAuth2Exception("invalid_request", "Authorization Header 格式错误，应为 'Bearer {token}'", 401);
		}

		return authorization.substring(7);
	}

}
