package com.ruoyi.modules.monitor.notify;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.Instant;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

@Component
public class DingTalkNotifier {

    @Value("${dingtalk.webhook}")
    private String webhook;

    @Value("${dingtalk.secret:}")
    private String secret;

    private final WebClient webClient = WebClient.create();

    public Mono<Void> sendMarkdown(String title, String content) {
        String url = buildUrlWithSign();

        Map<String, Object> markdownMsg = new HashMap<>();
        markdownMsg.put("msgtype", "markdown");

        Map<String, String> markdown = new HashMap<>();
        markdown.put("title", title);
        markdown.put("text", content);

        markdownMsg.put("markdown", markdown);

        return webClient.post()
                .uri(url)
                .contentType(MediaType.APPLICATION_JSON)
                .body(BodyInserters.fromValue(markdownMsg))
                .retrieve()
                .bodyToMono(String.class)
                .then();
    }

    private String buildUrlWithSign() {
        if (secret == null || secret.trim().isEmpty()) {
            return webhook;
        }
        long timestamp = Instant.now().toEpochMilli();
        String stringToSign = timestamp + "\n" + secret;
        try {
            Mac mac = Mac.getInstance("HmacSHA256");
            mac.init(new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
            byte[] signData = mac.doFinal(stringToSign.getBytes(StandardCharsets.UTF_8));
            String sign = URLEncoder.encode(new String(Base64.getEncoder().encode(signData)), String.valueOf(StandardCharsets.UTF_8));
            return webhook + "&timestamp=" + timestamp + "&sign=" + sign;
        } catch (Exception e) {
            throw new RuntimeException("生成钉钉签名失败", e);
        }
    }
}