package com.njzscloud.common.mvc.support;

import cn.hutool.core.util.StrUtil;
import com.njzscloud.common.core.ienum.Dict;
import com.njzscloud.common.core.ienum.DictInt;
import com.njzscloud.common.core.ienum.DictStr;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

/**
 * 字典枚举参数处理器
 */
@SuppressWarnings({"ConstantConditions"})
public class DictHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {

    /**
     * 支持 {@link DictInt} 和 {@link DictStr} 类型的返回值
     *
     * @param parameter 返回值信息
     * @return 当参数类型为 DictInt 或 DictStr 时返回 true
     */
    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return DictInt.class.isAssignableFrom(parameter.getParameterType()) || DictStr.class.isAssignableFrom(parameter.getParameterType());
    }

    /**
     * 解析参数
     *
     * @param parameter 参数信息
     * @param container 当前请求的模型视图容器
     * @param request   当前请求对象
     * @param factory   创建 {@link WebDataBinder} 的工厂对象
     * @return 返回 {@link DictInt} 或 {@link DictStr} 对象
     */
    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer container, NativeWebRequest request, WebDataBinderFactory factory) throws Exception {
        String parameterName = parameter.getParameterName();
        String param = request.getParameter(parameterName);

        if (StrUtil.isBlank(param)) return null;

        Class<?> type = parameter.getParameterType();

        if (DictInt.class.isAssignableFrom(type)) {
            Integer val = Integer.parseInt(param);
            DictInt[] constants = (DictInt[]) type.getEnumConstants();
            return Dict.parse(val, constants);
        } else if (DictStr.class.isAssignableFrom(type)) {
            DictStr[] constants = (DictStr[]) type.getEnumConstants();
            return Dict.parse(param, constants);
        } else {
            return null;
        }
    }
}
