package cn.teammodel.config.intercepter;

import cn.hutool.crypto.SecureUtil;
import cn.hutool.extra.servlet.ServletUtil;
import cn.hutool.jwt.JWTUtil;
import cn.teammodel.manager.notification.NotificationService;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.time.Instant;
import java.util.List;

/**
 * 上传接口调用日志拦截器
 * @author winter
 * @create 2024-03-18 10:00
 */
@Component
@Slf4j
public class UploadApiLogInterceptor implements HandlerInterceptor {
    @Value("${spring.env}")
    private String env;
    @Resource
    private NotificationService notificationService;

    private final ObjectMapper mapper = new ObjectMapper();

    @Override
    public boolean preHandle(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull Object handler) throws Exception {
        if (!env.equals("dev")) {
            doUploadLog(request);
        }
        return true;
    }

    private void doUploadLog(@NotNull HttpServletRequest request) throws IOException {
        String ip = ServletUtil.getClientIP(request);
        String client = "";
        String tokenSha = "";
        String id = "";
        String name = "";
        String school = "";
        String scope = "";
        String referer = request.getHeader("Referer");
        Long requestTime = Instant.now().toEpochMilli();
        // 获取 json 请求参数(这里读了后，后面就再也读不到了，需要处理)
        BufferedReader streamReader = new BufferedReader(new InputStreamReader(request.getInputStream(), StandardCharsets.UTF_8));
        StringBuilder responseStrBuilder = new StringBuilder();
        String inputStr;
        while ((inputStr = streamReader.readLine()) != null)
            responseStrBuilder.append(inputStr);

        JsonNode jsonNode = mapper.readTree(responseStrBuilder.toString());
        String xAuthToken = request.getHeader("x-auth-AuthToken");
        // 如果有 authorization
        String authorization = request.getHeader("Authorization");
        if (StringUtils.isNotBlank(authorization)) {
            authorization = authorization.replace("Bearer ", "");
            List<String> roles = (List<String>) JWTUtil.parseToken(authorization).getPayload("roles");
            if (ObjectUtils.isNotEmpty(roles)) {
                client = roles.get(0);
            }
            tokenSha = SecureUtil.sha1("Bearer " + authorization);
        }
        String xAuthIdToken = request.getHeader("X-Auth-IdToken");
        if (StringUtils.isNotBlank(xAuthIdToken)) {
            id = (String) JWTUtil.parseToken(xAuthIdToken).getPayload("sub");
            name = (String) JWTUtil.parseToken(xAuthIdToken).getPayload("name");
            if (StringUtils.isNotBlank(tokenSha)) {
                tokenSha = SecureUtil.sha1(xAuthIdToken);
            }
        }
        String xAuthSchool = request.getHeader("X-Auth-School");
        if (StringUtils.isNotBlank(xAuthSchool)) {
            school = xAuthSchool;
        }
        if (StringUtils.isNotBlank(xAuthToken)) {
            id = (String) JWTUtil.parseToken(xAuthToken).getPayload("sub");
            name = (String) JWTUtil.parseToken(xAuthToken).getPayload("name");
            school = (String) JWTUtil.parseToken(xAuthToken).getPayload("azp");
            scope = (String) JWTUtil.parseToken(xAuthToken).getPayload("scope");
            if (StringUtils.isNotBlank(tokenSha)) {
                tokenSha = SecureUtil.sha1(xAuthToken);
            }
        }

        ObjectNode root = mapper.createObjectNode();
        root.put("ip", ip);
        root.put("time", requestTime);
        root.put("id", id);
        root.put("name", name);
        root.set("param", jsonNode);
        root.put("school", school);
        root.put("client", client);
        root.put("tid", tokenSha);
        root.put("scope", scope);
        root.put("path", request.getContextPath() + request.getRequestURI());
        root.put("host", request.getServerName());
        root.put("p", "appraisal");

        // 发送请求
//        OkHttpClient okHttpClient = new OkHttpClient();
//        String requestData = root.toString();
//        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json"), requestData);
//        Request okRequest = new Request.Builder()
//                .url("http://52.130.252.100:8806/api/http-log")
//                .post(requestBody)
//                .build();
//
//        okHttpClient.newCall(okRequest).enqueue(new Callback() {
//            @Override
//            public void onFailure(Call call, IOException e) {
//                log.error("UploadApiLogIntercepter error") ;
//                notificationService.send("日志上传告警: 请求发送失败，检查请求发送客户端");
//            }
//
//            @Override
//            public void onResponse(Call call, Response response) throws IOException {
//                if (!response.isSuccessful()) {
//                    log.error("UploadApiLogIntercepter error" ) ;
//                    notificationService.send("日志上传告警: 请求响应异常，检查 API 源是否正常");
//                } else {
//                    log.info("UploadApiLogIntercepter success");
//                }
//            }
//        });
    }
}
