package org.xyzh.common.wechat.kefu.message;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.xyzh.common.wechat.kefu.core.KefuAccessTokenManager;
import org.xyzh.common.wechat.pojo.kefu.KefuSyncMsgResponse;
import org.xyzh.common.wechat.pojo.kefu.KefuSyncMsgResponse.KefuSyncMsg;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;

/**
 * @description    客服消息收发服务
 *                 - 接收消息和事件（同步消息）
 *                 - 发送消息
 *                 - 发送客服欢迎语
 *                 - 撤回消息
 * @filename    KefuMessageService.java
 * @author    yslg
 * @copyright xyzh
 * @since 2025-12-19
 */
@Service
public class KefuMessageService {

    private static final Logger logger = LoggerFactory.getLogger(KefuMessageService.class);
    private static final String BASE_URL = "https://qyapi.weixin.qq.com/cgi-bin";

    private final RestTemplate restTemplate = new RestTemplate();
    private final KefuAccessTokenManager tokenManager;
    private KefuMessageHandler handler;

    public KefuMessageService(KefuAccessTokenManager tokenManager) {
        this.tokenManager = tokenManager;
    }

    public void setHandler(KefuMessageHandler handler) {
        this.handler = handler;
    }

    // ========================= 接收消息和事件 =========================

    /**
     * 同步消息（拉取新消息）
     */
    public KefuSyncMsgResponse syncMessages(String cursor, String token, Integer limit) {
        String accessToken = tokenManager.getAccessToken();
        String url = BASE_URL + "/kf/sync_msg?access_token=" + accessToken;

        JSONObject body = new JSONObject();
        if (cursor != null && !cursor.isEmpty()) {
            body.put("cursor", cursor);
        }
        if (token != null && !token.isEmpty()) {
            body.put("token", token);
        }
        if (limit != null) {
            body.put("limit", limit);
        }

        String response = postJson(url, body.toJSONString());
        return JSON.parseObject(response, KefuSyncMsgResponse.class);
    }

    /**
     * 处理同步消息（模板方法）
     */
    public void processMessages(KefuSyncMsgResponse response) {
        if (response == null || !response.isSuccess()) {
            logger.error("消息同步响应异常: {}", response != null ? response.getErrmsg() : "null");
            return;
        }

        List<KefuSyncMsg> msgList = response.getMsgList();
        if (msgList == null || msgList.isEmpty()) {
            return;
        }

        logger.info("开始处理 {} 条消息", msgList.size());

        for (KefuSyncMsg msg : msgList) {
            try {
                processMessage(msg);
            } catch (Exception e) {
                logger.error("处理消息异常: msgid={}", msg.getMsgid(), e);
            }
        }
    }

    protected void processMessage(KefuSyncMsg msg) {
        if (handler == null) {
            logger.warn("未设置消息处理器");
            return;
        }

        String msgtype = msg.getMsgtype();

        if ("event".equals(msgtype)) {
            processEvent(msg);
        } else if ("text".equals(msgtype)) {
            String content = msg.getText() != null ? msg.getText().getContent() : "";
            handler.onTextMessage(msg.getOpenKfid(), msg.getExternalUserid(), msg.getMsgid(), content, msg.getSendTime());
        } else if ("image".equals(msgtype)) {
            String mediaId = msg.getImage() != null ? msg.getImage().getMediaId() : "";
            handler.onImageMessage(msg.getOpenKfid(), msg.getExternalUserid(), msg.getMsgid(), mediaId, msg.getSendTime());
        } else {
            handler.onOtherMessage(msg);
        }
    }

    protected void processEvent(KefuSyncMsg msg) {
        if (msg.getEvent() == null || handler == null) {
            return;
        }

        String eventType = msg.getEvent().getEventType();
        String openKfid = msg.getEvent().getOpenKfid();
        String externalUserid = msg.getEvent().getExternalUserid();

        switch (eventType) {
            case "enter_session":
                handler.onEnterSession(openKfid, externalUserid, msg.getEvent().getScene(),
                    msg.getEvent().getSceneParam(), msg.getEvent().getWelcomeCode());
                break;
            case "msg_send_fail":
                handler.onMsgSendFail(openKfid, externalUserid, msg.getEvent().getFailMsgid(), msg.getEvent().getFailType());
                break;
            case "session_status_change":
                handler.onSessionStatusChange(openKfid, externalUserid, msg.getEvent().getChangeType(),
                    msg.getEvent().getOldServicerUserid(), msg.getEvent().getNewServicerUserid());
                break;
            default:
                logger.debug("未处理的事件类型: {}", eventType);
                break;
        }
    }

    // ========================= 发送消息 =========================

    /**
     * 发送文本消息
     */
    public String sendTextMessage(String touser, String openKfid, String content) {
        String accessToken = tokenManager.getAccessToken();
        String url = BASE_URL + "/kf/send_msg?access_token=" + accessToken;

        JSONObject body = new JSONObject();
        body.put("touser", touser);
        body.put("open_kfid", openKfid);
        body.put("msgtype", "text");

        JSONObject text = new JSONObject();
        text.put("content", content);
        body.put("text", text);

        String response = postJson(url, body.toJSONString());
        JSONObject result = JSON.parseObject(response);

        if (result.getIntValue("errcode") == 0) {
            return result.getString("msgid");
        }

        logger.error("发送消息失败: {}", response);
        return null;
    }

    /**
     * 发送客服欢迎语
     */
    public String sendWelcomeMessage(String code, String content) {
        String accessToken = tokenManager.getAccessToken();
        String url = BASE_URL + "/kf/send_msg_on_event?access_token=" + accessToken;

        JSONObject body = new JSONObject();
        body.put("code", code);
        body.put("msgtype", "text");

        JSONObject text = new JSONObject();
        text.put("content", content);
        body.put("text", text);

        String response = postJson(url, body.toJSONString());
        JSONObject result = JSON.parseObject(response);

        if (result.getIntValue("errcode") == 0) {
            return result.getString("msgid");
        }

        logger.error("发送欢迎语失败: {}", response);
        return null;
    }

    /**
     * 撤回消息
     */
    public boolean recallMessage(String msgid) {
        String accessToken = tokenManager.getAccessToken();
        String url = BASE_URL + "/kf/recall_msg?access_token=" + accessToken;

        JSONObject body = new JSONObject();
        body.put("msgid", msgid);

        String response = postJson(url, body.toJSONString());
        JSONObject result = JSON.parseObject(response);

        return result.getIntValue("errcode") == 0;
    }

    private String postJson(String url, String json) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity<String> entity = new HttpEntity<>(json, headers);
        return restTemplate.postForObject(url, entity, String.class);
    }

}
