package com.haha.service.notify;

import com.haha.service.config.DeviceAlertProperties;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.TimeUnit;

/**
 * 企业微信群机器人通知服务
 * 通过Webhook发送设备告警和恢复通知到企业微信群
 */
@Slf4j
@Service
public class WeChatWorkNotifyService {

    private static final DateTimeFormatter DATETIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    private static final MediaType JSON_TYPE = MediaType.parse("application/json; charset=utf-8");

    private final DeviceAlertProperties alertProperties;
    private final OkHttpClient httpClient;

    public WeChatWorkNotifyService(DeviceAlertProperties alertProperties) {
        this.alertProperties = alertProperties;
        this.httpClient = new OkHttpClient.Builder()
                .connectTimeout(10, TimeUnit.SECONDS)
                .readTimeout(30, TimeUnit.SECONDS)
                .writeTimeout(30, TimeUnit.SECONDS)
                .retryOnConnectionFailure(true)
                .connectionPool(new ConnectionPool(5, 5, TimeUnit.MINUTES))
                .build();
    }

    /**
     * 发送设备离线告警
     *
     * @param deviceId      设备编号
     * @param deviceName    设备名称
     * @param shopName      所属门店
     * @param triggerSource 触发来源（如：定时巡检、心跳超时）
     * @param alertTime     告警时间
     */
    public void sendOfflineAlert(String deviceId, String deviceName, String shopName,
                                 String triggerSource, LocalDateTime alertTime) {
        String content = "### ⚠️ 设备离线告警\n" +
                "> **设备名称**：" + deviceName + "\n" +
                "> **设备编号**：" + deviceId + "\n" +
                "> **所属门店**：" + shopName + "\n" +
                "> **告警类型**：<font color=\"warning\">设备离线</font>\n" +
                "> **告警时间**：" + alertTime.format(DATETIME_FORMATTER) + "\n" +
                "> **触发来源**：" + triggerSource + "\n" +
                "> \n" +
                "> 请及时检查设备网络连接情况";
        sendMarkdownMessage(content);
    }

    /**
     * 发送设备信号弱告警
     *
     * @param deviceId    设备编号
     * @param deviceName  设备名称
     * @param shopName    所属门店
     * @param signalValue 信号值
     * @param alertTime   告警时间
     */
    public void sendWeakSignalAlert(String deviceId, String deviceName, String shopName,
                                    Integer signalValue, LocalDateTime alertTime) {
        String content = "### ⚠️ 设备信号弱告警\n" +
                "> **设备名称**：" + deviceName + "\n" +
                "> **设备编号**：" + deviceId + "\n" +
                "> **所属门店**：" + shopName + "\n" +
                "> **告警类型**：<font color=\"warning\">信号弱</font>\n" +
                "> **信号值**：" + signalValue + "\n" +
                "> **告警时间**：" + alertTime.format(DATETIME_FORMATTER) + "\n" +
                "> \n" +
                "> 设备信号较弱，可能导致离线，请关注";
        sendMarkdownMessage(content);
    }

    /**
     * 发送设备恢复上线通知
     *
     * @param deviceId   设备编号
     * @param deviceName 设备名称
     * @param shopName   所属门店
     * @param time       恢复时间
     */
    public void sendBackOnlineNotify(String deviceId, String deviceName, String shopName,
                                     LocalDateTime time) {
        String content = "### ✅ 设备恢复上线\n" +
                "> **设备名称**：" + deviceName + "\n" +
                "> **设备编号**：" + deviceId + "\n" +
                "> **所属门店**：" + shopName + "\n" +
                "> **状态**：<font color=\"info\">已恢复上线</font>\n" +
                "> **恢复时间**：" + time.format(DATETIME_FORMATTER);
        sendMarkdownMessage(content);
    }

    /**
     * 发送Markdown消息到企业微信群机器人
     *
     * @param content Markdown格式的消息内容
     */
    public void sendMarkdownMessage(String content) {
        if (!alertProperties.isEnabled()) {
            log.debug("[企业微信通知] 设备告警已禁用，跳过发送");
            return;
        }

        String webhookUrl = alertProperties.getWechatWork().getWebhookUrl();
        if (!StringUtils.hasText(webhookUrl)) {
            log.warn("[企业微信通知] 未配置企业微信Webhook地址，跳过发送");
            return;
        }

        // 构建请求JSON（手动拼接，避免额外依赖）
        String json = "{\"msgtype\":\"markdown\",\"markdown\":{\"content\":" + escapeJson(content) + "}}";

        RequestBody body = RequestBody.create(json, JSON_TYPE);
        Request request = new Request.Builder()
                .url(webhookUrl)
                .post(body)
                .build();

        try (Response response = httpClient.newCall(request).execute()) {
            ResponseBody responseBody = response.body();
            String responseStr = responseBody != null ? responseBody.string() : "";

            if (response.isSuccessful()) {
                log.info("[企业微信通知] 消息发送成功，响应：{}", responseStr);
            } else {
                log.error("[企业微信通知] 消息发送失败，HTTP状态码：{}，响应：{}", response.code(), responseStr);
            }
        } catch (IOException e) {
            log.error("[企业微信通知] 消息发送异常", e);
        }
    }

    /**
     * 将字符串转义为JSON字符串值（带双引号）
     */
    private String escapeJson(String value) {
        if (value == null) {
            return "null";
        }
        StringBuilder sb = new StringBuilder("\"");
        for (char c : value.toCharArray()) {
            switch (c) {
                case '"' -> sb.append("\\\"");
                case '\\' -> sb.append("\\\\");
                case '\n' -> sb.append("\\n");
                case '\r' -> sb.append("\\r");
                case '\t' -> sb.append("\\t");
                default -> sb.append(c);
            }
        }
        sb.append("\"");
        return sb.toString();
    }
}
