package com.yeejoin.amos.patrol.core.framework;


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

import javax.servlet.http.HttpServletRequest;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.typroject.tyboot.core.foundation.context.RequestContext;

import com.alibaba.fastjson.JSON;
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.component.feign.config.InnerInvokException;
import com.yeejoin.amos.component.feign.config.TokenOperation;
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;
import com.yeejoin.amos.patrol.exception.PermissionException;
import com.yeejoin.amos.patrol.feign.RemoteSecurityService;

@Aspect
@Component
@ResponseBody
public class PermissionAspect {
	private static final Logger logger = LoggerFactory.getLogger(PermissionAspect.class);

	@Autowired
	private RedisTemplate<String, String> redisTemplate;

	@Autowired
	private RemoteSecurityService remoteSecurityService;

	// 前置通知，在方法执行之前
	@Before(value = "@annotation(Permission)")
	public void PermissionCheck(JoinPoint joinPoint) throws PermissionException {
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
				.getRequestAttributes()).getRequest();

		logger.info("======开始权限校验======");
		// 用户token
		String token = (String) request.getHeader("token");
		token = ObjectUtils.isEmpty(token) ? (String) request.getHeader("X-Access-Token") : token;
		String product = (String) request.getHeader("product");
		String appKey = (String) request.getHeader("appKey");
		logger.info("用户token：" + token);
		RequestContext.setToken(token);
		RequestContext.setProduct(product);
		RequestContext.setAppKey(appKey);
		if (!TokenOperation.refresh(token)) {
			throw new PermissionException("登录信息失效，请重新登录");
		}

		if (joinPoint.getSignature().getName().equals("saveCurCompany")) {
			return;
		}
		FeignClientResult feignClientResult;
		AgencyUserModel userModel=null;
		try {
			feignClientResult = Privilege.agencyUserClient.getme();
			userModel = (AgencyUserModel) feignClientResult.getResult();

		} catch (InnerInvokException e) {
			e.printStackTrace();
		}
		String userId = null;
		ReginParams regionParam = new ReginParams();
		if(userModel != null){
			userId = userModel.getUserId();
			Map<Long, List<RoleModel>> orgRoles = userModel.getOrgRoles();
			List<RoleModel> roleModels = null;
			if(!ObjectUtils.isEmpty(orgRoles)) {
				for (Map.Entry<Long, List<RoleModel>> entry : orgRoles.entrySet()) {
					roleModels = entry.getValue();
					break;
				}
			}
			ReginParams reginParams = JSON.parseObject(redisTemplate.opsForValue().get(buildKey(userModel.getUserId(), token)), ReginParams.class);
			if(reginParams == null && userModel.getCompanys().size() > 0){
				CompanyModel companyModel = userModel.getCompanys().get(0);

				List<DepartmentModel> deptList = remoteSecurityService.getDepartmentTreeByCompanyId(token, product, appKey, companyModel.getSequenceNbr().toString());
				if(deptList.size() > 0){
					CompanyBo companyBo = convertCompanyModelToBo(companyModel);
					DepartmentBo departmentBo = convertDepartmentModelToBo(deptList.get(0));
					regionParam.setCompany(companyBo);
					regionParam.setDepartment(departmentBo);
					if(!ObjectUtils.isEmpty(roleModels)){
						regionParam.setRole(convertRoleModelToBo(roleModels.get(0)));
					}
				}else{
					if(!ObjectUtils.isEmpty(userModel.getOrgRoles()) && !ObjectUtils.isEmpty(companyModel) && userModel.getOrgRoles().get(companyModel.getSequenceNbr()).size() > 0){
						RoleModel role = userModel.getOrgRoles().get(companyModel.getSequenceNbr()).get(0);
						RoleBo  roleBo = new RoleBo();
						BeanUtils.copyProperties(role, roleBo);
						regionParam.setRole(roleBo);
					}
				}
				redisTemplate.opsForValue().set(buildKey(userId, token), JSONObject.toJSONString(regionParam));
			}
		}
	}


	private DepartmentBo convertDepartmentModelToBo(DepartmentModel departmentModel){
		DepartmentBo departmentBo = new DepartmentBo();
		if(departmentModel != null) {
			departmentBo.setCompanySeq(departmentModel.getCompanySeq());
			departmentBo.setDepartmentDesc(departmentModel.getDepartmentDesc());
			departmentBo.setDepartmentName(departmentModel.getDepartmentName());
			departmentBo.setLevel(departmentModel.getLevel());
			departmentBo.setOrgCode(departmentModel.getOrgCode());
			departmentBo.setParentId(departmentModel.getParentId());
			departmentBo.setDeptOrgCode(departmentModel.getDeptOrgCode().toString());
			departmentBo.setSequenceNbr(departmentModel.getSequenceNbr());
		}
		return departmentBo;
	}

	/**
	 * 	Model 转 Bo
	 */
	private CompanyBo convertCompanyModelToBo(CompanyModel companyModel){

		CompanyBo companyBo = new CompanyBo();
		if(companyModel != null) {
			companyBo.setAddress(companyModel.getAddress());
			companyBo.setCompanyName(companyModel.getCompanyName());
			companyBo.setCompanyOrgCode(companyModel.getCompanyOrgCode());
			companyBo.setEmail(companyModel.getEmail());
			companyBo.setLandlinePhone(companyModel.getLandlinePhone());
			companyBo.setLongitude(companyModel.getLongitude());
			companyBo.setLatitude(companyModel.getLatitude());
			companyBo.setLevel(companyModel.getLevel());
			companyBo.setOrgCode(companyModel.getOrgCode());
			companyBo.setSequenceNbr(companyModel.getSequenceNbr());
			companyBo.setParentId(companyModel.getParentId());
		}
		return companyBo;
	}

	private RoleBo convertRoleModelToBo(RoleModel roleModel) {
		RoleBo roleBo = new RoleBo();
		if(roleModel != null){
			roleBo.setRoleName(roleModel.getRoleName());
			roleBo.setRoleType(roleModel.getRoleType());
			roleBo.setSequenceNbr(roleModel.getSequenceNbr());
		}
		return roleBo;
	}

	//redi缓存选择的用户信息
	private String buildKey(String userId, String token) {
		return "region_" + userId + "_" + token;

	}
}
