package com.brframework.commoncms.core.layout.layout;

import com.brframework.commoncms.annatotion.layout.EditLayout;
import com.brframework.commoncms.annatotion.layout.ViewLayout;
import com.brframework.commoncms.core.layout.AbstractPanelLayout;
import com.brframework.commoncms.core.layout.PanelLayoutColumn;
import com.brframework.commoncms.utils.ControllerUtil;
import com.brframework.commonweb.exception.HandleException;
import com.brframework.commonweb.json.JSONResult;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import org.springframework.core.ResolvableType;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.core.annotation.AnnotationUtils;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;

/**
 * @author xu
 * @date 2018/9/26 13:49
 */
@Data
public class PanelViewLayout extends AbstractPanelLayout {

    /**
     * 只读
     */
    public static final String TYPE = "VIEW";


    private List<PanelLayoutColumn> columns;

    /**
     * 数据填充的URL
     * 默认情况下是submitUrl的GET请求
     */
    private String paddingUrl;

    @Override
    public String getType() {
        return TYPE;
    }

    @Override
    public void create(Method method) throws Throwable {
        init(method);

        Class<?> returnType = method.getReturnType();

        if (!returnType.getName().equals(JSONResult.class.getName())) {
            throw new HandleException("返回值类型" + returnType.getName() + "非协议类型");
        }

        ResolvableType methodType = ResolvableType.forMethodReturnType(method);

        //获取Data
        ResolvableType dataType = methodType.getGeneric(0);
        if (AnnotationUtils.findAnnotation(dataType.getRawClass(), ApiModel.class) == null) {
            throw new HandleException("返回值类型必须是ApiModel注解标识的类");
        }

        columns = Lists.newArrayList();
        List<Field> returnTypeFields = ControllerUtil.handlerPropertyField(
                ControllerUtil.getAllField(dataType.getRawClass())
        );
        for (Field returnTypeField : returnTypeFields) {
            columns.add(ControllerUtil.createColumn(returnTypeField));
        }

        paddingUrl = getPaddingUrl(method);
        if(Strings.isNullOrEmpty(paddingUrl)){
            //处理方法名映射
            String paddingMappingMethod = getPaddingMappingMethod(method);
            if(!Strings.isNullOrEmpty(paddingMappingMethod)){
                paddingUrl = handlerPaddingMapping(method, paddingMappingMethod);
            }
        }

    }

    private String handlerPaddingMapping(Method method, String paddingMappingMethod){
        if(Strings.isNullOrEmpty(paddingMappingMethod)) return null;

        Method[] declaredMethods = method.getDeclaringClass().getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            if (declaredMethod.getName().equals(paddingMappingMethod)) {
                return ControllerUtil.getControllerUrl(declaredMethod);
            }
        }

        return null;
    }

    /**
     * 数据填充
     * @param method
     * @return
     */
    protected String getPaddingUrl(Method method){
        ViewLayout editLayout = AnnotatedElementUtils.findMergedAnnotation(method, ViewLayout.class);

        return editLayout.paddingUrl();
    }

    /**
     * 数据填充映射方法
     * @param method
     * @return
     */
    protected String getPaddingMappingMethod(Method method){
        ViewLayout editLayout = AnnotatedElementUtils.findMergedAnnotation(method, ViewLayout.class);
        return editLayout.paddingMappingMethod();
    }

}
