package org.springblade.common.aop;

import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springblade.common.aop.core.TenantAop;
import org.springblade.common.constant.Agent;
import org.springblade.common.constant.Salesman;
import org.springblade.core.mp.base.BaseEntity;
import org.springblade.core.secure.BladeUser;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tenant.BladeTenantHolder;
import org.springblade.core.tool.api.R;
import org.springblade.gateway.web_gateway.service.ICensusService;
import org.springblade.ldt.agent.entity.AgentBills;
import org.springblade.ldt.agent.entity.AgentRecord;
import org.springblade.ldt.shop.entity.Shop;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * @Author: Silent
 * @Description
 * @Date: Created in 16:47 2021/10/13
 * @Modified By:
 */
@Component
@Aspect
public class TenantIgnoreAop{
	@Autowired
	private ICensusService censusService;

	/**
	 * 环绕方法
	 * @param pjp
	 * @param tenantAop
	 */
	@Around("@annotation(tenantAop)")
	public Object around(ProceedingJoinPoint pjp, TenantAop tenantAop) throws Throwable {
		BladeUser bladeUser = AuthUtil.getUser();
		if(ObjectUtils.isNotEmpty(bladeUser)){
			//判断是否有业务员注解 && 判断角色是否是业务员
			if(StringUtils.equals(tenantAop.salesman(),Salesman.roleName) && Salesman.isSalesman(bladeUser)){
				//业务员处理逻辑
				return invokeTenantIgnoreMethodBySalesman(pjp,bladeUser);
			}else if(StringUtils.equals(tenantAop.agent(), Agent.roleName) && Agent.isAgent(bladeUser)){ //判断是否是代理注解 && 判断角色是否是代理
				//代理处理逻辑
				return invokeTenantIgnoreMethodByAgent(pjp,bladeUser);
			}
		}
		return pjp.proceed();
	}

	/**
	 * 代理业务员方法(租户忽略)
	 * @param pjp
	 * @param bladeUser
	 * @return
	 * @throws Throwable
	 */
	public Object invokeTenantIgnoreMethodBySalesman(ProceedingJoinPoint pjp,BladeUser bladeUser) throws Throwable {
		try{
			BladeTenantHolder.setIgnore(Boolean.TRUE);
			for (Object arg : pjp.getArgs()) {
				if(arg instanceof BaseEntity){
					((BaseEntity) arg).setCreateUser(bladeUser.getUserId());
				}
			}
			return pjp.proceed();
		}finally {
			BladeTenantHolder.clear();
		}
	}

	/**
	 * 代理‘代理人’方法(租户忽略)
	 * @param pjp
	 * @param bladeUser
	 * @return
	 * @throws Throwable
	 */
	public Object invokeTenantIgnoreMethodByAgent(ProceedingJoinPoint pjp,BladeUser bladeUser) throws Throwable {
		try{
			Long agentUserId = censusService.getAgentUserId(bladeUser);
			if(ObjectUtils.isNotEmpty(agentUserId)){
				BladeTenantHolder.setIgnore(Boolean.TRUE);
				for (Object arg : pjp.getArgs()) {
					if(arg instanceof AgentRecord){
						((AgentRecord)arg).setAccountId(agentUserId);
					}else if(arg instanceof AgentBills){
						((AgentBills)arg).setAgenter(agentUserId);
					}else if(arg instanceof Shop){
						((Shop)arg).setAgenter(agentUserId);
					}
				}
				return pjp.proceed();
			}else{
				return R.fail("该账号未绑定代理,不允许使用");
			}
		}finally {
			BladeTenantHolder.clear();
		}
	}
}
