package cn.iocoder.foodnexus.module.system.aspect;

import cn.iocoder.foodnexus.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.foodnexus.module.system.annotations.AppSystemAuth;
import cn.iocoder.foodnexus.module.system.dal.dataobject.user.AdminUserDO;
import cn.iocoder.foodnexus.framework.common.enums.UserSystemEnum;
import cn.iocoder.foodnexus.module.system.service.user.AdminUserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import static cn.iocoder.foodnexus.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.foodnexus.module.system.enums.ErrorCodeConstants.NOT_APP_USER;

/**
 * @author : yanghao
 * create at:  2025/4/24  17:27
 * @description: app用户鉴别
 */
@Slf4j
@Aspect
@Component
@RequiredArgsConstructor
public class AppSystemAspect {

    private final AdminUserService userService;

    public static List<Long> CACHE = new ArrayList<>();

    // 切点：匹配所有带有 @AppSystemAuth 注解的方法
    @Pointcut("@annotation(cn.iocoder.foodnexus.module.system.annotations.AppSystemAuth)")
    public void appSystemAuthPointcut() {}

    // 前置通知
    @Before("appSystemAuthPointcut() && @annotation(appSystemAuth)")
    public void beforeAppSystemAuth(JoinPoint joinPoint, AppSystemAuth appSystemAuth) {
        Long loginUserId = SecurityFrameworkUtils.getLoginUserId();
        if (!CACHE.contains(loginUserId)) {
            AdminUserDO user = userService.getUser(loginUserId);

            if (appSystemAuth.value() == null) {
                if (!UserSystemEnum.isAppUser(user.getUserSystem())) {
                    throw exception(NOT_APP_USER);
                }
            } else {
                // 校验用户体系是否在允许范围内
                if (Arrays.stream(appSystemAuth.value()).noneMatch(e -> e.getKey() == user.getUserSystem())) {
                    throw exception(NOT_APP_USER);
                }
            }
        }
        CACHE.add(loginUserId);
    }

}
