package com.hotent.uc.manager.impl;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.hotent.base.feign.BpmRuntimeFeignService;
import com.hotent.base.query.FieldRelation;
import com.hotent.base.query.QueryOP;
import com.hotent.base.util.BeanUtils;
import com.hotent.base.util.StringUtil;
import com.hotent.uc.manager.TenantAuthManager;
import com.hotent.uc.model.TenantAuth;
import com.hotent.uc.util.ContextUtil;
import io.seata.spring.annotation.GlobalTransactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.hotent.base.constants.SystemConstants;
import com.hotent.base.constants.TenantConstant;
import com.hotent.base.exception.BaseException;
import com.hotent.base.feign.PortalFeignService;
import com.hotent.base.handler.MultiTenantHandler;
import com.hotent.base.handler.MultiTenantIgnoreResult;
import com.hotent.base.manager.impl.BaseManagerImpl;
import com.hotent.base.model.CommonResult;
import com.hotent.base.query.PageList;
import com.hotent.base.query.QueryFilter;
import com.hotent.base.util.TenantUtil;
import com.hotent.base.util.UniqueIdUtil;
import com.hotent.base.util.time.DateUtil;
import com.hotent.uc.dao.TenantManageDao;
import com.hotent.uc.manager.TenantManageManager;
import com.hotent.uc.manager.UserManager;
import com.hotent.uc.model.TenantManage;
import com.hotent.uc.model.User;

/**
 * 
 * <pre> 
 * 描述：UC_TENANT_MANAGE 处理实现类
 * 构建组：x7
 * 作者:zhangxw
 * 邮箱:zhangxw@jee-soft.cn
 * 日期:2020-04-17 10:56:07
 * 版权：广州宏天软件股份有限公司
 * </pre>
 */
@Service("tenantManageManager")
public class TenantManageManagerImpl extends BaseManagerImpl<TenantManageDao, TenantManage> implements TenantManageManager{
	
	@Resource
	PortalFeignService portalFeignService;
	@Autowired
	PasswordEncoder passwordEncoder;
	@Autowired
	UserManager userManager;
	@Resource
	TenantAuthManager tenantAuthManager;
	@Resource
	BpmRuntimeFeignService bpmRuntimeFeignService;
	
	/**
	 * <pre>
	 * 重写通用的创建数据的方法
	 * 创建租户的同时初始化一份平台的数据给租户使用(维度，默认分类)
	 * 需要处理分布式事务
	 * 
	 * </pre>
	 */
	@Override
    @GlobalTransactional
	public void create(TenantManage t) {
		t.setUpdateTime(DateUtil.getCurrentDate());
		super.create(t);
		//给租户添加管理员帐号和游客账号
		this.initTenantAdminAndGuest(t.getId());
		TenantUtil.initData(t.getId(), TenantConstant.INIT_UC_DATA_TABLE_NAMES);
		try {			
			CommonResult<String> initData = portalFeignService.initData(t.getId());
			if(!initData.getState()) {
				throw new BaseException("创建租户初始化数据失败");
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw new BaseException("创建租户初始化数据失败",e);
		}
	}
	
	/**
	 * 给新创建的租户添加默认超级管理员帐号
	 * @param tenantId
	 */
	private void initTenantAdminAndGuest(String tenantId){
		try(MultiTenantIgnoreResult setThreadLocalIgnore = MultiTenantHandler.setThreadLocalIgnore()){
			
			User tenantAdmin = new User();
			tenantAdmin.setAccount(SystemConstants.SYSTEM_ACCOUNT);
			tenantAdmin.setFullname("超级管理员");
			tenantAdmin.setStatus(User.STATUS_NORMAL);
			tenantAdmin.setId(UniqueIdUtil.getSuid());
			tenantAdmin.setCreateTime(LocalDateTime.now());
			tenantAdmin.setFrom(User.FROM_RESTFUL);
			tenantAdmin.setPassword(passwordEncoder.encode("123456"));
			tenantAdmin.setPwdCreateTime(LocalDateTime.now());
			tenantAdmin.setTenantId(tenantId);
			userManager.create(tenantAdmin);
			
			User tenantGuest = new User();
			tenantGuest.setAccount(SystemConstants.GUEST_ACCOUNT);
			tenantGuest.setFullname("游客账号");
			tenantGuest.setStatus(User.STATUS_NORMAL);
			tenantGuest.setId(UniqueIdUtil.getSuid());
			tenantGuest.setCreateTime(LocalDateTime.now());
			tenantGuest.setFrom(User.FROM_RESTFUL);
			tenantGuest.setPassword(passwordEncoder.encode("123456"));
			tenantGuest.setPwdCreateTime(LocalDateTime.now());
			tenantGuest.setTenantId(tenantId);
			userManager.create(tenantGuest);
		}
		catch(Exception e) {
			throw new BaseException(e.getMessage(),e);
		}
	}

	@Override
	public TenantManage getByCode(String code) {
		return baseMapper.getByCode(code);
	}

	@Override
	public List<TenantManage> getByTypeId(String typeId) {
		return baseMapper.getByTypeId(typeId);
	}

	@Override
	@Transactional
	public void deleteByTypeId(String typeId) {
		baseMapper.deleteByTypeId(typeId);
	}

	@Override
	public TenantManage getByDomain(String domain) {
		return baseMapper.getByDomain(domain);
	}

	@Override
	public PageList queryWithType(QueryFilter queryFilter) {
		IPage page = convert2IPage(queryFilter.getPageBean());
		return new PageList(baseMapper.queryWithType(page,convert2Wrapper(queryFilter,currentModelClass())));
	}

	@Override
	public PageList<TenantManage> listJson(QueryFilter queryFilter) throws Exception {
		User user = ContextUtil.getCurrentUser();
		if(!user.isAdmin()){
			//处理管理员数据权限
			List<String> authTypeIds = new ArrayList<String>();
			List<String> authTenantIds = new ArrayList<String>();
			List<TenantAuth> auths = tenantAuthManager.getByUserId(null, null, user.getId());
			if(BeanUtils.isNotEmpty(auths)){
				for (TenantAuth tenantAuth : auths) {
					if(StringUtil.isEmpty(tenantAuth.getTenantId())){
						authTypeIds.add(tenantAuth.getTypeId());
					}else{
						authTenantIds.add(tenantAuth.getTenantId());
					}
				}
			}
			if(BeanUtils.isEmpty(authTypeIds) && BeanUtils.isEmpty(authTenantIds) ){
				authTypeIds.add("0");
				authTenantIds.add("0");
			}
			if(BeanUtils.isNotEmpty(authTypeIds)){
				queryFilter.addFilter("TYPE_ID_", authTypeIds, QueryOP.IN, FieldRelation.OR, "auth");
			}
			if(BeanUtils.isNotEmpty(authTenantIds)){
				queryFilter.addFilter("ID_", authTenantIds, QueryOP.IN, FieldRelation.OR, "auth");
			}
		}
		PageList<TenantManage> pageList = this.queryWithType(queryFilter);
		//处理租户类型名称
//		if(BeanUtils.isNotEmpty(pageList) && pageList.getRows().size()>0){
//			List<TenantType> types = tenantTypeManager.getAll();
//			Map<String,String> typeNameMaps = new HashMap<String,String>();
//			for (TenantType tenantType : types) {
//				typeNameMaps.put(tenantType.getId(), tenantType.getName());
//			}
//			for (TenantManage tenant : pageList.getRows()) {
//				tenant.setTypeName(typeNameMaps.get(tenant.getTypeId()));
//			}
//		}
		return pageList;
	}

	@Override
	public CommonResult<String> saveTenantManage(TenantManage tenantManage) throws Exception {
		String msg = "添加租户管理 成功";
		if(StringUtil.isEmpty(tenantManage.getId())){
			this.create(tenantManage);
		}else{
			if(TenantManage.STATUS_DISABLED.equals(tenantManage.getStatus())) {
				TenantManage oldManage = this.get(tenantManage.getId());
				if(TenantManage.STATUS_ENABLE.equals(oldManage.getStatus())) {
					//禁用
					String tenantId = tenantManage.getId();
					List<ObjectNode> tasList = bpmRuntimeFeignService.getTaskListByTenantId(tenantId);
					if(BeanUtils.isNotEmpty(tasList)) {
						if(tasList.size() >0) {
							throw new BaseException("该租户仍有任务未完成，不允许禁用！");
						}
					}
				}
			}
			this.update(tenantManage);
			UpdateWrapper wrapper = new UpdateWrapper();
			wrapper.set("type_id_",tenantManage.getTypeId());
			wrapper.eq("tenant_id_",tenantManage.getId());
			tenantAuthManager.update(wrapper);
			msg = "保存成功";
		}
		return new CommonResult<String>(true,msg,tenantManage.getId());
	}

	@Override
	public List<TenantManage> getByStatus(String typeId, String status) {
		return baseMapper.getByStatus(typeId, status);
	}
	
}
