package cn.estsh.i3plus.ext.mes.pcn.apiservice.aspect;

import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords;
import cn.estsh.i3plus.pojo.base.bean.BaseBean;
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
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.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.context.annotation.Configuration;

import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;

/**
 * @Description : 同步状态和时间更新
 * @Reference :
 * @Author : zxw
 * @CreateDate :
 * @Modify:
 **/
@ConditionalOnExpression("'${pcn.aspect.repository:true}' == 'true'")
@Aspect
@Configuration
@Slf4j
public class PcnRepositoryAspect {

    @Before("controllerPointcut()")
    public void before(JoinPoint joinPoint){
        String methodName = joinPoint.getSignature().getName();
        if (methodName.equals("save") || methodName.equals("update")) {
            Object[] args = joinPoint.getArgs();
            for (Object arg : args) {
                if (arg.getClass().isArray()) {
                    int len = Array.getLength(arg);
                    for (int i = 0; i < len; ++i) {
                        Object item = Array.get(arg, i);
                        if (BaseBean.class.isAssignableFrom(item.getClass())) {
                            updateBeanSync((BaseBean)item);
                        }
                    }
                } else if (BaseBean.class.isAssignableFrom(arg.getClass())) {
                    updateBeanSync((BaseBean)arg);
                }
            }
        } else if (methodName.equals("saveAll")) {
            Object[] args = joinPoint.getArgs();
            if (args.length > 0) {
                Object arg = args[0];
                if (arg instanceof List) {
                    List<Object> items = (List<Object>) arg;
                    for (Object item : items) {
                        if (BaseBean.class.isAssignableFrom(item.getClass())) {
                            updateBeanSync((BaseBean)item);
                        }
                    }
                } else if (BaseBean.class.isAssignableFrom(arg.getClass())) {
                    updateBeanSync((BaseBean)arg);
                }
            }
        }
    }

    @Pointcut("execution(* cn.estsh.*..*.repository.*..*(..))")
    public void controllerPointcut() {}

    @After("controllerPointcut()")
    public void after(JoinPoint joinPoint) {
        String methodName = joinPoint.getSignature().getName();
        if (methodName.equals("updateByProperties")) {
            try {
                Object[] args = joinPoint.getArgs();
                Method method = ((MethodSignature)joinPoint.getSignature()).getMethod();
                if (args.length == 4) {
                    if (args[2].getClass().isArray()) {
                        method.invoke(joinPoint.getTarget(), args[0], args[1], new String[]{ "systemSyncStatus"},
                                new Object[]{CommonEnumUtil.FALSE});
                    } else {
                        method.invoke(joinPoint.getTarget(), args[0], args[1], "systemSyncStatus", CommonEnumUtil.FALSE);
                    }
                } else if (args.length == 3) {
                    if (args[0].getClass().isArray()) {
                        method.invoke(joinPoint.getTarget(), new String[]{ "systemSyncStatus"},
                                new Object[]{ CommonEnumUtil.FALSE}, args[2]);
                    } else {
                        method.invoke(joinPoint.getTarget(), "systemSyncStatus", CommonEnumUtil.FALSE, args[2]);
                    }
                }
            } catch (IllegalAccessException | InvocationTargetException e) {
                throw new RuntimeException(e);
            }
        } else if (methodName.equals("updateByHqlWhere")) {
            Object[] args = joinPoint.getArgs();
            try {
                if (args.length == 3) {
                    Method method = ((MethodSignature)joinPoint.getSignature()).getMethod();
                    if (args[1].getClass().isArray()) {
                        method.invoke(joinPoint.getTarget(), args[0], new String[]{"systemSyncStatus"},
                                new Object[]{ CommonEnumUtil.FALSE});
                    } else {
                       // method.invoke(joinPoint.getTarget(), TimeTool.getNowTime(true), args[2]);
                        method.invoke(joinPoint.getTarget(), "systemSyncStatus", CommonEnumUtil.FALSE, args[2]);
                    }
                }
            } catch (IllegalAccessException | InvocationTargetException e) {
                throw new RuntimeException(e);
            }
        }
    }

    private void updateBeanSync(BaseBean bean) {
        bean.setSystemSyncStatus(CommonEnumUtil.FALSE);
        bean.setSystemSyncDatetime(MesPcnExtConstWords.EMPTY);
    }
}
