package com.ruoyi.framework.aspectj;

import com.ruoyi.framework.annotation.DataUpdateCheck;
import com.ruoyi.project.common.dto.ExclusiveDto;
import com.ruoyi.project.common.service.IExclusiveService;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author :tiantf
 * @date : 2023/11/8
 */
@Aspect
@Component
public class DataUpdateCheckAspect {
    @Resource
    private IExclusiveService exclusiveService;

    private static final Logger log = LoggerFactory.getLogger(DataUpdateCheckAspect.class);

    @Before("dataUpdateCheckPointCut()")
    public void beforeDataUpdateCheck(JoinPoint joinPoint) {
        Signature signature = joinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        Method method = methodSignature.getMethod();
        if (method != null) {
            log.info("进入方法");
            DataUpdateCheck dataUpdateCheck = method.getAnnotation(DataUpdateCheck.class);
            if (dataUpdateCheck != null) {
                log.info("主键: " + dataUpdateCheck.key() + ", 表名: " + dataUpdateCheck.tableName());
                // 获取切点方法传入的参数 有获取 updateDt 时间属性
                Object[] args = joinPoint.getArgs();
                if (args.length > 0) {
                    Object firstArg = null;
                    if("".equals(dataUpdateCheck.fieldName())){
                        firstArg =   args[0];
                    }else{
                        try{
                            Method firstField = args[0].getClass().getMethod("get" + toCamelCase(dataUpdateCheck.fieldName()));
                            firstArg = firstField.invoke(args[0]);
                        }catch (Exception e){
                            log.info("获取参数" + dataUpdateCheck.fieldName() + "异常");
                        }
                    }

                    if (firstArg instanceof List) {
                        // firstArg 是list
                        List<?> list = (List<?>) firstArg;
                        List<ExclusiveDto> exclusiveDtos = new ArrayList<>();
                        // 在这里处理数组
                        for (Object obj : list) {
                            ExclusiveDto exclusiveDto = new ExclusiveDto();
                            Class<?> parameterType = obj.getClass();
                            Date updateDt = null;
                            Long idVal  = null;
                            // 处理数组中的每个元素
                            try {
                                // 使用反射获取参数对象的 updateDt 属性值
                                Method getUpdateDtMethod = parameterType.getMethod("getUpdateTime");
                                updateDt = (Date) getUpdateDtMethod.invoke(obj);
                                exclusiveDto.setUpdateTime(updateDt);
                                // 获取id值
                                Method getIdMethod = parameterType.getMethod("get"+toCamelCase(dataUpdateCheck.key()));
                                idVal =  (Long)getIdMethod.invoke(obj);
                                exclusiveDto.setId(idVal);
                                exclusiveDtos.add(exclusiveDto);
                            } catch (Exception e) {
                                log.error("获取参数的 updateDt 属性值时发生异常: " + e.getMessage());
                            }
                        }
                        exclusiveService.exclusives(new ExclusiveDto(dataUpdateCheck.key(),dataUpdateCheck.tableName()),exclusiveDtos);
                    }
                    else {
                        // 获取参数的类型
                        Class<?> parameterType = firstArg.getClass();
                        Date updateDt = null;
                        Long idVal  = null;
                        try {
                            // 使用反射获取参数对象的 updateDt 属性值
                            Method getUpdateDtMethod = parameterType.getMethod("getUpdateTime");
                            updateDt = (Date) getUpdateDtMethod.invoke(firstArg);
                            // 获取id值
                            Method getIdMethod = parameterType.getMethod("get"+toCamelCase(dataUpdateCheck.key()));
                            idVal =  (Long)getIdMethod.invoke(firstArg);
                        } catch (Exception e) {
                            log.error("获取参数的 updateDt 属性值时发生异常: " + e.getMessage());
                        }

                        exclusiveService.exclusive(new ExclusiveDto(idVal, updateDt,dataUpdateCheck.key(),dataUpdateCheck.tableName()));

                    }
                }
            }
        }
    }

    @Pointcut("@annotation(com.ruoyi.framework.annotation.DataUpdateCheck)")
    public void dataUpdateCheckPointCut() {
    }

    public static String toCamelCase(String input) {
        StringBuilder result = new StringBuilder();

        // 将字符串按下划线分割为单词
        String[] words = input.split("_");

        for (String word : words) {
            // 将单词的第一个字符变为小写，其余字符保持不变
            String firstLetter = word.substring(0, 1).toUpperCase();
            String restOfWord = word.substring(1);

            result.append(firstLetter).append(restOfWord);
        }

        return result.toString();
    }



}
