package com.ygtx.common.utils.getui;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson2.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.*;

/**
 * 个推推送服务工具类
 *
 * @author ruoyi
 */
@Component
public class GetuiTemplate {

    private static final Logger log = LoggerFactory.getLogger(GetuiTemplate.class);

    @Autowired
    private GetuiConfig getuiConfig;

    private static GetuiTemplate getuiTemplate;

    private static final String AUTH_URL = "/auth";
    private static final String PUSH_SINGLE_URL = "/push/single/cid";
    private static final String PUSH_BATCH_URL = "/push/list/cid";

    @PostConstruct
    public void init() {
        getuiTemplate = this;
        getuiTemplate.getuiConfig = this.getuiConfig;
    }

    /**
     * 获取鉴权Token
     *
     * @return token
     */
    private String getAuthToken() {
        if (!getuiConfig.isEnabled()) {
            throw new RuntimeException("个推服务未启用");
        }

        try {
            Map<String, Object> paramMap = new HashMap<>();
            paramMap.put("appkey", getuiConfig.getAppKey());
            paramMap.put("timestamp", String.valueOf(System.currentTimeMillis()));
            paramMap.put("sign", generateSign(paramMap));

            String url = getuiConfig.getPushUrl() + getuiConfig.getAppId() + AUTH_URL;

            HttpResponse response = HttpRequest.post(url)
                    .header("content-type", "application/json")
                    .body(JSONUtil.toJsonStr(paramMap))
                    .execute();

            if (response.getStatus() == 200) {
                JSONObject result = JSONObject.parseObject(response.body());
                if ("ok".equals(result.getString("code"))) {
                    return result.getJSONObject("data").getString("token");
                } else {
                    log.error("获取个推鉴权Token失败: {}", result.getString("msg"));
                    return null;
                }
            }
        } catch (Exception e) {
            log.error("获取个推鉴权Token异常", e);
        }
        return null;
    }

    /**
     * 生成签名
     *
     * @param paramMap 参数map
     * @return 签名
     */
    private String generateSign(Map<String, Object> paramMap) {
        // 根据个推官方文档实现签名生成逻辑
        String appKey = paramMap.get("appkey").toString();
        String timestamp = paramMap.get("timestamp").toString();
        String masterSecret = getuiConfig.getMasterSecret();

        // 个推签名算法：SHA256(masterSecret + timestamp + appKey)
        String signStr = masterSecret + timestamp + appKey;
        return cn.hutool.crypto.SecureUtil.sha256(signStr);
    }

    /**
     * 推送消息给单个用户
     *
     * @param cid 用户cid
     * @param title 消息标题
     * @param content 消息内容
     * @param payload 透传内容
     * @return 推送结果
     */
    public boolean pushToSingle(String cid, String title, String content, String payload) {
        if (!getuiConfig.isEnabled()) {
            log.warn("个推服务未启用");
            return false;
        }

        if (StrUtil.isBlank(cid)) {
            log.warn("用户cid不能为空");
            return false;
        }

        String token = getAuthToken();
        if (StrUtil.isBlank(token)) {
            log.error("获取个推鉴权Token失败");
            return false;
        }

        try {
            Map<String, Object> paramMap = new HashMap<>();
            paramMap.put("request_id", String.valueOf(System.currentTimeMillis()));

            Map<String, Object> pushMessage = new HashMap<>();
            pushMessage.put("notification", createNotification(title, content));
            if (StrUtil.isNotBlank(payload)) {
                pushMessage.put("transmission", createTransmission(payload));
            }

            paramMap.put("settings", createSettings());
            paramMap.put("push_message", pushMessage);
            paramMap.put("audience", createAudience(cid));

            String url = getuiConfig.getPushUrl() + getuiConfig.getAppId() + PUSH_SINGLE_URL;

            HttpResponse response = HttpRequest.post(url)
                    .header("content-type", "application/json")
                    .header("token", token)
                    .body(JSONUtil.toJsonStr(paramMap))
                    .execute();

            if (response.getStatus() == 200) {
                JSONObject result = JSONObject.parseObject(response.body());
                if ("ok".equals(result.getString("code"))) {
                    log.info("个推消息推送成功: cid={}", cid);
                    return true;
                } else {
                    log.error("个推消息推送失败: cid={}, 错误信息={}", cid, result.getString("msg"));
                    return false;
                }
            }
        } catch (Exception e) {
            log.error("个推消息推送异常: cid={}", cid, e);
        }
        return false;
    }

    /**
     * 批量推送消息给多个用户
     *
     * @param cids 用户cid列表
     * @param title 消息标题
     * @param content 消息内容
     * @param payload 透传内容
     * @return 推送结果
     */
    public boolean pushToBatch(String[] cids, String title, String content, String payload) {
        if (!getuiConfig.isEnabled()) {
            log.warn("个推服务未启用");
            return false;
        }

        if (cids == null || cids.length == 0) {
            log.warn("用户cid列表不能为空");
            return false;
        }

        String token = getAuthToken();
        if (StrUtil.isBlank(token)) {
            log.error("获取个推鉴权Token失败");
            return false;
        }

        try {
            Map<String, Object> paramMap = new HashMap<>();
            paramMap.put("request_id", String.valueOf(System.currentTimeMillis()));

            Map<String, Object> pushMessage = new HashMap<>();
            pushMessage.put("notification", createNotification(title, content));
            if (StrUtil.isNotBlank(payload)) {
                pushMessage.put("transmission", createTransmission(payload));
            }

            paramMap.put("settings", createSettings());
            paramMap.put("push_message", pushMessage);
            paramMap.put("audience", createAudience(cids));

            String url = getuiConfig.getPushUrl() + getuiConfig.getAppId() + PUSH_BATCH_URL;

            HttpResponse response = HttpRequest.post(url)
                    .header("content-type", "application/json")
                    .header("token", token)
                    .body(JSONUtil.toJsonStr(paramMap))
                    .execute();

            if (response.getStatus() == 200) {
                JSONObject result = JSONObject.parseObject(response.body());
                if ("ok".equals(result.getString("code"))) {
                    log.info("个推批量消息推送成功: cids数量={}", cids.length);
                    return true;
                } else {
                    log.error("个推批量消息推送失败: cids数量={}, 错误信息={}", cids.length, result.getString("msg"));
                    return false;
                }
            }
        } catch (Exception e) {
            log.error("个推批量消息推送异常: cids数量={}", cids.length, e);
        }
        return false;
    }

    /**
     * 创建通知消息
     */
    private Map<String, Object> createNotification(String title, String content) {
        Map<String, Object> notification = new HashMap<>();
        notification.put("title", StrUtil.blankToDefault(title, "消息通知"));
        notification.put("body", StrUtil.blankToDefault(content, "您有一条新消息"));
        notification.put("click_type", "intent");
        return notification;
    }

    /**
     * 创建透传消息
     */
    private Map<String, Object> createTransmission(String payload) {
        Map<String, Object> transmission = new HashMap<>();
        transmission.put("transmission_content", payload);
        return transmission;
    }

    /**
     * 创建推送设置
     */
    private Map<String, Object> createSettings() {
        Map<String, Object> settings = new HashMap<>();
        settings.put("ttl", 3600000); // 消息离线时间1小时
        return settings;
    }

    /**
     * 创建推送目标（单个用户）
     */
    private Map<String, Object> createAudience(String cid) {
        Map<String, Object> audience = new HashMap<>();
        audience.put("cid", new String[]{cid});
        return audience;
    }

    /**
     * 创建推送目标（多个用户）
     */
    private Map<String, Object> createAudience(String[] cids) {
        Map<String, Object> audience = new HashMap<>();
        audience.put("cid", cids);
        return audience;
    }

    /**
     * 静态方法推送消息给单个用户
     */
    public static boolean pushMessageToSingle(String cid, String title, String content) {
        return getuiTemplate.pushToSingle(cid, title, content, null);
    }

    /**
     * 静态方法推送消息给单个用户（带透传内容）
     */
    public static boolean pushMessageToSingle(String cid, String title, String content, String payload) {
        return getuiTemplate.pushToSingle(cid, title, content, payload);
    }

    /**
     * 静态方法批量推送消息给多个用户
     */
    public static boolean pushMessageToBatch(String[] cids, String title, String content) {
        return getuiTemplate.pushToBatch(cids, title, content, null);
    }

    /**
     * 静态方法批量推送消息给多个用户（带透传内容）
     */
    public static boolean pushMessageToBatch(String[] cids, String title, String content, String payload) {
        return getuiTemplate.pushToBatch(cids, title, content, payload);
    }
}
