package com.artfess.uc.manager.impl;

import com.artfess.base.conf.SaaSConfig;
import com.artfess.base.constants.SystemConstants;
import com.artfess.base.constants.TenantConstant;
import com.artfess.base.exception.BaseException;
import com.artfess.base.feign.SystemConfigFeignService;
import com.artfess.base.handler.MultiTenantHandler;
import com.artfess.base.handler.MultiTenantIgnoreResult;
import com.artfess.base.manager.impl.BaseManagerImpl;
import com.artfess.base.model.CommonResult;
import com.artfess.base.query.PageList;
import com.artfess.base.query.QueryFilter;
import com.artfess.base.util.BeanUtils;
import com.artfess.base.util.TenantUtil;
import com.artfess.base.util.UniqueIdUtil;
import com.artfess.base.util.time.DateUtil;
import com.artfess.security.util.AuthorCheck;
import com.artfess.uc.dao.TenantManageDao;
import com.artfess.uc.dao.UserDao;
import com.artfess.uc.manager.PwdStrategyManager;
import com.artfess.uc.manager.TenantManageManager;
import com.artfess.uc.manager.UserManager;
import com.artfess.uc.model.PwdStrategy;
import com.artfess.uc.model.TenantManage;
import com.artfess.uc.model.User;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.seata.spring.annotation.GlobalTransactional;
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 org.springframework.util.Assert;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;

/**
 *
 * <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
    SystemConfigFeignService systemConfigFeignService;
	@Autowired
	PasswordEncoder passwordEncoder;
	@Autowired
	UserManager userManager;
	@Autowired
	UserDao userDao;
	@Autowired
	PwdStrategyManager pwdStrategyManager;
	@Autowired
	SaaSConfig saaSConfig;
	@Autowired
	private AuthorCheck authorCheck;
	/**
	 * <pre>
	 * 重写通用的创建数据的方法
	 * 创建租户的同时初始化一份平台的数据给租户使用(维度，默认分类)
	 * 需要处理分布式事务
	 *
	 * </pre>
	 */
	@Override
    @GlobalTransactional
	public void create(TenantManage t) {
		//Todo 等要验证版本权限时候开放
		/*SysAuthorization resultCode = authorCheck.redFileToObject();
		if(resultCode==null){
			throw new RuntimeException("添加租户失败，没找到系统的授权信息！");
		}
		int tenantNum = Integer.valueOf(resultCode.getTenantNum());
		JdbcTemplate jdbcTemplate = AppUtil.getBean(JdbcTemplate.class);
		String sql = "select count(*) from UC_TENANT_MANAGE where  IS_DELE_!= '1' ";
		int num = jdbcTemplate.queryForObject(sql, Integer.class);
		if(num >= tenantNum){
			throw new RuntimeException("添加租户失败，添加的租户数量已等于授权的数量【"+tenantNum+"】了！");
		}*/

		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 = systemConfigFeignService.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()){
			PwdStrategy strategy = pwdStrategyManager.getDefault();
			String defaultPswd = "123456";
			if (strategy != null) {
				defaultPswd = strategy.getInitPwd();
			}
			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(defaultPswd));
			tenantAdmin.setPwdCreateTime(LocalDateTime.now());
			tenantAdmin.setUserType(0);
			tenantAdmin.setLockedStatus(1);
			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(defaultPswd));
			tenantGuest.setPwdCreateTime(LocalDateTime.now());
			tenantAdmin.setUserType(2);
			tenantAdmin.setLockedStatus(1);
			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 List<TenantManage> getByStatus(String typeId, String status) {
		return baseMapper.getByStatus(typeId, status);
	}

	@Override
	@Transactional
	public void setThreeAdmin(Integer isPartThree, String tenantId) throws Exception {
		Assert.notNull(isPartThree, "开启或关闭三员状态不能为空！");
		TenantManage tenantManage = baseMapper.selectById(tenantId);
		//关闭三员
		if(tenantManage != null && isPartThree == 0){
			tenantManage.setIsPartThree(0);
			User sysadmin = userManager.getByAccount(SystemConstants.SYS_ADMIN_ACCOUNT);
			User secadmin = userManager.getByAccount(SystemConstants.SEC_ACCOUNT);
			User audit = userManager.getByAccount(SystemConstants.AUDIT_ACCOUNT);
			if (BeanUtils.isNotEmpty(sysadmin)) {
				userManager.remove(sysadmin.getId());
			}
			if (BeanUtils.isNotEmpty(secadmin)) {
				userManager.remove(secadmin.getId());
			}
			if (BeanUtils.isNotEmpty(audit)) {
				userManager.remove(audit.getId());
			}
		}
		//开启三员
		if(tenantManage != null && isPartThree == 1){
			tenantManage.setIsPartThree(1);
			User sysadmin = userDao.getAllDataByAccount(SystemConstants.SYS_ADMIN_ACCOUNT);
			User secadmin = userDao.getAllDataByAccount(SystemConstants.SEC_ACCOUNT);
			User audit = userDao.getAllDataByAccount(SystemConstants.AUDIT_ACCOUNT);
			if(BeanUtils.isNotEmpty(sysadmin)){
				userDao.restoreDeletedUser(sysadmin.getId());
			}else{
				try(MultiTenantIgnoreResult setThreadLocalIgnore = MultiTenantHandler.setThreadLocalIgnore()){
					PwdStrategy strategy = pwdStrategyManager.getDefault();
					String defaultPswd = "123456";
					if (strategy != null) {
						defaultPswd = strategy.getInitPwd();
					}
					User sys = new User();
					sys.setAccount(SystemConstants.SYS_ADMIN_ACCOUNT);
					sys.setFullname("系统管理员");
					sys.setStatus(User.STATUS_NORMAL);
					sys.setId(UniqueIdUtil.getSuid());
					sys.setCreateTime(LocalDateTime.now());
					sys.setFrom(User.FROM_RESTFUL);
					sys.setPassword(passwordEncoder.encode(defaultPswd));
					sys.setPwdCreateTime(LocalDateTime.now());
					sys.setUserType(1);
					sys.setLockedStatus(1);
					if(saaSConfig.isEnable()) {
						sys.setTenantId(tenantId);
					}
					userManager.create(sys);
				}catch(Exception e) {
					throw new BaseException(e.getMessage(),e);
				}
			}
			if(BeanUtils.isNotEmpty(secadmin)){
				userDao.restoreDeletedUser(secadmin.getId());
			}else{
				try(MultiTenantIgnoreResult setThreadLocalIgnore = MultiTenantHandler.setThreadLocalIgnore()){
					PwdStrategy strategy = pwdStrategyManager.getDefault();
					String defaultPswd = "123456";
					if (strategy != null) {
						defaultPswd = strategy.getInitPwd();
					}
					User sys = new User();
					sys.setAccount(SystemConstants.SEC_ACCOUNT);
					sys.setFullname("系统安全员");
					sys.setStatus(User.STATUS_NORMAL);
					sys.setId(UniqueIdUtil.getSuid());
					sys.setCreateTime(LocalDateTime.now());
					sys.setFrom(User.FROM_RESTFUL);
					sys.setPassword(passwordEncoder.encode(defaultPswd));
					sys.setPwdCreateTime(LocalDateTime.now());
					sys.setUserType(1);
					sys.setLockedStatus(1);
					if(saaSConfig.isEnable()) {
						sys.setTenantId(tenantId);
					}
					userManager.create(sys);
				}catch(Exception e) {
					throw new BaseException(e.getMessage(),e);
				}
			}
			if(BeanUtils.isNotEmpty(audit)){
				userDao.restoreDeletedUser(audit.getId());
			}else{
				try(MultiTenantIgnoreResult setThreadLocalIgnore = MultiTenantHandler.setThreadLocalIgnore()){
					PwdStrategy strategy = pwdStrategyManager.getDefault();
					String defaultPswd = "123456";
					if (strategy != null) {
						defaultPswd = strategy.getInitPwd();
					}
					User sys = new User();
					sys.setAccount(SystemConstants.AUDIT_ACCOUNT);
					sys.setFullname("日志审计员");
					sys.setStatus(User.STATUS_NORMAL);
					sys.setId(UniqueIdUtil.getSuid());
					sys.setCreateTime(LocalDateTime.now());
					sys.setFrom(User.FROM_RESTFUL);
					sys.setPassword(passwordEncoder.encode(defaultPswd));
					sys.setPwdCreateTime(LocalDateTime.now());
					sys.setUserType(1);
					sys.setLockedStatus(1);
					if(saaSConfig.isEnable()) {
						sys.setTenantId(tenantId);
					}
					userManager.create(sys);
				}catch(Exception e) {
					throw new BaseException(e.getMessage(),e);
				}
			}
		}
		//保存三员状态
		baseMapper.updateById(tenantManage);
	}
}
