package com.sckw.excel.translate.wrapper;


import com.sckw.core.web.response.result.Result;
import com.sckw.excel.translate.Translator;
import com.sckw.excel.translate.annotation.Translate;
import com.sckw.excel.translate.enums.Source;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 *
 * translate aop
 *
 *
 * @author lfdc
 * @version v1
 * @create 2020-11-28 15:48:35
 * @copyright
 */
@Component
@Aspect
@Slf4j
public class TranslateWrapper implements Ordered {

    public TranslateWrapper() {
        log.info("The translator is loading complete. source -> {}", Arrays.toString(Source.values()));
    }

    @Pointcut("@annotation(com.sckw.excel.translate.annotation.Translates) || @annotation(com.sckw.excel.translate.annotation.Translate)")
    public void annotationWrapper(){}

    @Around(value = "annotationWrapper()")
    @SuppressWarnings("unchecked")
    public Object annotationHandler(ProceedingJoinPoint joinPoint) throws Throwable {

        Object obj = joinPoint.proceed();
        if(obj == null) {
            log.warn("translate failed, method return value is null");
            throw new IllegalArgumentException("method return value is null");
        }

        Result result = (Result) obj;
        if (result.nonSuccess() || result.getData() == null || result.getData().getBody() == null) {
            return obj;
        }

        Map<Source, Map<Integer, Object>> sources = Translator.getSources();

        Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
        List<Translate> translates = Translator.getTranslates(method);

        Object body = result.getData().getBody();
        if(body instanceof List) {
            Translator.translate(translates, (List) body, sources);
        } else if(body instanceof Map) {
            Map<String, Object> results = (Map<String, Object>) body;
            results.values().forEach(value -> {
                if(value instanceof List) {
                    Translator.translate(translates, (List) value, sources);
                } else {
                    Translator.translate(translates, value, sources);
                }
            });
        } else {
            Translator.translate(translates, body, sources);
        }

        return obj;
    }

    @Override
    public int getOrder() {
        return Ordered.LOWEST_PRECEDENCE;
    }
}