package com.yeejoin.precontrol.common.utils;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yeejoin.amos.component.feign.config.InnerInvokException;
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.DepartmentModel;
import com.yeejoin.amos.feign.privilege.model.IdPasswordAuthModel;
import com.yeejoin.amos.feign.privilege.model.RoleModel;
import com.yeejoin.precontrol.common.entity.Company;
import com.yeejoin.precontrol.common.entity.Person;
import com.yeejoin.precontrol.common.entity.PersonAscription;
import com.yeejoin.precontrol.common.exception.BaseException;
import com.yeejoin.precontrol.common.service.ICompanyService;
import com.yeejoin.precontrol.common.service.IPersonAscriptionService;
import com.yeejoin.precontrol.common.service.IPersonService;
import com.yeejoin.precontrol.common.start.StartPlatformTokenService;
import com.yeejoin.precontrol.common.vo.ReginParams;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.typroject.tyboot.component.cache.ConcurrentUtil;
import org.typroject.tyboot.core.foundation.context.RequestContext;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Callable;

/**
 * @Description: 平台操作类
 * @Author: duanwei
 * @Date: 2020/11/9
 */
@Component
@Slf4j
public class PlatformUtils {

	@Autowired
	public HttpServletRequest request;
	@Autowired
	private IPersonService iPersonService;
	@Autowired
	private IPersonAscriptionService iPersonAscriptionService;
	@Autowired
	private ICompanyService iCompanyService;
	@Autowired
	StartPlatformTokenService startPlatformTokenService;
	@Autowired
	RedisUtil redisUtil;
	@Value("${admin.product}")
	String product;

	@Value("${admin.appkey}")
	String appkey;

	@Value("${admin.user}")
	String user;

	@Value("${admin.password}")
	String password;

	@Value("${amos.secret.key}")
	String secretKey;
	
	@Value("${jxdj.id}")
	Long jxdjId;

	@Value("${amos.not-auto-orgcode}")
	Boolean noAutoOrgCode;

	/**
	 * 获取是否自动填充orgcode
	 * 
	 * @return
	 */
	public boolean isAutoSetOrgCode() {
		return !noAutoOrgCode;
	}

	/**
	 * 根据token获取组织机构id
	 *
	 * @return
	 */
	public String getOrgCode() {
		AgencyUserModel userInfo = getUserInfo();
		Long userIdSequenceNbr = userInfo.getSequenceNbr();
		if (userIdSequenceNbr != null) {
			Person person = iPersonService.getById(userIdSequenceNbr);
			if (person != null) {
				return person.getOrgCode();
			}
		}
		return null;
	}

	public String getToken() {
		String authToken = request.getHeader("token");
		if (authToken == null) {
			authToken = request.getHeader("X-Access-Token");
		}
		return authToken;
	}

	public String getProduct() {
		String authToken = request.getHeader("product");
		if (authToken == null) {
			authToken = request.getParameter("product");
		}
		return authToken;
	}

	public String getAppKey() {
		String authToken = request.getHeader("appKey");
		if (authToken == null) {
			authToken = request.getParameter("appKey");
		}
		return authToken;
	}

	public ReginParams getReginInfo() {
		String token = getToken();
		log.info("token-------------------->:" + getToken());
		if (StringUtils.isEmpty(token)) {
			throw new BaseException("token为空!");
		}
		AgencyUserModel userInfo = getUserInfo();
		if (userInfo == null) {
			log.info("请求平台用户为空");
			return null;
		}
		Long userId = userInfo.getSequenceNbr();
		if (redisUtil.hasKey(userId + "_" + getToken())) {
			ReginParams reginParams = (ReginParams) redisUtil.get(userId + "_" + getToken());
			log.info("user------------------>获取缓存用户信息成功");
			return reginParams;
		}
		ReginParams reginParams = new ReginParams();
		Person curPerson = iPersonService
				.getOne(new QueryWrapper<Person>().lambda().eq(Person::getId, userInfo.getSequenceNbr()));
		if (curPerson == null) {
			log.info("当前用户未绑定平台,请绑定平台");
			return null;
		}
		reginParams.setPerson(curPerson);
		// 获取用户角色
		Map<Long, List<RoleModel>> orgRoles = userInfo.getOrgRoles();
		if (orgRoles != null) {
			Set<Long> keySet = orgRoles.keySet();
			if (!keySet.isEmpty()) {
				List<RoleModel> list = orgRoles.get(keySet.iterator().next());
				RoleModel roleModel = list.get(0);
				reginParams.setRole(roleModel);
			}
		}
		// 查询用户所属信息
		PersonAscription ascription = iPersonAscriptionService.getOne(
				new QueryWrapper<PersonAscription>().lambda().eq(PersonAscription::getPersonId, curPerson.getId()));
		if (ascription != null) {
			Company company = iCompanyService.getById(ascription.getCompanyId());
			reginParams.setCompany(company);
		}
		redisUtil.set(userId + "_" + getToken(), reginParams, 60);
		return reginParams;
	}

	/**
	 * <pre>
	 * 判断当前用户是否为分包商角色：true:分包商/false:江西电建
	 * </pre>
	 *
	 * @return
	 */
	public boolean isFbsRole(ReginParams reginParams) {
		if (reginParams != null) {
			if (reginParams.getRole() != null) {
				String roleType = reginParams.getRole().getRoleType();
				if (roleType != null && "fbs".equals(roleType)) {
					return true;
				}
			}
		}
		return false;
	}

	/**
	 * 当前登录用户信息
	 */
	public AgencyUserModel getUserInfo() {
		AgencyUserModel agencyUserModel = new AgencyUserModel();
		String token = getToken();
		if (token != null) {
			String product = getProduct();
			String appKey = getAppKey();
			RequestContext.setToken(token);
			RequestContext.setProduct(product);
			RequestContext.setAppKey(appKey);
			FeignClientResult<AgencyUserModel> feignClientResult;
			try {
				feignClientResult = Privilege.agencyUserClient.getme();
				try {
					agencyUserModel = feignClientResult.getResult();
					if (agencyUserModel != null) {
						log.info("请求平台用户数据,数据result返回:{}", agencyUserModel.toString());
					}
				} catch (Exception e) {
					log.info("请求平台用户数据,对象转换错误 AgencyUserModel-result error:{}", e.toString());
					throw new BaseException("请求平台用户数据,数据转换错误！");
				}
			} catch (Exception e) {
//				if (e instanceof InnerInvokException) {
//					int httpStatus = ((InnerInvokException) e).getHttpStatus();
//					throw new BaseException(httpStatus, "请求平台用户信息接口错误:" + e.getMessage());
//				}
				throw new BaseException(1, "请求平台用户信息接口失败,token:" + token);
			}
		} else {
			log.error("token为空!!!!!!!!!!!!!!!!!!!!!!!!!!!");
		}
		return agencyUserModel;
	}

	public String getUserId() {
		String userId = null;
		if (getUserInfo() != null) {
			userId = getUserInfo().getUserId();
		}
		return userId;
	}

	public Long getCompanyId(ReginParams reginParams) {
		if (reginParams == null) {
			return null;
		}
		if (reginParams.getCompany() != null) {
			return reginParams.getCompany().getId();
		}
		return null;
	}

	/**
	 * 获取平台绑定的用户信息
	 *
	 * @return
	 */
	public Person getPerson() {
		ReginParams reginInfo = getReginInfo();
		Person person;
		if (reginInfo != null) {
			person = reginInfo.getPerson();
		} else {
			throw new BaseException("当前用户未绑定平台,请绑定平台");
		}
		return person;
	}

	public DepartmentModel getDepartment(Long departmentId) {
		String token = getToken();
		String product = getProduct();
		String appKey = getAppKey();
		RequestContext.setToken(token);
		RequestContext.setProduct(product);
		RequestContext.setAppKey(appKey);
		FeignClientResult<DepartmentModel> departmentModel = Privilege.departmentClient.seleteOne(departmentId);
		return departmentModel.getResult();
	}

	/**
	 * 同步锁获取用户信息
	 *
	 * @return
	 */
	public AgencyUserModel getSyncPlatformUser(String userId) {
		Callable<AgencyUserModel> callable = new Callable<AgencyUserModel>() {
			@Override
			public AgencyUserModel call() throws Exception {
				RequestContext.setProduct(product);
				RequestContext.setAppKey(appkey);
				IdPasswordAuthModel authModel = new IdPasswordAuthModel();
				authModel.setLoginId(user);
				authModel.setPassword(DesUtil.encode(password, secretKey));
				System.out.println("user:" + user);
				System.out.println("secretKey:" + secretKey);
				FeignClientResult<Map<String, String>> authResult = Privilege.authClient.idpassword(authModel);
				String token = authResult.getResult().get("token");
				System.out.println("token:" + token);
				RequestContext.setToken(token);
				FeignClientResult<AgencyUserModel> userResult = Privilege.agencyUserClient.queryByUserId(userId);
				return userResult.getResult();
			}
		};
		return ConcurrentUtil.runWithAsynLock("SERVER_LOGIN", callable);
	}

	/**
	 * 获取操作人所属项目部的id
	 * 
	 * @param userId
	 * @return
	 */
	public String getOrgCode(String userId) {
		Callable<String> callable = new Callable<String>() {
			@Override
			public String call() throws Exception {
				AgencyUserModel operUserModel = getSyncPlatformUser(userId);
				Map<Long, List<DepartmentModel>> companyDepartments = operUserModel.getCompanyDepartments();
				Long companyId = (operUserModel.getCompanys() != null && operUserModel.getCompanys().get(0) != null)
						? operUserModel.getCompanys().get(0).getSequenceNbr()
						: null;
				String orgCode = null;
				List<DepartmentModel> departmentList = null;
				if (null != companyDepartments) {
					departmentList = operUserModel.getCompanyDepartments().get(companyId);
					if (departmentList != null && departmentList.get(0) != null) {
						if (!isBelongDept(departmentList.get(0).getSequenceNbr(), companyId, "public")) {
							boolean hasChild = hasChild(departmentList.get(0).getSequenceNbr());
							orgCode = hasChild ? departmentList.get(0).getOrgCode()
									: departmentList.get(0).getOrgCode().substring(0,
											departmentList.get(0).getOrgCode().lastIndexOf("*"));
						}
					}
				}
				return orgCode;
			}
		};
		return ConcurrentUtil.runWithAsynLock("GET_ORGCODE", callable);
	}

	/**
	 * 查询是否属于指定类型部门
	 * 
	 * @param deptId
	 * @param companyId
	 * @param key
	 * @return
	 */
	public boolean isBelongDept(Long deptId, Long companyId, String key) {
		if (deptId == null) {
			return true;
		}
		DepartmentModel dept = Privilege.departmentClient.seleteOne(deptId).getResult();
		if (dept != null && key.equals(dept.getLevel())) {
			return true;
		}
		List<DepartmentModel> list = (List<DepartmentModel>) Privilege.departmentClient.treeByUser(deptId, companyId)
				.getResult();
		if (!StringUtil.isEmpty(list)) {
			for (DepartmentModel upDept : list) {
				if (dept != null && dept.getParentId().equals(upDept.getSequenceNbr())
						&& key.equals(upDept.getLevel())) {
					return true;
				}
			}
		}
		return false;
	}

	/**
	 * 是否是最终节点
	 * 
	 * @param deptId
	 * @param companyId
	 * @param key
	 * @return
	 */
	public boolean hasChild(Long deptId) {
		return Privilege.departmentClient.querySubAgencyTree(deptId).getResult() != null
				&& !Privilege.departmentClient.querySubAgencyTree(deptId).getResult().isEmpty();
	}

	/**
	 * 根据组合的orgCode查询项目部名称
	 * 
	 * @param orgCode
	 * @return
	 */
	public String getDepartmentNameByOrgCode(String orgCode) {
		StringBuffer departmentName = new StringBuffer();
		String token = getToken();
		String product = getProduct();
		RequestContext.setToken(token);
		String appKey = getAppKey();
		RequestContext.setProduct(product);
		RequestContext.setAppKey(appKey);
		if (StringUtils.isNotBlank(orgCode)) {
			DepartmentModel children = Privilege.departmentClient.queryByOrgcode(orgCode).getResult();
			if (null != children) {
				departmentName.append(children.getDepartmentName());
			}
			return departmentName.toString();
		} else {
			return "";
		}
	}

	/**
	 * 设置平台接口调用权限
	 */
	public void setPlatFormAccess() {
//		RequestContext.setProduct("WX");
//		RequestContext.setAppKey(appkey);
//		RequestContext.setToken("token");
//		IdPasswordAuthModel authModel = new IdPasswordAuthModel();
//		authModel.setLoginId(user);
//		authModel.setPassword(DesUtil.encode(password, secretKey));
//		FeignClientResult<Map<String, String>> authResult = Privilege.authClient.idpassword(authModel);
//		String token = authResult.getResult().get("token");
//		RequestContext.setToken(token);

		RequestContext.setProduct(product);
		RequestContext.setAppKey(appkey);
		String token = (String) redisUtil.get("platform_token");
		RequestContext.setToken(token);
		System.out.println("old token:"+RequestContext.getToken());
		try {
			Privilege.companyClient.seleteOne(jxdjId);
		} catch (Exception e) {
			System.out.println("platform token is invalid!!!!!");
			startPlatformTokenService.getToken();
		}
		token = (String) redisUtil.get("platform_token");
		RequestContext.setToken(token);
		System.out.println("new token:"+RequestContext.getToken());
	}
}
