package com.tzy.framework.aspectj;

import com.alibaba.fastjson.JSONObject;
import com.tzy.common.dto.InDto;
import com.tzy.common.dto.OutDTO;
import com.tzy.common.exception.ServiceException;
import com.tzy.common.utils.spring.SpringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

@Aspect
@Component
public class UserCheckAspect {

    @Around("@annotation(com.tzy.common.annotation.CheckUser)")
    public Object checkUser(ProceedingJoinPoint joinPoint) throws Throwable {
        Object[] args = joinPoint.getArgs();
        if (args.length > 0 && args[0] instanceof InDto) {
            InDto inDto = (InDto) args[0];
            //通过spring 上下文获取 bean
            Object mineApiService = SpringUtils.getBean("mineApiService");

            if (mineApiService == null) {
                return OutDTO.error(500, "MineApiService 未初始化");
            }

            // 获取 Class 对象
            Class<?> clazz = mineApiService.getClass();

            try {
                // 获取 checkUser 方法，参数类型为 InDto
                Method method = clazz.getMethod("checkUser", InDto.class);

                // 调用方法
                Object result = method.invoke(mineApiService, inDto);

                if (result instanceof OutDTO) {
                    OutDTO outDTO = (OutDTO) result;
                    if (!outDTO.isSuccess()) {
                        return outDTO;
                    }

                    // 获取 userInfo
                    Object userInfoObj = outDTO.get("userInfo");
                    JSONObject userInfo = JSONObject.parseObject(JSONObject.toJSONString(userInfoObj));
                    inDto.put("appUserInfoDto", userInfo);
                    inDto.setUserId((Integer) userInfo.get("id"));
                }
            } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
                e.printStackTrace();
                throw new ServiceException(500, "调用 checkUser 方法失败");
            }
        }
        return joinPoint.proceed();
    }
}
