package com.ruoyi.common.wrapper;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.ruoyi.common.annotation.DictText;
import com.ruoyi.common.core.service.DictService;
import com.ruoyi.common.utils.spring.SpringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author
 */
@Slf4j
public class DictTextWrapper implements BaseWrapper<Object> {

    /**
     * 字典数据输出后缀
     */
    private static final String DICT_OUTPUT_SUFFIX = "Text";

    @Override
    public Object doWrap(Object beWrappedModel) {
//        Map<String, Object> map = BeanUtil.beanToMap(beWrappedModel);

        Class<?> aClass = beWrappedModel.getClass();
        Field[] declaredFields = aClass.getDeclaredFields();
        for (Field field : declaredFields) {
            DictText dictText = field.getAnnotation(DictText.class);
            if (ObjectUtil.isNotNull(dictText)) {
                field.setAccessible(true);
                try {
//                    // 获取要解析的字段的类型
//                    Class<?> fieldTypeClass = field.getType();
                    // 如果字段是List类型
                    Method fieldGetMethod = aClass.getMethod(transGetMethodFromList(field.getName()));
                    Object fieldObj = fieldGetMethod.invoke(beWrappedModel);
                    if (fieldObj instanceof List) {
                        ArrayList list = (ArrayList) fieldObj;
                        ArrayList<Object> newList = new ArrayList<>();
                        list.forEach(obj -> {
                            newList.add(doWrap(obj));
                        });
                        if (!newList.isEmpty()) {
                            String name = field.getName();
//                            map.put(name, newList);
                            field.set(name, newList);
                        }
                    }
                    //如果是Stirng、Integer、Long类型
                    else if (fieldObj instanceof String || fieldObj instanceof Integer || fieldObj instanceof Long) {
                        basicTypeField(beWrappedModel, field, dictText.dictType());
                    }

                    //如果是实体类型
                    else if (fieldObj != null) {
                        Object map1 = doWrap(fieldObj);
                        String name = field.getName();
                        field.set(name, map1);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    log.error("----->>>>字典数据输出错误<<<<------", e.getMessage());
                }
            }
        }
        return beWrappedModel;
    }

    private void basicTypeField(Object beWrappedModel, Field field, String dictType) throws IllegalAccessException {
        String fieldValue = field.get(beWrappedModel).toString();
        if (ObjectUtil.isNull(fieldValue)) {
            return;
        }

        //根据字典表dictType、dictValue查询值
        DictService dictService = SpringUtils.getBean(DictService.class);
        String dictLabel = dictService.getDictLabel(dictType, fieldValue);
        if (StringUtils.isNotBlank(dictLabel)) {
            String name = field.getName();

            try {
                Field fieldText = beWrappedModel.getClass().getDeclaredField(name + DICT_OUTPUT_SUFFIX);
                PropertyDescriptor propertyDescriptor = new PropertyDescriptor(fieldText.getName(), beWrappedModel.getClass());
                Method method = propertyDescriptor.getWriteMethod();
                method.invoke(beWrappedModel,dictLabel);
            } catch (Exception e) {
                e.printStackTrace();
            }


        }

    }

    private String transGetMethodFromList(String fieldName) {
        return "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
    }

    private String transSetMethodFromList(String fieldName) {
        return "set" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
    }

}
