package com.njzscloud.common.http.resolver;

import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import com.njzscloud.common.http.annotation.PathParam;
import com.njzscloud.common.http.constant.HttpMethod;
import com.njzscloud.common.http.processor.PathParamProcessor;

import java.math.RoundingMode;
import java.util.Map;
import java.util.TreeMap;

public class PathParamResolver extends ParamResolver<PathParam, String> {
    Map<String, String> result = new TreeMap<>();

    public PathParamResolver() {
        super(PathParam.class);
    }

    @Override
    public String resolve(HttpMethod httpMethod, String urlTpl) {
        if (result.isEmpty()) return urlTpl;
        return StrUtil.format(urlTpl, result);
    }

    @Override
    @SuppressWarnings("unchecked")
    protected boolean resolveParameter(PathParam anno, String paramName, Class<?> paramClazz, Object paramValue) {
        if (isKv(paramClazz)) resolveKv(paramValue);
        else if (isStr(paramClazz) || isNum(paramClazz) || isDt(paramClazz)) resolveFormable(anno, paramName, paramClazz, paramValue);
        else return false;
        return true;
    }


    @Override
    @SuppressWarnings("unchecked")
    protected boolean resolveField(boolean hasParameterAnno, PathParam anno, String paramName, Class<?> paramClazz, Object paramValue) {
        if (anno != null) {
            Class<? extends PathParamProcessor> processorClazz = anno.processor();
            if (processorClazz != PathParamProcessor.class) {
                ReflectUtil.newInstance(processorClazz).process(anno, paramName, paramClazz, paramValue, result);
            } else if (!hasParameterAnno && isKv(paramClazz)) {
                resolveKv(paramValue);
            }
        }
        resolveFormable(anno, paramName, paramClazz, paramValue);
        return true;
    }

    protected void resolveFormable(PathParam anno, String paramName, Class<?> paramClazz, Object paramValue) {
        String key = paramName;
        String val;

        String format = null;
        RoundingMode roundingMode = null;
        if (anno != null) {
            format = anno.format();
            roundingMode = anno.roundingMode();
            String value = anno.value();
            if (StrUtil.isNotBlank(value)) key = value;
        }

        if (isNum(paramClazz)) {
            val = formatNum(format, roundingMode, paramValue);
        } else if (isDt(paramClazz)) {
            val = formatDt(format, paramValue);
        } else {
            val = paramValue.toString();
        }
        result.put(key, val);
    }

}
