package cn.axzo.msg.center.message.service.impl.v3;

import cn.axzo.msg.center.domain.entity.MessageEntity;
import cn.axzo.msg.center.inside.notices.config.PendingMessageBizConfig;
import cn.axzo.msg.center.message.service.todo.manage.TodoExt;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.Nullable;

import java.net.URLEncoder;
import java.util.Map;

/**
 * @author yanglin
 */
@Slf4j
public class TodoUrlParser extends UrlParser {

    private final PendingMessageBizConfig cfg;
    protected final MessageEntity entity;
    @Nullable private final JSONObject appendRouterParam;

    public TodoUrlParser(PendingMessageBizConfig cfg,
                         MessageEntity entity,
                         JSONObject routerParam,
                         @Nullable JSONObject appendRouterParam) {
        super(routerParam);
        this.cfg = cfg;
        this.entity = entity;
        this.appendRouterParam = appendRouterParam;
    }

    @Override
    protected String parseUrl(String url) {
        if (StringUtils.isBlank(url)) return url;
        boolean populateWorkspaceId =
                // @formatter:off
                cfg.getPopulateWorkspaceIdTemplateCodes().contains(entity.getTemplateCode())

                        && entity.getReceiverWorkspaceId() != null
                        && entity.getReceiverWorkspaceId() > 0L

                        && !routerParam.containsKey("workspaceId")

                        && url.matches(".*\\$\\{\\s*workspaceId\\s*}.*");
        // @formatter:on
        if (populateWorkspaceId)
            routerParam.put("workspaceId", entity.getReceiverWorkspaceId());
        try {
            String parsedUrl = super.parseUrl(url);
            if (cfg.isConcatRouterParams(entity.getTemplateCode()))
                parsedUrl = appendRouterParam(parsedUrl, appendRouterParam);
            return parsedUrl;
        } finally {
            if (populateWorkspaceId)
                routerParam.remove("workspaceId");
        }
    }

    private String appendRouterParam(String url, @Nullable JSONObject routerParam) {
        if (routerParam == null)
            return url;
        Object ctx = routerParam.remove(TodoExt.CTX);
        try {
            if (routerParam.isEmpty()) {
                return url;
            }
            StringBuilder paramBuilder = new StringBuilder();
            for (Map.Entry<String, Object> entry : routerParam.entrySet()) {
                if (url.contains(entry.getKey() + "=")) {
                    continue;
                }
                String value = tryEncode(entry.getValue());
                paramBuilder.append("&").append(entry.getKey()).append("=").append(value);
            }
            if (StringUtils.isBlank(paramBuilder.toString())) {
                return url;
            }
            if (!url.contains("?")) {
                // 替换掉第一个参数分隔符(&)
                paramBuilder.replace(0, 1, "?");
            }
            return url + paramBuilder;
        } finally {
            if (ctx != null) {
                routerParam.put(TodoExt.CTX, ctx);
            }
        }
    }

    String tryEncode(Object o) {
        String value = String.valueOf(o);
        try {
            value = URLEncoder.encode(value, "UTF-8");
        } catch (Exception e) {
            log.warn("error encode pending dynamic value. value={}", value);
        }
        return value;
    }

}