package com.xunhong.erp.turbo.web.aspect;

import com.alibaba.cola.dto.DTO;
import com.xunhong.erp.turbo.base.dto.UserSession;
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.Method;
import java.util.Objects;

@Aspect
@Component
public class MerchantIdAspect {

	private static void setParam(DTO dto, String methodName, Long methodNameValue) {
		if (methodNameValue == null) {
			return;
		}

		try {
			if (Objects.nonNull(dto.getClass().getMethod("get" + methodName).invoke(dto))) {
				return;
			}

			Method method = dto.getClass().getMethod("set" + methodName, Long.class);
			method.invoke(dto, methodNameValue);
		} catch (Exception e) {
			// ignore
		}
	}

	private static void setParam(DTO dto, String methodName, String methodNameValue) {
		if (methodNameValue == null) {
			return;
		}

		try {
			if (Objects.nonNull(dto.getClass().getMethod("get" + methodName).invoke(dto))) {
				return;
			}

			Method method = dto.getClass().getMethod("set" + methodName, String.class);
			method.invoke(dto, methodNameValue);
		} catch (Exception e) {
			// ignore
		}
	}

	@Around("@annotation(org.springframework.web.bind.annotation.RequestMapping) " +
		"|| @annotation(org.springframework.web.bind.annotation.PatchMapping) " +
		"|| @annotation(org.springframework.web.bind.annotation.PostMapping) " +
		"|| @annotation(org.springframework.web.bind.annotation.DeleteMapping) " +
		"|| @annotation(org.springframework.web.bind.annotation.GetMapping) " +
		"|| @annotation(org.springframework.web.bind.annotation.PutMapping)")
	public Object handleRequestMapping(ProceedingJoinPoint joinPoint) throws Throwable {
		// 获取方法参数列表
		Object[] args = joinPoint.getArgs();

		// 获取方法的第一个参数对象
		if (args.length > 0 && args[0] instanceof DTO dto) {

			String roleSlug = UserSession.USER_THREAD_LOCAL.get().getRoleSlug();
			if (!"operation".equals(roleSlug)) {
				setParam(dto, "CreatedBy", UserSession.USER_THREAD_LOCAL.get().getCreatedBy());
				setParam(dto, "CreatedByName", UserSession.USER_THREAD_LOCAL.get().getCreatedByName());
			}
		}

		// 继续执行原方法
		return joinPoint.proceed(args);
	}
}
