package com.linearpast.minecraftmanager.interceptor;

import com.linearpast.minecraftmanager.exception.UnauthorizedException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;

import java.io.IOException;
import java.nio.charset.StandardCharsets;

@Component
public class ApiKeyInterceptor implements HandlerInterceptor {

    @Value("${api.key}")
    private String apiKey;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        // 1. 优先检查 API Key（Header: X-API-Key / X-API-TOKEN 或 Query: apiKey）
        String reqApiKey = request.getHeader("X-API-Key");
        if (!StringUtils.hasText(reqApiKey)) {
            reqApiKey = request.getHeader("X-API-TOKEN");
        }
        if (!StringUtils.hasText(reqApiKey)) {
            reqApiKey = request.getParameter("apiKey");
        }
        if (StringUtils.hasText(reqApiKey) && apiKey.equals(reqApiKey)) {
            return true;
        }

        // 2. 回退到 Session 鉴权（浏览器访问）
        HttpSession session = request.getSession();
        if (session != null
                && session.getAttribute("isLoggedIn") != null
                && (boolean) session.getAttribute("isLoggedIn")
                && session.getAttribute("adminAccount") != null) {
            return true;
        }

        // 3. 鉴权失败 → API 请求返回 JSON，浏览器请求抛异常跳转登录页
        if (isApiRequest(request)) {
            writeJsonResponse(response, 403, "{\"code\":403,\"msg\":\"无权限：API Key 无效或未提供\",\"data\":null}");
            return false;
        }
        throw new UnauthorizedException("redirect:/admin/login?error=please login first");
    }

    private boolean isApiRequest(HttpServletRequest request) {
        String header = request.getHeader("X-API-Key");
        if (!StringUtils.hasText(header)) {
            header = request.getHeader("X-API-TOKEN");
        }
        return StringUtils.hasText(header)
                || StringUtils.hasText(request.getParameter("apiKey"))
                || request.getRequestURI().startsWith("/api/");
    }

    private void writeJsonResponse(HttpServletResponse response, int status, String body) {
        response.setStatus(status);
        response.setContentType("application/json");
        response.setCharacterEncoding(StandardCharsets.UTF_8.name());
        try {
            response.getWriter().write(body);
            response.getWriter().flush();
        } catch (IOException ignored) {
        }
    }
}
