package com.goafanti.permission.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.goafanti.common.constant.AFTConstants;
import com.goafanti.common.dao.RoleMapper;
import com.goafanti.common.dao.RolePermissionMapper;
import com.goafanti.common.dao.UserMapper;
import com.goafanti.common.dao.UserRoleMapper;
import com.goafanti.common.model.Permission;
import com.goafanti.common.model.Role;
import com.goafanti.common.model.RolePermission;
import com.goafanti.common.model.UserRole;
import com.goafanti.core.mybatis.BaseMybatisDao;
import com.goafanti.core.shiro.token.TokenManager;
import com.goafanti.permission.bo.RoleBo;
import com.goafanti.permission.bo.RolePermissionBo;
import com.goafanti.permission.service.RoleService;

@Service
public class RoleServiceImpl extends BaseMybatisDao<RoleMapper> implements RoleService {

	@Autowired
	RoleMapper				roleMapper;
	@Autowired
	UserMapper				userMapper;
	@Autowired
	UserRoleMapper			userRoleMapper;
	@Autowired
	RolePermissionMapper	rolePermissionMapper;

	@Override
	public Set<String> findRoleByUserId(String userId) {
		return roleMapper.findRoleByUserId(userId);
	}

	@Override
	public List<RoleBo> findRoles() {
		List<RolePermissionBo> res = null;
		if (!TokenManager.hasRole(AFTConstants.SUPERADMIN)) {
			 res = roleMapper.findRolePermissionsExceptAreaManager();
		} else {
			 res = roleMapper.findRolePermissions();
		}
		
		Map<String, RoleBo> roleMap = new HashMap<>();
		for (RolePermissionBo rp : res) {
			RoleBo rb = roleMap.get(rp.getRid());
			if (rb == null) {
				rb = new RoleBo();
				rb.setId(rp.getRid());
				rb.setRoleName(rp.getRname());
				rb.setRoleType(rp.getType());
				roleMap.put(rp.getRid(), rb);
			}
			Permission p = new Permission();
			p.setId(rp.getPid());
			p.setName(rp.getPname());
			p.setUrl(rp.getUrl());
			if (p.getId() != null) {
				rb.getPermissions().add(p);
			}
		}
		return new ArrayList<>(roleMap.values());
	}

	@Override
	public int insert(List<Role> records) {
		return roleMapper.insertBatch(records);
	}

	@Override
	public int deleteByPrimaryKeys(List<String> records) {
		rolePermissionMapper.deleteByRoleId(records);
		userRoleMapper.deleteByRoleId(records);
		TokenManager.clearUserAuthByUserId((String[]) userRoleMapper.findUserIdByRoleIds(records).toArray());
		return roleMapper.deleteByPrimaryKeys(records);
	}

	@Override
	public int bindPermission(String rid, String pid) {
		TokenManager.clearUserAuthByUserId((String[]) userRoleMapper.findUserIdByRoleId(rid).toArray());
		return rolePermissionMapper.insert(new RolePermission(rid, pid));
	}

	@Override
	public int bindUser(String rid, String uid) {
		TokenManager.clearUserAuthByUserId(new String[] { uid });
		return userRoleMapper.insert(new UserRole(uid, rid));
	}

	@Override
	public int unbindPermission(String roleId, String permissionId) {
		Map<String, Object> params = new HashMap<>();
		params.put("rid", roleId);
		params.put("pid", permissionId);
		TokenManager.clearUserAuthByUserId((String[]) userRoleMapper.findUserIdByRoleId(roleId).toArray());
		return rolePermissionMapper.deleteByPrimaryKey(params);
	}

	@Override
	public int unbindUser(String roleId, String userId) {
		Map<String, Object> params = new HashMap<>();
		params.put("rid", roleId);
		params.put("uid", userId);
		TokenManager.clearUserAuthByUserId(new String[] { userId });
		return userRoleMapper.deleteByUserRole(params);
	}

	@Override
	public int insert(Role record, List<String> permissions) {
		if (record.getId() != null) {
			List<RolePermission> rps = new ArrayList<>();
			rolePermissionMapper.deleteByRid(record.getId());
			for (String pid : permissions) {
				rps.add(new RolePermission(record.getId(), pid));
			}
			if (!rps.isEmpty()) {
				rolePermissionMapper.insertBatch(rps);
			}
			List<String> ids = userRoleMapper.findUserIdByRoleId(record.getId());
			TokenManager.clearUserAuthByUserId(ids.toArray(new String[ids.size()]));
		}
		record.getId();
		return roleMapper.insert(record);
	}

}
