package com.wzj.soopin.member.annotation;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.wzj.soopin.member.domain.vo.MemberVO;
import com.wzj.soopin.member.service.IMemberService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.dromara.common.core.domain.R;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.util.Collection;

@Aspect
@Component
@RequiredArgsConstructor
@Slf4j
public class MemberFillAspect {

    private final IMemberService memberService;

    @Around("@annotation(com.wzj.soopin.member.annotation.MemberFillMethod)")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        Object result = joinPoint.proceed();
        if (result instanceof R<?>) {
            Object data = ((R<?>) result).getData();
            if (data != null) {
                processObject(data);
            }
        }
        return result;
    }

    private void processObject(Object obj) {

        //基础类型跳过
        if (obj == null || isPrimitiveType(obj.getClass())) return;

        // 处理集合类型
        if (obj instanceof Collection) {
            for (Object item : (Collection<?>) obj) {
                processObject(item);
            }
            return;
        }

        // 处理分页类型
        if (obj instanceof IPage<?>) {

            for (Object item : (Collection<?>)((IPage<?>) obj).getRecords()) {
                processObject(item);
            }
            return;
        }

        // 处理数组类型
        if (obj.getClass().isArray()) {
            int length = java.lang.reflect.Array.getLength(obj);
            for (int i = 0; i < length; i++) {
                processObject(java.lang.reflect.Array.get(obj, i));
            }
            return;
        }



        // 同原 MemberFillInterceptor 中的逻辑，简化处理
        Class<?> clazz = obj.getClass();
        while (clazz != null && clazz != Object.class) {
            for (Field field : clazz.getDeclaredFields()) {
                if (field.isAnnotationPresent(MemberFillField.class)) {
                    handleMemberFill(obj, field);
                }
            }
            clazz = clazz.getSuperclass();
        }
    }

    // 判断是否为基本类型或包装类型
    private boolean isPrimitiveType(Class<?> clazz) {
        return clazz.isPrimitive() ||
            clazz.equals(String.class) ||
            clazz.equals(Integer.class) ||
            clazz.equals(Long.class) ||
            clazz.equals(Double.class) ||
            clazz.equals(Float.class) ||
            clazz.equals(Boolean.class) ||
            clazz.equals(Character.class) ||
            clazz.equals(Short.class) ||
            clazz.equals(Byte.class);
    }

    private void handleMemberFill(Object obj, Field field) {
        try {
            field.setAccessible(true);
            MemberFillField annotation = field.getAnnotation(MemberFillField.class);
            String memberIdFieldName = annotation.id();

            Field idField = findField(obj.getClass(), memberIdFieldName);
            idField.setAccessible(true);
            Object memberId = idField.get(obj);

            if (memberId instanceof Long) {
                MemberVO member = memberService.getMemberInfo((Long) memberId);
                if (member != null) {
                    field.set(obj, member);
                }
            }
        } catch (Exception e) {
            log.error("会员信息填充失败", e);
        }
    }

    private Field findField(Class<?> clazz, String fieldName) throws NoSuchFieldException {
        try {
            return clazz.getDeclaredField(fieldName);
        } catch (NoSuchFieldException e) {
            Class<?> superClass = clazz.getSuperclass();
            if (superClass == null) throw e;
            return findField(superClass, fieldName);
        }
    }
}

