package com.tashow.cloud.app.mq.interceptor;

import cn.hutool.core.util.IdUtil;
import com.tashow.cloud.app.mq.message.BuriedMessages;
import com.tashow.cloud.app.mq.producer.buriedPoint.BuriedPointProducer;
import com.tashow.cloud.common.util.json.JsonUtils;
import com.tashow.cloud.common.util.servlet.ServletUtils;
import com.tashow.cloud.common.util.spring.SpringUtils;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StopWatch;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import java.net.InetAddress;
import java.net.UnknownHostException;

/**
 * 后端静默埋点拦截器
 * 用于收集API请求信息并异步发送到消息队列
 */
@Slf4j
@RequiredArgsConstructor
public class BuriedPointInterceptor implements HandlerInterceptor {

    private final BuriedPointProducer buriedPointProducer;
    
    private static final String ATTRIBUTE_STOPWATCH = "BuriedPoint.StopWatch";
    private static final String ATTRIBUTE_REQUEST_ID = "BuriedPoint.RequestId";
    
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        
        try {
            // 开始计时
            StopWatch stopWatch = new StopWatch();
            stopWatch.start();
            request.setAttribute(ATTRIBUTE_STOPWATCH, stopWatch);

            // 生成请求ID
            int requestId = (int)(Math.abs(IdUtil.getSnowflakeNextId()) % Integer.MAX_VALUE);
            request.setAttribute(ATTRIBUTE_REQUEST_ID, requestId);
            
            // 收集埋点数据
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            String method = request.getMethod() + " " + request.getRequestURI()+ JsonUtils.toJsonString(request.getParameterMap());
            String controllerName = handlerMethod.getBeanType().getSimpleName();
            String actionName = handlerMethod.getMethod().getName();
            
            // 创建埋点消息
            BuriedMessages message = new BuriedMessages();
            message.setId(requestId);
            message.setEventTime(System.currentTimeMillis());
            message.setService(SpringUtils.getApplicationName());
            message.setMethod(method);
            message.setUserId(getUserId(request));
            message.setSessionId(request.getSession().getId());
            message.setClientIp(ServletUtils.getClientIP(request));
            message.setServerIp(getServerIp());
            message.setEventType("API_REQUEST_START");
            message.setPagePath(controllerName + "#" + actionName);
            message.setUserAgent(request.getHeader("User-Agent"));
            message.setStatusCode(BuriedMessages.STATUS_INIT);
            buriedPointProducer.asyncSendMessage(message);
            if (log.isDebugEnabled()) {
                log.debug("[埋点] 收集请求开始数据: {}", message);
            }
        } catch (Exception e) {
            log.warn("[埋点] 埋点数据收集异常", e);
        }
        
        return true;
    }

    /**
     * 获取当前登录用户ID
     * 如果未登录返回匿名标识
     */
    private String getUserId(HttpServletRequest request) {
        Object userAttribute = request.getSession().getAttribute("USER_ID");
        if (userAttribute != null) {
            return userAttribute.toString();
        }
        // 返回匿名用户标识
        return "anonymous";
    }
    
    /**
     * 获取服务器IP
     */
    private String getServerIp() {
        try {
            return InetAddress.getLocalHost().getHostAddress();
        } catch (UnknownHostException e) {
            throw new RuntimeException(e);
        }
    }
} 