package com.crm.rely.backend.aspect;

import com.crm.rely.backend.core.constant.PrefixEnum;
import com.crm.rely.backend.core.entity.base.BaseDateAndPageSearchEntity;
import com.crm.rely.backend.core.entity.base.BaseInterfaceEntity;
import com.crm.rely.backend.core.entity.base.DateBaseSearchEntity;
import com.crm.rely.backend.core.entity.custom.info.InfoEntity;
import com.crm.rely.backend.exception.ServiceException;
import com.crm.rely.backend.service.RedisService;
import com.crm.rely.backend.service.SysCountryService;
import com.crm.rely.backend.util.DateUtil;
import com.crm.rely.backend.util.GetIpAndMac;
import com.crm.rely.backend.util.HttpServletRequestUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;

/**
 * @author houn
 */
@Aspect
@Component
public class ServiceAop {

    @Autowired
    private RedisService redisService;

    @Autowired
    private ControllerAop controllerAop;

    @Autowired
    private SysCountryService sysCountryService;

    //    private ThreadLocal<InfoEntity> threadLocal = new ThreadLocal<>();
    @Pointcut("execution(* com.*.*.service.*.*.*(..))")
    public void allService() {
    }

    @Pointcut("execution(* com.*.*.service.*.*.*.*(..))")
    public void allPayService() {
    }


    @Before("allService()||allPayService()")
    public void allServiceBefore(JoinPoint joinPoint) throws Exception {
        Long userId;
        String ip;
        String returnStr;
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();

        if (requestAttributes != null) {
            HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
            userId = getUserId(request);
            ip = GetIpAndMac.getIp(request);
            if ("127.0.0.1".equals(ip)) {
                returnStr = "127.0.0.1-localhost";
            } else {
                returnStr = sysCountryService.getAdderByIp(ip);
            }
        } else {
            returnStr = "127.0.0.1-localhost";
            userId = -1L;
        }

        Date dateTime = new Date();
        for (Object arg : joinPoint.getArgs()) {
            setTimeInfo(arg);

            if (arg instanceof Iterable) {
                Iterable iterable = (Iterable) arg;
                iterable.forEach(value -> {
                    try {
                        setInfo(returnStr, userId, dateTime, value);
                    } catch (ServiceException e) {
                        e.printStackTrace();
                    }
                });
            } else {
                setInfo(returnStr, userId, dateTime, arg);
            }
        }
    }

    private void setInfo(String ip, Long userId, Date dateTime, Object arg) throws ServiceException {
        if (arg instanceof BaseInterfaceEntity) {
            ((BaseInterfaceEntity) arg).populateMetadata(ip, userId, "", dateTime);
        }
    }

    private Long getUserId(HttpServletRequest request) throws ServiceException {
        InfoEntity loginInfoEntity = getLoginInfo(request);

        Long userId = null;
        if (PrefixEnum.PREFIX_CUSTOM.equals(loginInfoEntity.getPrefix())) {
            if (loginInfoEntity.getCustomInfo() != null) {
                userId = loginInfoEntity.getCustomInfo().getId();
            }

        } else {
            if (loginInfoEntity.getIbInfo() != null) {
                userId = loginInfoEntity.getIbInfo().getId();
            }
        }
//        if (PrefixEnum.PREFIX_SYSTEM.equals(loginInfoEntity.getPrefix())
//                || PrefixEnum.PREFIX_SALE.equals(loginInfoEntity.getPrefix())
//                || PrefixEnum.PREFIX_USER.equals(loginInfoEntity.getPrefix())) {
//
//            if (loginInfoEntity.getIbInfo() != null) {
//                userId = loginInfoEntity.getIbInfo().getId();
//            }
//
//        } else {
//            if (loginInfoEntity.getCustomInfo() != null) {
//                userId = loginInfoEntity.getCustomInfo().getId();
//            }
//        }
        return userId;
    }

    private void setTimeInfo(Object arg) {
        if (arg instanceof BaseDateAndPageSearchEntity) {
            BaseDateAndPageSearchEntity dateAndPageSearchEntity = (BaseDateAndPageSearchEntity) arg;
            if (dateAndPageSearchEntity != null && dateAndPageSearchEntity.getTemporaryDate() == null) {
                if (dateAndPageSearchEntity.getEndDate() != null) {
                    dateAndPageSearchEntity.setTemporaryDate(dateAndPageSearchEntity.getEndDate());
                    if (dateAndPageSearchEntity.getEndDate() != null) {
                        Date endDate = DateUtil.operationDay(dateAndPageSearchEntity.getEndDate(), 1);
                        dateAndPageSearchEntity.setEndDate(DateUtil.parseDate(endDate));
                    }
                }
                if (dateAndPageSearchEntity.getStartDate() != null) {
                    dateAndPageSearchEntity.setStartDate(DateUtil.parseDate(dateAndPageSearchEntity.getStartDate()));
                }
            }
        } else if (arg instanceof DateBaseSearchEntity) {
            DateBaseSearchEntity dateBaseSearchEntity = (DateBaseSearchEntity) arg;
            if (dateBaseSearchEntity != null && dateBaseSearchEntity.getTemporaryDate() == null) {
                if (dateBaseSearchEntity.getEndDate() != null) {
                    dateBaseSearchEntity.setTemporaryDate(dateBaseSearchEntity.getEndDate());
                    if (dateBaseSearchEntity.getEndDate() != null) {
                        Date endDate = DateUtil.operationDay(dateBaseSearchEntity.getEndDate(), 1);
                        dateBaseSearchEntity.setEndDate(DateUtil.parseDate(endDate));
                    }
                }
                if (dateBaseSearchEntity.getStartDate() != null) {
                    dateBaseSearchEntity.setStartDate(DateUtil.parseDate(dateBaseSearchEntity.getStartDate()));
                }
            }
        }
    }

    /**
     * 获取登录信息
     *
     * @param request
     * @return
     * @throws ServiceException
     */
    private InfoEntity getLoginInfo(HttpServletRequest request) throws ServiceException {

        InfoEntity userInfoEntity = HttpServletRequestUtil.getLoginInfo(InfoEntity.class, request, redisService, true);

        if (userInfoEntity == null) {
            userInfoEntity = new InfoEntity();
        }

        return userInfoEntity;
    }
}
