package org.jeecg.modules.app.weixinService;

import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.modules.app.vo.weixin.NotificationRequest;
import org.jeecg.modules.app.vo.weixin.NotificationResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Service
public class WechatNotificationService {

    private static final Logger logger = LoggerFactory.getLogger(WechatNotificationService.class);

    private final WechatAccessTokenService tokenService;
    private final CloseableHttpClient httpClient;

    public WechatNotificationService(WechatAccessTokenService tokenService,
                                     CloseableHttpClient httpClient) {
        this.tokenService = tokenService;
        this.httpClient = httpClient;
    }

    /**
     * 发送小程序订阅消息
     * @param request 通知请求参数
     * @return 发送结果
     */
    public NotificationResult sendSubscribeMessage(NotificationRequest request) {
        String accessToken = tokenService.getAccessToken();
        String url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" + accessToken;

        JSONObject requestBody = buildRequestBody(request);

        try {
            HttpPost httpPost = new HttpPost(url);
            httpPost.setEntity(new StringEntity(requestBody.toJSONString(), StandardCharsets.UTF_8));
            httpPost.setHeader("Content-Type", "application/json;charset=utf8");

            try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
                String result = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
                JSONObject resultJson = JSONObject.parseObject(result);

                if (resultJson.getInteger("errcode") == 0) {
                    logger.info("成功发送小程序订阅消息: openid={}, templateId={}",
                            request.getOpenid(), request.getTemplateId());
                    return null;
                } else {
                    logger.error("发送小程序订阅消息失败: {}, 请求参数: {}",
                            result, requestBody.toJSONString());
                    throw new JeecgBootException(""+resultJson);
                }
            }
        } catch (Exception e) {
            logger.error("发送小程序订阅消息异常", e);
            throw new JeecgBootException("系统异常: " + e.getMessage());
        }
    }

    private JSONObject buildRequestBody(NotificationRequest request) {
        JSONObject body = new JSONObject();
        body.put("touser", request.getOpenid());
        body.put("template_id", request.getTemplateId());
        body.put("data", request.getData());

        if (StringUtils.isNotBlank(request.getPage())) {
            body.put("page", request.getPage());
        }

        if (StringUtils.isNotBlank(request.getMiniprogramState())) {
            body.put("miniprogram_state", request.getMiniprogramState());
        }

        return body;
    }

    private NotificationResult handleErrorResponse(JSONObject resultJson) {
        int errcode = resultJson.getInteger("errcode");
        String errmsg = resultJson.getString("errmsg");

        switch (errcode) {
            case 40003: // 无效的openid
            case 40037: // 无效的模板ID
                return NotificationResult.failure("参数错误: " + errmsg);
            case 43101: // 用户拒绝接受消息
                return NotificationResult.failure("用户未订阅消息");
            case 47003: // 模板参数不准确
                return NotificationResult.failure("模板参数错误: " + errmsg);
            default:
                return NotificationResult.failure("微信接口错误: " + errmsg);
        }
    }

    // 批量发送（异步）
    public void batchSendSubscribeMessages(List<NotificationRequest> requests) {
        ExecutorService executor = Executors.newFixedThreadPool(10);

        for (NotificationRequest request : requests) {
            executor.submit(() -> {
                try {
                    sendSubscribeMessage(request);
                } catch (Exception e) {
                    logger.error("批量发送小程序订阅消息异常", e);
                }
            });
        }
    }
}