package com.backendsys.aspect;

import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

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

/**
 * 自动在 控制器 的实体类中加入 { lang: 'zh' } 字段
 * (此写法要求控制器传参为实体类)
 * (详情接口可能要改变传参方式为实体类)
 */

@Aspect
@Component
public class LanguageAspect {

    @Value("${DEFAULT_LANGUAGE}")
    private String DEFAULT_LANGUAGE;

    @Around("@annotation(org.springframework.web.bind.annotation.GetMapping) || @annotation(org.springframework.web.bind.annotation.PostMapping) || @annotation(org.springframework.web.bind.annotation.PutMapping) || @annotation(org.springframework.web.bind.annotation.DeleteMapping)")
    // @Around("@annotation(org.springframework.web.bind.annotation.GetMapping)")
    public Object injectLanguage(ProceedingJoinPoint joinPoint) throws Throwable {

        // 获取 HttpServletRequest 对象
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();

        // 从 Cookie 中获取 lang 值
        // String langValue = getCookieValue(request, "lang");

        // 从 Headers 中获取 lang 值
        String langValue = request.getHeader("lang");
        if (langValue == null || langValue.isEmpty()) langValue = DEFAULT_LANGUAGE;

        // 获取方法参数
        Object[] args = joinPoint.getArgs();

        // 遍历方法参数，查找带有lang字段的实体类，并设置lang的值
        for (Object arg : args) {
            setLangValue(arg, langValue);
        }

        // 调用原始方法
        Object result = joinPoint.proceed(args);

        return result;
    }

    // 通过Cookie名称获取Cookie的值
    private String getCookieValue(HttpServletRequest request, String name) {
        Cookie[] cookies = request.getCookies();
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                if (name.equals(cookie.getName())) {
                    return cookie.getValue();
                }
            }
        }
        return null;
    }

    // 使用反射设置对象中的lang值
    private void setLangValue(Object object, String langValue) throws IllegalAccessException {

        if (object != null) {

            Class<?> clazz = object.getClass();
            Field[] fields = clazz.getDeclaredFields();

            // 遍历对象的所有字段
            for (Field field : fields) {
                // 判断字段是否为lang，并且为String类型
                if (field.getName().equals("lang") && field.getType().equals(String.class)) {
                    field.setAccessible(true);
                    field.set(object, langValue);
                }
            }
        }
    }
}
