package com.yeejoin.amos.boot.biz.common.aop;

import java.util.Arrays;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
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.beans.factory.annotation.Value;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.typroject.tyboot.core.foundation.utils.Bean;

import com.alibaba.fastjson.JSONObject;
import com.yeejoin.amos.boot.biz.common.bo.CompanyBo;
import com.yeejoin.amos.boot.biz.common.bo.DepartmentBo;
import com.yeejoin.amos.boot.biz.common.bo.ReginParams;
import com.yeejoin.amos.boot.biz.common.bo.RoleBo;
import com.yeejoin.amos.boot.biz.common.utils.RedisUtils;
import com.yeejoin.amos.component.feign.model.FeignClientResult;
import com.yeejoin.amos.feign.privilege.Privilege;
import com.yeejoin.amos.feign.privilege.model.AgencyUserModel;
import com.yeejoin.amos.feign.privilege.model.CompanyModel;
import com.yeejoin.amos.feign.privilege.model.DepartmentModel;
import com.yeejoin.amos.feign.privilege.model.RoleModel;

/**
 * controller层切面 用于用户数据缓存 供 sql自动填充使用
 *
 * @author Admin
 */
@Aspect
@Component
@Order(value = 0)
public class ControllerAop {
    /**
     * saveUserRedis设置过期时间
     */
    @Value("${redis.cache.failure.time}")
    private Long redisRegionTimeSecond;

    @Autowired
    private RedisUtils redisUtils;

    @Pointcut("execution(public * com.yeejoin.amos.boot.module.*.biz.controller..*(..)) || execution(public * com.yeejoin.amos.*.business.controller..*(..))")
    public void userCache() {

    }

    @Before("userCache()")
    public void doBefore(JoinPoint joinPoint) throws Throwable {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        String token = request.getHeader("token");
	    if (token == null) {
	    	 token = request.getHeader("X-Access-Token");
	     }
        String authProduct = request.getHeader("product");
	    if (authProduct == null) {
	    	authProduct = request.getParameter("product");
	    }
        String authAppKey = request.getHeader("appKey");
	    if (authAppKey == null) {
	    	authAppKey = request.getParameter("appKey");
	    }
        String authToken = buildKey(token);
        if (token != null) {
        	//验证token有效性，防止token失效
        	AgencyUserModel userModel;
        	try {
        		 FeignClientResult<AgencyUserModel> agencyUserModel = Privilege.agencyUserClient.getme();
        		 userModel = agencyUserModel.getResult();
        		 if (userModel == null) {
                     throw new Exception("无法获取用户信息");
                 }
			} catch (Exception e) {
				//删除失效token缓存
				redisUtils.del(authToken);
				throw new RuntimeException(e.getMessage());
			}
             // 不需要添加请求头的接口
            String[] url = new String[]{"/api/user/selectInfo", "/api/user/save/curCompany", "/jcs/command/lookHtmlText"};
            // 获取请求路径
            if (Arrays.asList(url).contains(request.getRequestURI())) {
                // 暂无需要
            } else {
                if (!redisUtils.hasKey(authToken)) {
                	  saveUserRedis(userModel, token);
                }
             }
        }
//        buildRequestCxt(authToken,authProduct,authAppKey);
        System.out.println(redisUtils.get(authToken));
    }

    public void saveUserRedis(AgencyUserModel user, String token) {
        CompanyBo company = new CompanyBo();
        DepartmentBo department = new DepartmentBo();
        RoleBo role = new RoleBo();
        CompanyModel companyM = user.getCompanys().get(0);
        Bean.copyExistPropertis(companyM, company);
        Map<Long, List<DepartmentModel>> mapDepartments = user.getCompanyDepartments();
        DepartmentModel departmentM = mapDepartments.get(companyM.getSequenceNbr()).get(0);
        Bean.copyExistPropertis(departmentM, department);
        Map<Long, List<RoleModel>> roles = user.getOrgRoles();
        Long sequenceNbr;
        if (departmentM == null) {
            sequenceNbr = null;
        } else {
            sequenceNbr = departmentM.getSequenceNbr();
        }
        RoleModel roleM = null;
        if (sequenceNbr == null) {
            roleM = roles.get(companyM.getSequenceNbr()).get(0);
        } else {
            roleM = roles.get(sequenceNbr).get(0);
        }
        Bean.copyExistPropertis(roleM, role);
        ReginParams reginParams = new ReginParams();
        reginParams.setCompany(company);
        reginParams.setRole(role);
        reginParams.setDepartment(department);
        reginParams.setUserModel(user);
        String authToken = buildKey(token);
        redisUtils.set(authToken, JSONObject.toJSONString(reginParams), redisRegionTimeSecond);
    }
    public String buildKey(String token) {
    	//由于用户id 不是接口携带参数，为了避免，公共字段填充时频繁访问平台，缓存用户信息时，
        //return "region_" + userId + "_" + token;
        return "region_"+ token;
    }

    @AfterReturning(returning = "ret", pointcut = "userCache()")
    public void doAfterReturning(Object ret) throws Throwable {
    	//统一redis管理
//        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
//        HttpServletRequest request = attributes.getRequest();
//        String token = request.getHeader("token");
//        if (token != null) {
//            GlobalCache.paramMap.remove(token);
//        }
    }
//	public void buildRequestCxt(String token,String product,String appKey){
//	RequestContext.setToken(token);
//	RequestContext.setProduct(product);
//	RequestContext.setAppKey(appKey);
//}
}
