package cn.nianxx.thhotel.platform.security.service.impl;

import cn.nianxx.thhotel.platform.security.common.dto.AuthenticatedUserContext;
import cn.nianxx.thhotel.platform.security.service.AdminAuthorizationService;
import cn.nianxx.thhotel.platform.security.service.CurrentUserContextService;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;

/**
 * 管理后台强制鉴权服务实现。只负责鉴权语义，不读取业务数据。
 */
@Service
public class AdminAuthorizationServiceImpl implements AdminAuthorizationService {

    private final CurrentUserContextService currentUserContextService;
    private final HttpServletRequest request;

    /**
     * 注入当前用户上下文服务，复用可选 token 解析后的请求上下文。
     */
    public AdminAuthorizationServiceImpl(
            CurrentUserContextService currentUserContextService,
            HttpServletRequest request) {
        this.currentUserContextService = currentUserContextService;
        this.request = request;
    }

    /**
     * 要求当前请求已登录；没有有效 token 时返回管理后台专用 401。
     */
    @Override
    public AuthenticatedUserContext requireLogin() {
        return currentUserContextService.currentUser()
                .orElseThrow(this::missingOrInvalidLogin);
    }

    /**
     * 要求当前请求用户拥有指定权限码；已登录但无权限时返回 403。
     */
    @Override
    public AuthenticatedUserContext requirePermission(String permissionCode) {
        AuthenticatedUserContext context = requireLogin();
        if (permissionCode == null || permissionCode.isBlank()
                || !context.permissionCodes().contains(permissionCode)) {
            throw new AdminAuthorizationException(
                    HttpStatus.FORBIDDEN,
                    "ADMIN_PERMISSION_DENIED",
                    "当前用户没有访问该系统管理能力的权限。");
        }
        return context;
    }

    private AdminAuthorizationException missingOrInvalidLogin() {
        String authorizationHeader = request.getHeader("Authorization");
        if (hasBearerToken(authorizationHeader)) {
            return new AdminAuthorizationException(
                    HttpStatus.UNAUTHORIZED,
                    "AUTH_SESSION_INVALID",
                    "登录已失效，请重新登录。");
        }
        return new AdminAuthorizationException(
                HttpStatus.UNAUTHORIZED,
                "ADMIN_AUTH_REQUIRED",
                "请先登录后再访问系统管理后台。");
    }

    private boolean hasBearerToken(String authorizationHeader) {
        if (authorizationHeader == null || authorizationHeader.isBlank()) {
            return false;
        }
        String prefix = "Bearer ";
        return authorizationHeader.regionMatches(true, 0, prefix, 0, prefix.length())
                && !authorizationHeader.substring(prefix.length()).trim().isBlank();
    }
}
