package com.agent.management.config;

import com.agent.management.external.dto.ApiError;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;

/**
 * 外部 API（/api/v1/**）鉴权过滤器：
 * - 校验 X-API-Key 头部
 * - 将匹配到的 KeyEntry 放入请求属性，供 Controller 二次校验工作流白名单
 * - 总开关 external.api.enabled=false 时直接返回 404
 *
 * 已通过认证的 KeyEntry 通过 {@code request.setAttribute(ATTR_KEY_ENTRY)} 暴露。
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class ExternalApiAuthFilter extends OncePerRequestFilter {

    public static final String ATTR_KEY_ENTRY = "externalApi.keyEntry";
    private static final String HEADER = "X-API-Key";

    private final ExternalApiProperties properties;
    private final ObjectMapper objectMapper = new ObjectMapper();

    @Override
    protected void doFilterInternal(HttpServletRequest request,
                                    HttpServletResponse response,
                                    FilterChain filterChain) throws ServletException, IOException {
        // 仅拦截 /api/v1/**
        String path = request.getRequestURI();
        if (!path.startsWith("/api/v1/")) {
            filterChain.doFilter(request, response);
            return;
        }

        // 总开关
        if (!properties.isEnabled()) {
            writeError(response, HttpStatus.NOT_FOUND, "EXTERNAL_API_DISABLED", "外部 API 未启用");
            return;
        }

        // 校验 API Key
        String apiKey = request.getHeader(HEADER);
        ExternalApiProperties.KeyEntry entry = properties.lookup(apiKey);
        if (entry == null) {
            log.warn("[ExternalApi] 鉴权失败 path={} ip={} reason=invalid-key", path, request.getRemoteAddr());
            writeError(response, HttpStatus.UNAUTHORIZED, "UNAUTHORIZED", "API Key 缺失或无效");
            return;
        }

        request.setAttribute(ATTR_KEY_ENTRY, entry);
        filterChain.doFilter(request, response);
    }

    private void writeError(HttpServletResponse response, HttpStatus status, String code, String message) throws IOException {
        response.setStatus(status.value());
        response.setContentType(MediaType.APPLICATION_JSON_VALUE);
        response.setCharacterEncoding("UTF-8");
        ApiError err = new ApiError(code, message, null);
        response.getWriter().write(objectMapper.writeValueAsString(err));
    }
}
