package com.gxwebsoft.hjm.service.impl;

import cn.hutool.core.util.CharsetUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;
import com.gxwebsoft.common.core.utils.WxOfficialUtil;
import com.gxwebsoft.common.system.entity.Setting;
import com.gxwebsoft.common.system.service.SettingService;
import com.gxwebsoft.hjm.dto.SubscribeMessageRequest;
import com.gxwebsoft.hjm.dto.SubscribeMessageRequest.SubscribeDataItem;
import com.gxwebsoft.hjm.dto.TemplateMessageRequest;
import com.gxwebsoft.hjm.dto.TemplateMessageRequest.TemplateDataItem;
import com.gxwebsoft.hjm.service.WxNotificationService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 微信通知服务实现
 *
 * @author 科技小王子
 * @since 2025-06-15
 */
@Slf4j
@Service
public class WxNotificationServiceImpl implements WxNotificationService {

    @Resource
    private SettingService settingService;

    @Resource
    private WxOfficialUtil wxOfficialUtil;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public boolean sendTemplateMessage(Integer tenantId, TemplateMessageRequest request) {
        try {
            String accessToken = getWxAccessToken(tenantId);
            return sendWxTemplateMessage(accessToken, request);
        } catch (Exception e) {
            log.error("发送模板消息失败", e);
            return false;
        }
    }

    @Override
    public boolean sendSubscribeMessage(Integer tenantId, SubscribeMessageRequest request) {
        try {
            String accessToken = getWxAccessToken(tenantId);
            return sendWxSubscribeMessage(accessToken, request);
        } catch (Exception e) {
            log.error("发送订阅消息失败", e);
            return false;
        }
    }

    @Override
    public BatchSendResult batchSendTemplateMessage(Integer tenantId, List<TemplateMessageRequest> requests) {
        int successCount = 0;
        int failCount = 0;

        try {
            String accessToken = getWxAccessToken(tenantId);

            for (TemplateMessageRequest request : requests) {
                boolean success = sendWxTemplateMessage(accessToken, request);
                if (success) {
                    successCount++;
                } else {
                    failCount++;
                }

                // 避免频率限制，每次发送间隔100ms
                Thread.sleep(100);
            }
        } catch (Exception e) {
            log.error("批量发送模板消息失败", e);
            failCount += (requests.size() - successCount - failCount);
        }

        return new BatchSendResult(successCount, failCount);
    }

    @Override
    public String getTemplateList(Integer tenantId) {
        try {
            String accessToken = getWxAccessToken(tenantId);
            String url = "https://api.weixin.qq.com/cgi-bin/template/get_all_private_template?access_token=" + accessToken;

            String response = HttpUtil.get(url, CharsetUtil.CHARSET_UTF_8);
            return response;
        } catch (Exception e) {
            log.error("获取模板列表失败", e);
            return null;
        }
    }

    /**
     * 获取微信公众号Access Token
     */
    private String getWxAccessToken(Integer tenantId) {
        String cacheKey = "wx_official_access_token:" + tenantId;

        // 先从缓存获取
        String cachedToken = stringRedisTemplate.opsForValue().get(cacheKey);
        if (cachedToken != null) {
            return cachedToken;
        }

        // 缓存中没有，重新获取
        try {
            // 获取微信公众号配置
            String appId = "wx100365d412078b8c";
            String appSecret = "bba73c9fc8f5f7d0edc4de50786a8c62";

            if (appId == null || appSecret == null) {
                throw new RuntimeException("微信公众号配置不完整");
            }



          // 调用微信API获取access_token
            String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="
                    + appId + "&secret=" + appSecret;

            String response = HttpUtil.get(url, CharsetUtil.CHARSET_UTF_8);
          System.out.println("response = " + response);
            JSONObject jsonObject = JSONObject.parseObject(response);

            String accessToken = jsonObject.getString("access_token");
            Integer expiresIn = jsonObject.getInteger("expires_in");

            if (accessToken == null) {
                String errorMsg = jsonObject.getString("errmsg");
                throw new RuntimeException("获取access_token失败: " + errorMsg);
            }

            // 缓存access_token，提前5分钟过期
            int cacheSeconds = expiresIn != null ? expiresIn - 300 : 7200 - 300;
            stringRedisTemplate.opsForValue().set(cacheKey, accessToken, cacheSeconds, TimeUnit.SECONDS);

            return accessToken;

        } catch (Exception e) {
            log.error("获取微信公众号access_token失败", e);
            throw new RuntimeException("获取access_token失败: " + e.getMessage());
        }
    }

    /**
     * 发送微信模板消息
     */
    private boolean sendWxTemplateMessage(String accessToken, TemplateMessageRequest request) {
        try {
            String url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accessToken;

            // 构建请求数据
            JSONObject data = new JSONObject();
            data.put("touser", request.getToUser());
            data.put("template_id", request.getTemplateId());
            data.put("url", request.getUrl());
            data.put("topcolor", request.getTopColor());

            // 构建模板数据
            JSONObject templateData = new JSONObject();
            if (request.getData() != null) {
                for (Map.Entry<String, TemplateDataItem> entry : request.getData().entrySet()) {
                    JSONObject item = new JSONObject();
                    item.put("value", entry.getValue().getValue());
                    item.put("color", entry.getValue().getColor());
                    templateData.put(entry.getKey(), item);
                }
            }
            data.put("data", templateData);

            // 小程序跳转
            if (request.getMiniprogram() != null) {
                JSONObject miniprogram = new JSONObject();
                miniprogram.put("appid", request.getMiniprogram().getAppid());
                miniprogram.put("pagepath", request.getMiniprogram().getPagepath());
                data.put("miniprogram", miniprogram);
            }

            // 发送请求
            String response = HttpUtil.post(url, data.toJSONString());
            JSONObject result = JSONObject.parseObject(response);

            Integer errcode = result.getInteger("errcode");
            String errmsg = result.getString("errmsg");

            if (errcode != null && errcode == 0) {
                log.info("模板消息发送成功: {}", result.getString("msgid"));
                return true;
            } else {
                log.error("模板消息发送失败: errcode={}, errmsg={}", errcode, errmsg);
                return false;
            }

        } catch (Exception e) {
            log.error("发送微信模板消息异常", e);
            return false;
        }
    }

    /**
     * 发送微信订阅消息
     */
    private boolean sendWxSubscribeMessage(String accessToken, SubscribeMessageRequest request) {
        try {
            String url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" + accessToken;

            // 构建请求数据
            JSONObject data = new JSONObject();
            data.put("touser", request.getToUser());
            data.put("template_id", request.getTemplateId());
            data.put("page", request.getPage());
            data.put("miniprogram_state", request.getMiniprogramState());
            data.put("lang", request.getLang());

            // 构建订阅消息数据
            JSONObject subscribeData = new JSONObject();
            if (request.getData() != null) {
                for (Map.Entry<String, SubscribeDataItem> entry : request.getData().entrySet()) {
                    JSONObject item = new JSONObject();
                    item.put("value", entry.getValue().getValue());
                    subscribeData.put(entry.getKey(), item);
                }
            }
            data.put("data", subscribeData);

            // 发送请求
            String response = HttpUtil.post(url, data.toJSONString());
            JSONObject result = JSONObject.parseObject(response);

            Integer errcode = result.getInteger("errcode");
            String errmsg = result.getString("errmsg");

            if (errcode != null && errcode == 0) {
                log.info("订阅消息发送成功");
                return true;
            } else {
                log.error("订阅消息发送失败: errcode={}, errmsg={}", errcode, errmsg);
                return false;
            }

        } catch (Exception e) {
            log.error("发送微信订阅消息异常", e);
            return false;
        }
    }
}
