package com.mosquito.project.web;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.mosquito.project.persistence.repository.ApiKeyRepository;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;

import java.util.Base64;
import java.util.Map;

public class ApiKeyAuthInterceptor implements HandlerInterceptor {

    private static final String API_KEY_HEADER = "X-API-Key";
    private static final String API_KEY_PREFIX_ATTR = "apiKeyPrefix";
    private static final String API_KEY_ID_ATTR = "apiKeyId";
    private static final String ACTIVITY_ID_ATTR = "activityId";

    private final ApiKeyRepository apiKeyRepository;
    private final ObjectMapper objectMapper = new ObjectMapper();

    public ApiKeyAuthInterceptor(ApiKeyRepository apiKeyRepository) {
        this.apiKeyRepository = apiKeyRepository;
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        String rawApiKey = request.getHeader(API_KEY_HEADER);
        if (rawApiKey == null || rawApiKey.isBlank()) {
            writeUnauthorizedResponse(response, "INVALID_API_KEY", "API Key不能为空");
            return false;
        }
        String prefix = rawApiKey.substring(0, Math.min(12, rawApiKey.length())).trim();
        var candidateOpt = apiKeyRepository.findByKeyPrefix(prefix);
        if (candidateOpt.isEmpty()) {
            writeUnauthorizedResponse(response, "INVALID_API_KEY", "API Key无效");
            return false;
        }
        var entity = candidateOpt.get();
        if (entity.getRevokedAt() != null) {
            writeUnauthorizedResponse(response, "INVALID_API_KEY", "API Key已被吊销");
            return false;
        }
        if (entity.getEnabled() == null || !entity.getEnabled()) {
            writeUnauthorizedResponse(response, "INVALID_API_KEY", "API Key已被禁用");
            return false;
        }
        // verify hash using same PBKDF2 as service
        try {
            byte[] salt = Base64.getDecoder().decode(entity.getSalt());
            javax.crypto.SecretKeyFactory skf = javax.crypto.SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
            javax.crypto.spec.PBEKeySpec spec = new javax.crypto.spec.PBEKeySpec(rawApiKey.toCharArray(), salt, 185000, 256);
            byte[] derived = skf.generateSecret(spec).getEncoded();
            String computed = Base64.getEncoder().encodeToString(derived);
            if (!computed.equals(entity.getKeyHash())) {
                writeUnauthorizedResponse(response, "INVALID_API_KEY", "API Key不匹配");
                return false;
            }
        } catch (Exception e) {
            writeUnauthorizedResponse(response, "INVALID_API_KEY", "API Key验证失败");
            return false;
        }
        // 保存API Key ID和关联的Activity ID到请求属性
        request.setAttribute(API_KEY_PREFIX_ATTR, prefix);
        request.setAttribute(API_KEY_ID_ATTR, entity.getId());
        if (entity.getActivityId() != null) {
            request.setAttribute(ACTIVITY_ID_ATTR, entity.getActivityId());
        }
        return true;
    }

    /**
     * 写入结构化的401 Unauthorized响应
     */
    private void writeUnauthorizedResponse(HttpServletResponse response, String errorCode, String message) {
        try {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            response.setContentType("application/json");
            response.setCharacterEncoding("UTF-8");
            Map<String, Object> errorResponse = Map.of(
                "success", false,
                "errorCode", errorCode,
                "message", message
            );
            response.getWriter().write(objectMapper.writeValueAsString(errorResponse));
        } catch (Exception e) {
            // 忽略写入异常
        }
    }
}
