package com.nisum.mytime.service;

import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;

import com.mongodb.WriteResult;
import com.nisum.mytime.exception.handler.MyTimeException;
import com.nisum.mytime.model.RoleMappingInfo;
import com.nisum.mytime.repository.RoleInfoRepo;
import com.nisum.mytime.repository.RoleMappingInfoRepo;
import com.nisum.mytime.utils.MyTimeUtils;

@Service
public class RoleMappingServiceImpl implements RoleMappingService {

	@Autowired
	private RoleMappingInfoRepo roleMappingInfoRepo;

	@Autowired
	private RoleInfoRepo roleInfoRepo;

	@Autowired
	private MongoTemplate mongoTemplate;

	@Override
	public void saveUniqueEmployeeAndRole(List<String> employeeIds, String roleId) throws MyTimeException {
		for (String employeeId : employeeIds) {
			addEmployeeRole(employeeId, roleId);
		}
	}
	
	public void addEmployeeRole(String employeeId, String roleId) throws MyTimeException {
		RoleMappingInfo roleMappingInfo = roleMappingInfoRepo.findByEmployeeIdAndRoleId(employeeId, roleId);
		boolean isChanged = false;
		if (roleMappingInfo == null) {
			roleMappingInfo = new RoleMappingInfo();
			roleMappingInfo.setEmployeeId(employeeId);
			roleMappingInfo.setRoleId(roleId);
			roleMappingInfo.setIsActive("Y");
			isChanged = true;
		} else if (roleMappingInfo.getIsActive().equalsIgnoreCase("N")) {
			roleMappingInfo.setIsActive("Y");
			isChanged = true;
		}
		if (isChanged) {
			roleMappingInfoRepo.save(roleMappingInfo);
		}
	}

	@Override
	public WriteResult deleteRole(String employeeId, String roleId) throws MyTimeException {
		Query query = new Query(Criteria.where("employeeId").is(employeeId).and("roleId").is(roleId));
		Update update = new Update();
		update.set(MyTimeUtils.IS_ACTIVE, "N");
		return mongoTemplate.upsert(query, update, RoleMappingInfo.class);
	}

	@Override
	public String getEmployeeRole(String employeeId) {
		Map<Integer, String> roleInfoMap = new LinkedHashMap<Integer, String>();

		List<RoleMappingInfo> listOfEmployeeRoles = roleMappingInfoRepo.findByEmployeeId(employeeId);

		for (RoleMappingInfo employee : listOfEmployeeRoles) {
			roleInfoMap.put((roleInfoRepo.findByRoleId(employee.getRoleId())).getPriority(), employee.getRoleId());
		}
		roleInfoMap = roleInfoMap.entrySet().stream().sorted(Map.Entry.comparingByKey()).collect(Collectors
				.toMap(Map.Entry::getKey, Map.Entry::getValue, (oldValue, newValue) -> oldValue, LinkedHashMap::new));

		String roleName = null;
		if (!roleInfoMap.isEmpty()) {
			Map.Entry<Integer, String> entry = roleInfoMap.entrySet().iterator().next();
			roleName = roleInfoRepo.findByRoleId(entry.getValue()).getRoleName();
		} else {
			roleName = null;
		}
		return roleName;
	}
	
	
	@Override
	public Set<String> empRolesMapInfoByEmpId(String employeeId) { 
		Set<String> roleSet = new HashSet<String>();
		List<RoleMappingInfo> listOfEmployeeRoles = roleMappingInfoRepo.findByEmployeeId(employeeId);
		
		if(null != listOfEmployeeRoles && !listOfEmployeeRoles.isEmpty() && MyTimeUtils.INT_ZERO  < listOfEmployeeRoles.size()) {
			for(RoleMappingInfo obj : listOfEmployeeRoles) {
				roleSet.add(obj.getRoleId());
			}
		}
		
		return roleSet;
	}
	

}
