package com.wzj.soopin.im.service.impl;

import cn.hutool.json.JSONObject;
import com.wzj.soopin.im.domain.SysMessageTemplate;
import com.wzj.soopin.im.service.IMQMessageHandleService;
import com.wzj.soopin.im.service.ISysMessageTemplateService;
import com.wzj.soopin.im.service.ITencentIMService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.constant.CacheConstants;
import org.dromara.common.json.utils.JsonUtils;
import org.dromara.common.mq.domain.MQMessage;
import org.dromara.common.mq.enums.MessageActionEnum;
import org.dromara.common.redis.redis.RedisCache;
import org.dromara.system.websocket.MessageWebSocketServer;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

@Service
@RequiredArgsConstructor
@Slf4j
public class MQMessageHandleServiceImpl implements IMQMessageHandleService {
    // 变量替换的正则表达式模式
    private final RedisCache redisCache;
    private final ISysMessageTemplateService templateService;
    private final ITencentIMService tencentIMService;
    private final MessageWebSocketServer messageWebSocketServer;

    public boolean handleMessage(MQMessage message) {
        // 消息幂等性检查
        String messageId = message.getMessageId();
        // 检查消息是否已处理
        if (redisCache.getCacheObject(CacheConstants.IM_MSG_RECEIVE + messageId) != null) {
            log.info("消息已处理，忽略重复消息：{}", messageId);
            return true;
        }
        //创建im消息
        //根据消息类型获取消息模板
        Map<String, Object> params = (Map<String, Object>) message.getData();
        String action = (String) params.get("action");
        //根据action获取消息模板
        MessageActionEnum actionEnum = MessageActionEnum.getByAccount(action);
        if(actionEnum == null){
            log.error("根据action获取消息模板失败，action：{}", action);
            return false;
        }

        SysMessageTemplate template = templateService.getTemplateByAction(actionEnum.getCode());

        if (template == null) {
            log.error("根据action获取消息模板失败，action：{}", action);
            return true;
        }

        // 首先尝试发送消息到腾讯IM
        boolean tencentIMSendSuccess = false;
        try {
            // 消息发送者可能是系统或管理员，这里使用action对应的账号发送
            String fromUserId = actionEnum.getAccount();
            String toUserId = ""; // 接收者是事件中的用户ID
            String content = template.getContent(); // 只取content字段

            // 处理消息变量替换（如果有）
            // 从消息中提取标题和描述
            String title = template.getTitle();
            String desc = template.getContent();
            // 扩展字段，可以在APP端获取
            String ext = template.getExt();
            // 处理变量替换
            if (params.size() > 0) {
                title = processMessageVariables(title, params);
                desc = processMessageVariables(desc, params);
                content = processMessageVariables(content, params);
                ext = processMessageVariables(ext, params);
                toUserId = String.valueOf(params.get("toUserId"));
            }

            String pushType = null;
            // 根据消息类型决定推送方式
            String templateParams = template.getParams();
            if (templateParams != null) {
                JSONObject param = new JSONObject(templateParams);
                // 从消息参数中提取接收者
                if (param != null && param.containsKey("pushType")) {
                    pushType = String.valueOf(param.get("pushType"));
                }
            }

            if (pushType != null) {
                switch (pushType) {
                    case "ALL":
                        // 全员推送
                        tencentIMSendSuccess = tencentIMService.pushToAll(title, desc, true, ext);
                        break;
                    case "ATTRIBUTE":
                        // 属性推送
                        Map<String, Object> attributes = new HashMap<>();
                        // 从消息参数中提取属性条件
                        if (params != null && params.containsKey("attributes")) {
                            Object attrObj = params.get("attributes");
                            if (attrObj instanceof Map) {
                                attributes = (Map<String, Object>) attrObj;
                            }
                        }
                        tencentIMSendSuccess = tencentIMService.pushByAttributes(title, desc, attributes, true, ext);
                        break;
                    case "TAG":
                        // 标签推送
                        if (params != null && params.containsKey("tags")) {
                            Object tagsObj = params.get("tags");
                            if (tagsObj instanceof String[]) {
                                tencentIMSendSuccess = tencentIMService.pushByTags(title, desc,
                                    Arrays.asList((String[]) tagsObj), true, ext);
                            }
                        }
                        break;
                    case "USER":
                    default:
                        // 单用户推送（默认）
                        tencentIMSendSuccess = tencentIMService.pushToUsers(title, desc,
                            Collections.singletonList(toUserId), true, ext);
                        break;
                }
            } else {
                // 默认为单用户推送
                tencentIMSendSuccess = tencentIMService.sendMessageToTencentIM(fromUserId, toUserId, content, ext);
            }
            if (tencentIMSendSuccess) {
                log.info("腾讯IM推送成功，userId={}", toUserId);
            } else {
                log.error("腾讯IM推送失败，userId={}", toUserId);
            }
            // 如果前两种方式都失败，则尝试直接通过WebSocket发送
            if (!tencentIMSendSuccess) {
                try {
                    messageWebSocketServer.sendMessage(
                        Long.parseLong(toUserId),
                        JsonUtils.toJsonString(message)
                    );
                    log.info("消息事件已直接通过WebSocket发送，userId: {}", toUserId);
                } catch (Exception e) {
                    log.error("通过WebSocket发送消息失败", e);
                }
            }
        } catch (Exception e) {
            log.error("发送消息到腾讯IM异常，将尝试通过其他方式发送", e);
        }
        return true;
    }

    public String processMessageVariables(String content, Map<String, Object> variables) {
        if (content == null || variables == null || variables.isEmpty()) {
            return content;
        }
        for (String key : variables.keySet()) {
            content = content.replaceAll("\\$\\{" + key + "\\}", variables.get(key).toString());
        }
        return content;
    }

}
