package com.fdkankan.common.interceptor;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fdkankan.common.annotation.Dict;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Objects;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

/**
 * 记录注册用户操作记录、异常记录
 */
@Slf4j
@Aspect
@Order(100)
@Component
public class DictAspect {

	@Pointcut("@annotation(com.fdkankan.common.annotation.Dict)")
	public void dictAspect() {
	}

	@AfterReturning(pointcut = "dictAspect()", returning = "res")
	public void afterReturning(JoinPoint joinPoint, Object res) throws Exception {
		if(Objects.isNull(res)){
			return;
		}
		if(res instanceof Page){
			Page page = (Page)res;
			List records = page.getRecords();
			if(CollUtil.isEmpty(records)){
				return;
			}
			records.stream().forEach(obj->{
				try {
					this.handler(obj);
				} catch (Exception e) {
					log.info("类型转换名称报错", e);
				}
			});
		}else if(res instanceof Iterable){
			((Iterable<?>) res).forEach(obj ->{
				try {
					this.handler(obj);
				} catch (Exception e) {
					log.info("类型转换名称报错", e);
				}
			});
		}else{
			this.handler(res);
		}
	}

	private void handler(Object obj) throws Exception{
		Class<?> clazz = obj.getClass();
		Field[] declaredFields = clazz.getDeclaredFields();
		for (Field field : declaredFields) {
			Dict annotation = field.getAnnotation(Dict.class);
			if(Objects.isNull(annotation)){
				continue;
			}
			String name = field.getName();
			Field strField = clazz.getDeclaredField(name + "Str");
			if(Objects.isNull(strField)){
				continue;
			}
			field.setAccessible(true);
			Class<?> enumClazz = annotation.enumClazz();
			Method getCode = enumClazz.getMethod("code");
			Method getMessage = enumClazz.getMethod("message");
			Object[] enumConstants = enumClazz.getEnumConstants();
			for (Object enumConstant : enumConstants) {
				Object code = getCode.invoke(enumConstant);
				if(code.equals(field.get(obj))){
					Object message = getMessage.invoke(enumConstant);
					strField.setAccessible(true);
					strField.set(obj, message);
				}
			}

		}
	}

}
