package com.artfess.uc.util;

import com.artfess.base.feign.UCFeignService;
import com.artfess.base.util.AppUtil;
import com.artfess.base.util.BeanUtils;
import com.artfess.base.util.JsonUtil;
import com.artfess.base.util.StringUtil;
import com.artfess.uc.api.context.ICurrentContext;
import com.artfess.uc.api.model.IGroup;
import com.artfess.uc.api.model.IUser;
import com.artfess.uc.api.service.IUserService;
import com.artfess.uc.manager.UserManager;
import com.artfess.uc.model.Org;
import com.artfess.uc.model.User;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.collect.Maps;
import org.springframework.context.annotation.Primary;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;

/**
 * 获取上下文数据对象的工具类。
 * <pre>
 *
 * 构建组：x5-org-core
 * 作者：ray
 * 邮箱:zhangyg@jee-soft.cn
 * 日期:2013-12-20-上午9:38:46
 * 版权：广州宏天软件有限公司版权所有
 * </pre>
 */
@Service
@Primary
public class ContextUtil  {

	private static ContextUtil contextUtil;

	private ICurrentContext currentContext;


    public void setCurrentContext(ICurrentContext _currentContext){
		contextUtil=this;
		contextUtil.currentContext=_currentContext;
	}

	/**
	 * 获取当前执行人
	 * @return
	 * User
	 * @exception
	 * @since  1.0.0
	 */
	public static User getCurrentUser(){
		try {
			Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
			Assert.notNull(authentication, "当前登录用户不能为空");
			Object principal = authentication.getPrincipal();
			if(principal instanceof User) {
				return (User)principal;
			}else if(principal instanceof UserDetails) {
				UserDetails ud = (UserDetails)principal;
				User user = JsonUtil.toBean(JsonUtil.toJson(ud), User.class);
				return user;
			}
			return null;
		} catch (Exception e) {
			throw new RuntimeException(e.getMessage());
		}
	}

	public static String getCurrentUserId(){
		User user = getCurrentUser();
		return BeanUtils.isEmpty(user)?null:user.getUserId();
	}

	public static List<String> getCurrentAndChildOrgIds(){
		UCFeignService service = AppUtil.getBean(UCFeignService.class);
		String userId = getCurrentUserId();
		if(StringUtil.isNotEmpty(userId)) {
			ObjectNode orgObj = service.getMainGroup(userId);
			if (BeanUtils.isNotEmpty(orgObj)) {
				String orgKind = orgObj.get("orgKind").asText();
				if(orgKind.equals("ogn")){
					Map<String, String> map = Maps.newHashMap();
					map.put("ids", orgObj.get("id").asText());
					Map<String, Set<String>> childrenIds = service.getChildrenIds(map);
					if(!CollectionUtils.isEmpty(childrenIds)){
						Set<String> ids = childrenIds.get("ids");
						List<String> orgIds = new ArrayList<>(ids);
						return orgIds;
					}
					return new ArrayList<>();
				}
			}
		}
		return new ArrayList<>();
	}

	public static String getCurrentUserAccount(){
		User user = getCurrentUser();
		return BeanUtils.isEmpty(user)?null:user.getUsername();
	}

	public static String getCurrentUserName(){
		User user = getCurrentUser();
		return BeanUtils.isEmpty(user)?null:user.getFullname();
	}

	/**
	 * 获取当前人员的直属下级
	 * @return
	 * User
	 * @exception
	 * @since  1.0.0
	 */
	public static List<User> getCurrentUserUnder() throws Exception {
		String userId = getCurrentUserId();
		UserManager userManager=AppUtil.getBean(UserManager.class);
		List<User> list = userManager.getUnderUsersByUserId(userId);
		return list;
	}

	/**获取当前组织*/
	public static IGroup getCurrentGroup(){
		//return null;
		//return contextUtil.currentContext.getCurrentGroup();
		try {
			UCFeignService service = AppUtil.getBean(UCFeignService.class);
			String userId = getCurrentUserId();
			if(StringUtil.isNotEmpty(userId)){
				ObjectNode orgObj = service.getMainGroup(userId);
				if(BeanUtils.isNotEmpty(orgObj)){
					boolean isParent = orgObj.get("isParent").asBoolean();
					orgObj.put("isIsParent", isParent?1:0);
					orgObj.remove("isParent");
					IGroup org = JsonUtil.toBean(orgObj, Org.class);
					return org;
				}

			}
		} catch (Exception e) {
			throw new RuntimeException(e.getMessage());
		}
		return null;
	}

	/**获取当前组织Id。组织为空则返回空*/
	public static String getCurrentGroupId(){
		IGroup iGroup =  getCurrentGroup();
		if(BeanUtils.isNotEmpty(iGroup)){
			return iGroup.getGroupId();
		}else{
			return "";
		}
	}

	public static String getCurrentOrgId(){
		UCFeignService service = AppUtil.getBean(UCFeignService.class);
		String userId = getCurrentUserId();
		if(StringUtil.isNotEmpty(userId)) {
			ObjectNode orgObj = service.getMainGroup(userId);
			if (BeanUtils.isNotEmpty(orgObj)) {
				String orgKind = orgObj.get("orgKind").asText();
				if(orgKind.equals("ogn")){
					return orgObj.get("id").asText();
				}
				if(orgKind.equals("dept")){
					return getParentOrgAttr(orgObj.get("parentId").asText(),"id");
				}
			}
		}
		return "";
	}

	public static String getCurrentOrgName(){
		UCFeignService service = AppUtil.getBean(UCFeignService.class);
		String userId = getCurrentUserId();
		if(StringUtil.isNotEmpty(userId)) {
			ObjectNode orgObj = service.getMainGroup(userId);
			if (BeanUtils.isNotEmpty(orgObj)) {
				String orgKind = orgObj.get("orgKind").asText();
				if(orgKind.equals("ogn")){
					return orgObj.get("name").asText();
				}
				if(orgKind.equals("dept")){
					return getParentOrgAttr(orgObj.get("parentId").asText(),"name");
				}
			}
		}
		return "";
	}

	public static String getParentOrgAttr(String parentId,String attrName){
		try {
			UCFeignService service = AppUtil.getBean(UCFeignService.class);
			ObjectNode parentOrgObj = service.getOrgByIdOrCode(parentId);
			if(BeanUtils.isNotEmpty(parentOrgObj)){
				String orgKind = parentOrgObj.get("orgKind").asText();

				if(orgKind.equals("ogn")){
					return parentOrgObj.get(attrName).asText();
				}
				if(orgKind.equals("dept")){
					String parentOrgParentId = parentOrgObj.get("parentId").asText();
					return getParentOrgAttr(parentOrgParentId,attrName);
				}
			}
		} catch (Exception e) {

		}
		return "";
	}

	public static String getCurrentDeptId(){
		UCFeignService service = AppUtil.getBean(UCFeignService.class);
		String userId = getCurrentUserId();
		if(StringUtil.isNotEmpty(userId)) {
			ObjectNode orgObj = service.getMainGroup(userId);
			if (BeanUtils.isNotEmpty(orgObj)) {
				String orgKind = orgObj.get("orgKind").asText();
				if(orgKind.equals("dept")){
					return orgObj.get("id").asText();
				}
			}
		}
		return "";
	}

	public static String getCurrentDeptName(){
		UCFeignService service = AppUtil.getBean(UCFeignService.class);
		String userId = getCurrentUserId();
		if(StringUtil.isNotEmpty(userId)) {
			ObjectNode orgObj = service.getMainGroup(userId);
			if (BeanUtils.isNotEmpty(orgObj)) {
				String orgKind = orgObj.get("orgKind").asText();
				if(orgKind.equals("dept")){
					return orgObj.get("name").asText();
				}
			}
		}
		return "";
	}

	public static String getCurrentOrgFullId(){
		UCFeignService service = AppUtil.getBean(UCFeignService.class);
		String userId = getCurrentUserId();
		if(StringUtil.isNotEmpty(userId)) {
			ObjectNode orgObj = service.getMainGroup(userId);
			if (BeanUtils.isNotEmpty(orgObj)) {
				String orgFullId = orgObj.get("path").asText();
				return orgFullId;
			}
		}
		return "";
	}

	public static String getCurrentOrgAddvcd(){
		UCFeignService service = AppUtil.getBean(UCFeignService.class);
		String userId = getCurrentUserId();
		if(StringUtil.isNotEmpty(userId)) {
			ObjectNode orgObj = service.getMainGroup(userId);
			if (BeanUtils.isNotEmpty(orgObj)) {
				if(orgObj.has("addvcd")){
					return orgObj.get("addvcd").asText();
				}
			}
		}
		return "";
	}
	public static String getCurrentOrgAddvcdName(){
		UCFeignService service = AppUtil.getBean(UCFeignService.class);
		String userId = getCurrentUserId();
		if(StringUtil.isNotEmpty(userId)) {
			ObjectNode orgObj = service.getMainGroup(userId);
			if (BeanUtils.isNotEmpty(orgObj)) {
				if(orgObj.has("addvcdName")){
					return orgObj.get("addvcdName").asText();
				}
			}
		}
		return "";
	}
	public static String getCurrentOrgAddvcdFull(){
		UCFeignService service = AppUtil.getBean(UCFeignService.class);
		String userId = getCurrentUserId();
		if(StringUtil.isNotEmpty(userId)) {
			ObjectNode orgObj = service.getMainGroup(userId);
			if (BeanUtils.isNotEmpty(orgObj)) {
				if(orgObj.has("addvcdFull")){
					return orgObj.get("addvcdFull").asText();
				}
			}
		}
		return "";
	}

	/**
	 * 获取当前Locale。
	 * @return
	 * Locale
	 * @exception
	 * @since  1.0.0
	 */
	public static Locale getLocale(){
		return contextUtil.currentContext.getLocale();
	}

	/**
	 * 清除当前执行人。
	 * void
	 * @exception
	 * @since  1.0.0
	 */
	public static void clearCurrentUser(){
		if(contextUtil!=null){
			contextUtil.currentContext.clearCurrentUser();
		}
	}

	/**
	 * 设置当前执行人。
	 * @param user
	 * void
	 * @exception
	 * @since  1.0.0
	 */
	public static void setCurrentUser(IUser user){
		Assert.isTrue(BeanUtils.isNotEmpty(user), "传入的用户不能为空");
		Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
		Assert.isNull(authentication, "当前登录上下文中有登录用户时不能设置用户");
		UsernamePasswordAuthenticationToken usernamePwdAuth = new UsernamePasswordAuthenticationToken(user, null);
		SecurityContextHolder.getContext().setAuthentication(usernamePwdAuth);
	}

	/**
	 * 根据用户账户获取用户
	 *
	 * @param account
	 * @return
	 * @throws Exception
	 */
	public static IUser getUserByAccount(String account)
	{
		Assert.isTrue(StringUtil.isNotEmpty(account), "必须传入用户账号");
		IUserService userServiceImpl=AppUtil.getBean(IUserService.class);
		IUser user = userServiceImpl.getUserByAccount(account);
		Assert.isTrue(BeanUtils.isNotEmpty(user), String.format("账号为：%s的用户不存在", account));
		return user;
	}

	public static void setCurrentUserByAccount(String account){
		setCurrentUser(getUserByAccount(account));
	}

	/**
	 * 设置当前组织(岗位)。
	 * @param group
	 * void
	 * @exception
	 * @since  1.0.0
	 */
	public static void setCurrentOrg(IGroup group){
		contextUtil.currentContext.setCurrentGroup(group);
	}

	/**
	 * 设置Locale。
	 * @param locale
	 * void
	 * @exception
	 * @since  1.0.0
	 */
	public static void setLocale(Locale locale){
		contextUtil.currentContext.setLocale(locale);
	}

	/**
	 * 清除Local。
	 * void
	 * @exception
	 * @since  1.0.0
	 */
	public static void cleanLocale(){
		if(contextUtil!=null){
			contextUtil.currentContext.clearLocale();
		}
	}

	public static void clearAll() {
		cleanLocale();
		clearCurrentUser();
	}
}
