package net.vtstar.zhongtong.avi.global.listener;


import io.swagger.annotations.ApiModel;
import lombok.extern.slf4j.Slf4j;
import net.vtstar.user.search.Search;
import net.vtstar.user.util.ReadAnnotationUtils;
import net.vtstar.zhongtong.avi.global.web.Show;
import net.vtstar.zhongtong.avi.global.web.domain.ShowField;
import net.vtstar.zhongtong.avi.global.web.domain.enums.FieldType;
import org.springframework.cache.Cache;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

@Slf4j
@Component
public class WebFiledListener implements ApplicationListener<ContextRefreshedEvent> {

    @Resource(name = "showFieldCache")
    private Cache showFieldCache;

    @Resource(name = "classNameCache")
    private Cache classNameCache;

    @Override
    public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {

        Set<Class> classes = ReadAnnotationUtils.getClazzFromAnnotation("net.vtstar.zhongtong", Search.class);
        if (CollectionUtils.isEmpty(classes)) {
            return;
        }

        for (Class<?> clazz : classes) {
            Search clazzAnnotation = clazz.getAnnotation(Search.class);
            if (StringUtils.isEmpty(clazzAnnotation.code())) {
                log.error("{} 类@Search注解code属性未赋值！", clazz);
            }
            classNameCache.put(clazzAnnotation.code(), clazz);
            String name = clazz.getAnnotation(ApiModel.class).description();
            if (!StringUtils.isEmpty(name)){
                classNameCache.put(clazzAnnotation.code() + "name", name);
            }
            List<ShowField> showFileds = new ArrayList<>();
            Field[] fields = clazz.getDeclaredFields();
            for (Field field : fields) {
                ShowField showFiled = new ShowField();
                Show annotation = field.getAnnotation(Show.class);
                if (null == annotation) {
                    continue;
                }
                String value = annotation.value();
                if (StringUtils.isEmpty(value)) {
                    value = field.getName();
                }
                showFiled.setValue(value);
                String label = annotation.label();
                if (StringUtils.isEmpty(label)) {
                    log.error("{} 类{} 字段 @show 注解 label 属性未赋值", clazz, field.getName());
                }
                showFiled.setLabel(label);
                FieldType fieldType = annotation.dataType();
                if (null == fieldType) {
                    fieldType = FieldType.STRING;
                }
                showFiled.setDateType(fieldType.toString());
                int width = annotation.width();
                if (0 == width){
                    showFiled.setWidth(null);
                } else {
                    showFiled.setWidth(new BigDecimal(width));
                }

                showFileds.add(showFiled);
            }
            showFieldCache.put(clazzAnnotation.code(), showFileds);
        }
    }
}
