package com.kingdee.eas.custom.weaverTodo.server;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.kingdee.bos.Context;
import com.kingdee.bos.dao.ormapping.ObjectUuidPK;
import com.kingdee.bos.util.BOSUuid;
import com.kingdee.eas.base.message.BMCMessageFactory;
import com.kingdee.eas.base.message.BMCMessageInfo;
import com.kingdee.eas.base.message.IBMCMessage;
import com.kingdee.eas.base.message.MsgStatus;
import com.kingdee.eas.base.permission.UserInfo;
import com.kingdee.eas.custom.weaverTodo.client.WeaverSendMsgClient;
import com.kingdee.eas.custom.weaverTodo.config.WeaverTodoConfig;
import com.kingdee.eas.custom.weaverTodo.enums.WeaverCallOperTypeEnum;
import com.kingdee.eas.custom.weaverTodo.util.WeaverTodoSupport;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;

import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

/**
 * BMC 通知：走消息中心 sendMsg，不再推统一待办 isremark=8。
 * 只发送，不做已读回写；无 BMC url 时不传 entity.pcUrl。
 * 发送人：getSenderId 查用户 number/name；正文 getBody；人员只传 workCode。
 */
public class WeaverToBeReadMessageServer {
    private static final Logger logger = Logger.getLogger(WeaverToBeReadMessageServer.class);
    private static final String BMC_BOS_TYPE = "41C9B39B";

    private final WeaverTodoConfig config;
    private final WeaverTodoSupport support;
    private final WeaverSendMsgClient sendMsgClient;

    public WeaverToBeReadMessageServer(WeaverTodoConfig config,
                                       WeaverTodoSupport support,
                                       WeaverSendMsgClient sendMsgClient) {
        this.config = config;
        this.support = support;
        this.sendMsgClient = sendMsgClient;
    }

    public boolean handleToBeReadMessage(String id, MsgStatus msgStatus, Context ctx, String traceId) {
        String tid = StringUtils.isBlank(traceId) ? "-" : traceId;
        logger.info("[WEAVER-TOREAD][" + tid + "] 业务=通知sendMsg BEGIN id=" + id
                + " status=" + (msgStatus == null ? null : msgStatus.getAlias()));
        try {
            if (MsgStatus.READED.equals(msgStatus)) {
                logger.info("[WEAVER-TOREAD][" + tid + "] 业务=通知sendMsg 跳过：已读不回写泛微");
                return true;
            }
            BOSUuid bosId = BOSUuid.read(id);
            String bosType = bosId.getType().toString();
            if (!BMC_BOS_TYPE.equalsIgnoreCase(bosType)) {
                logger.info("[WEAVER-TOREAD][" + tid + "] 业务=通知sendMsg 跳过：非BMC bosType=" + bosType);
                return false;
            }
            IBMCMessage msgIns = BMCMessageFactory.getLocalInstance(ctx);
            BMCMessageInfo msgInfo = msgIns.getBMCMessageInfo(new ObjectUuidPK(id));
            String receiver = support.resolveReceiverWorkcode(ctx, msgInfo.getReceiver());
            if (StringUtils.isBlank(receiver)) {
                logger.error("[WEAVER-TOREAD][" + tid + "] 业务=通知sendMsg 放弃：接收人工号为空 id=" + id);
                return false;
            }
            String title = support.sanitize(StringUtils.defaultIfBlank(msgInfo.getTitle(), "SHR通知"));
            // 正文：BMCMessageInfo.getBody()；空则回退标题
            String text = support.sanitize(StringUtils.defaultIfBlank(msgInfo.getBody(), title));
            String senderId = msgInfo.getSenderId();
            UserInfo senderUser = trySenderKey(ctx, senderId);
            String senderWorkCode = senderUser == null ? "" : StringUtils.trimToEmpty(senderUser.getNumber());
            String senderName = senderUser == null ? "" : StringUtils.trimToEmpty(senderUser.getName());
            if (StringUtils.isBlank(senderWorkCode)) {
                logger.error("[WEAVER-TOREAD][" + tid + "] 业务=通知sendMsg 放弃：发送人工号为空 senderId="
                        + senderId + " id=" + id);
                return false;
            }
            if (StringUtils.isBlank(senderName)) {
                senderName = senderWorkCode;
            }

            JSONObject payload = buildSendMsgPayload(id, title, text, receiver, senderWorkCode, senderName, msgInfo.getUrl());
            logger.info("[WEAVER-TOREAD][" + tid + "] 业务=通知sendMsg 即将推送 title=" + title
                    + " receiver=" + receiver + " sender=" + senderWorkCode);
            String resp = sendMsgClient.push(payload, tid);
            boolean ok = WeaverSendMsgClient.isSuccess(resp);
            support.addCallLog(ctx, id, "", "", WeaverCallOperTypeEnum.NOTIFY_SEND,
                    support.buildSendMsgUrl(),
                    payload.toJSONString(), resp, ok ? 1 : 0,
                    "traceId=" + tid + " sendMsg " + (ok ? "成功" : "失败"));
            logger.info("[WEAVER-TOREAD][" + tid + "] 业务=通知sendMsg END ok=" + ok);
            return ok;
        } catch (Exception e) {
            logger.error("[WEAVER-TOREAD][" + tid + "] 业务=通知sendMsg 异常 id=" + id, e);
            support.addCallLog(ctx, id, "", "", WeaverCallOperTypeEnum.NOTIFY_SEND,
                    support.buildSendMsgUrl(),
                    "", e.getMessage(), 0, "traceId=" + tid + " " + e.getMessage());
            return false;
        }
    }

    /**
     * 用 BMC 发送人 id 查用户，取 number / name。
     */
    private UserInfo trySenderKey(Context ctx, String senderId) {
        return support.getUserById(ctx, senderId);
    }

    private JSONObject buildSendMsgPayload(String msgId,
                                           String title,
                                           String text,
                                           String receiverWorkCode,
                                           String senderWorkCode,
                                           String senderName,
                                           String bmcUrl) throws Exception {
        JSONObject body = new JSONObject();
        body.put("title", title);
        body.put("text", StringUtils.defaultIfBlank(text, title));
        body.put("eventId", config.getNotifyEventId());
        body.put("moduleId", config.getNotifyModuleId());
        body.put("todo", Boolean.FALSE);

        JSONObject sender = new JSONObject();
        sender.put("tenantKey", config.getNotifyTenantKey());
        sender.put("workCode", senderWorkCode);
        sender.put("name", senderName);
        body.put("sender", sender);

        JSONArray receivers = new JSONArray();
        JSONObject receiver = new JSONObject();
        receiver.put("tenantKey", config.getNotifyTenantKey());
        receiver.put("workCode", receiverWorkCode);
        receivers.add(receiver);
        body.put("recivers", receivers);

        JSONArray channels = new JSONArray();
        int[] ch = config.getNotifyChannels();
        for (int i = 0; i < ch.length; i++) {
            channels.add(Integer.valueOf(ch[i]));
        }
        body.put("channels", channels);

        JSONObject entity = new JSONObject();
        entity.put("id", StringUtils.defaultString(msgId));
        entity.put("name", title.length() > 100 ? title.substring(0, 100) : title);
        if (StringUtils.isNotBlank(bmcUrl)) {
            entity.put("pcUrl", buildSsoRelativeUrl(bmcUrl.trim()));
        }
        body.put("entity", entity);
        return body;
    }

    private String buildSsoRelativeUrl(String bmcUrl) throws Exception {
        String redirectTarget;
        if (bmcUrl.startsWith("http://") || bmcUrl.startsWith("https://")) {
            redirectTarget = bmcUrl;
        } else if (bmcUrl.startsWith("/")) {
            redirectTarget = config.getShrServerName() + bmcUrl;
        } else {
            redirectTarget = config.getShrServerName() + "/" + bmcUrl;
        }
        String entryPath = StringUtils.defaultIfBlank(config.getSsoEntryPath(), "/qy/auth/weaver/app.do");
        String charset = StandardCharsets.UTF_8.name();
        return entryPath + "?appId=" + URLEncoder.encode(config.getSsoAppId(), charset)
                + "&redirect=" + URLEncoder.encode(redirectTarget, charset);
    }
}
