package com.kingdee.eas.custom.integration.riskcontrol.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Properties;

import org.springframework.web.servlet.HandlerInterceptor;

/**
 * 风控平台 API 认证拦截器
 * <p>
 * 校验 Authorization: Bearer <token> 请求头。
 * Token 优先级：系统属性 > 配置文件 > 环境变量。
 * </p>
 *
 * <h3>配置方式（任选其一）</h3>
 * <ol>
 *   <li>JVM 参数：-Driskcontrol.api.token=sk-xxx</li>
 *   <li>配置文件：{EAS_HOME}/server/properties/riskcontrol/api-token.properties
 *       <br/>内容：riskcontrol.api.token=sk-xxx</li>
 *   <li>环境变量：RISKCONTROL_API_TOKEN=sk-xxx</li>
 * </ol>
 */
public class RiskControlAuthInterceptor implements HandlerInterceptor {

    private static final Logger logger = LoggerFactory.getLogger(RiskControlAuthInterceptor.class);
    private static final ObjectMapper MAPPER = new ObjectMapper();
    private static final String TOKEN_KEY = "riskcontrol.api.token";
    private static final String PROPERTIES_PATH = "/server/properties/riskcontrol/api-token.properties";

    private final String apiToken;

    public RiskControlAuthInterceptor() {
        this.apiToken = loadToken();
        if (apiToken == null || apiToken.isEmpty()) {
            logger.error("风控API认证Token未配置！请设置 {} (JVM参数/配置文件/环境变量)", TOKEN_KEY);
        } else {
            logger.info("风控API认证Token已加载 (长度={})", apiToken.length());
        }
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
                             Object handler) throws Exception {
        if (apiToken == null || apiToken.isEmpty()) {
            writeUnauthorized(response, "服务端认证未配置");
            return false;
        }

        String authHeader = request.getHeader("Authorization");
        if (authHeader == null || !authHeader.startsWith("Bearer ")) {
            logger.warn("风控API认证失败 - 缺少Authorization头 - IP: {}", getClientIp(request));
            writeUnauthorized(response, "缺少有效的Authorization头");
            return false;
        }

        String token = authHeader.substring(7);
        if (!apiToken.equals(token)) {
            logger.warn("风控API认证失败 - Token不匹配 - IP: {}", getClientIp(request));
            writeUnauthorized(response, "Token无效");
            return false;
        }

        return true;
    }

    // ---- Token 加载 ----

    private static String loadToken() {
        // 1. JVM 系统属性（优先级最高）
        String token = System.getProperty(TOKEN_KEY);
        if (token != null && !token.isEmpty()) {
            logger.info("从JVM系统属性加载风控API Token");
            return token;
        }

        // 2. 配置文件
        token = loadFromPropertiesFile();
        if (token != null && !token.isEmpty()) {
            return token;
        }

        // 3. 环境变量
        token = System.getenv("RISKCONTROL_API_TOKEN");
        if (token != null && !token.isEmpty()) {
            logger.info("从环境变量加载风控API Token");
            return token;
        }

        return null;
    }

    private static String loadFromPropertiesFile() {
        try {
            String easHome = System.getProperty("EAS_HOME");
            if (easHome == null) {
                easHome = System.getenv("EAS_HOME");
            }
            if (easHome == null) {
                return null;
            }
            File propFile = new File(easHome + PROPERTIES_PATH);
            if (!propFile.exists()) {
                return null;
            }
            Properties props = new Properties();
            try (InputStream in = new FileInputStream(propFile)) {
                props.load(in);
            }
            String token = props.getProperty(TOKEN_KEY);
            if (token != null && !token.isEmpty()) {
                logger.info("从配置文件加载风控API Token: {}", propFile.getAbsolutePath());
            }
            return token;
        } catch (Exception e) {
            logger.warn("读取风控API Token配置文件失败: {}", e.getMessage());
            return null;
        }
    }

    private void writeUnauthorized(HttpServletResponse response, String message) throws Exception {
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        response.setContentType("application/json;charset=UTF-8");
        Map<String, Object> body = new LinkedHashMap<>();
        body.put("code", 401);
        body.put("message", message);
        MAPPER.writeValue(response.getWriter(), body);
    }

    private String getClientIp(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("X-Real-IP");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip.split(",")[0].trim();
    }
}
