/*
 * 
 */
package com.bankaudit.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.bankaudit.constants.BankAuditConstant;
import com.bankaudit.dao.MaintEntityDao;
import com.bankaudit.dto.DataTableResponse;
import com.bankaudit.model.MaintEntity;
import com.bankaudit.model.MaintEntityAuditSubgroupMapping;
import com.bankaudit.model.MaintEntityAuditSubgroupMappingHst;
import com.bankaudit.model.MaintEntityAuditSubgroupMappingWrk;
import com.bankaudit.model.MaintEntityHst;
import com.bankaudit.model.MaintEntityWrk;

/**
 * {@link MaintEntityServiceImpl} class implements the methods of
 * {@link MaintEntityService} interface.
 *
 * @author amit.patel
 * @version 1.0
 */
@Service("maintEntityService")
@Transactional("transactionManager")
public class MaintEntityServiceImpl implements MaintEntityService {

	/**
	 * The maint entity dao is autowired and make methods available from dao
	 * layer .
	 */
	@Autowired
	MaintEntityDao maintEntityDao;
	
	/**
	 * The business date service is autowired and make methods available from
	 * dao layer .
	 */
	@Autowired
	BusinessDateService businessDateService;
	
	/**
	 * The maint entity audit subgroup mapping service is autowired and make
	 * methods available from dao layer .
	 */
	@Autowired 
	MaintEntityAuditSubgroupMappingService maintEntityAuditSubgroupMappingService;
	
	/* (non-Javadoc)
	 * @see com.bankaudit.service.MaintEntityService#createMaintEntity(com.bankaudit.model.MaintEntityWrk)
	 */
	@Override
	public void createMaintEntity(MaintEntityWrk maintEntityWrk) {
			
		if(maintEntityWrk.getStatus().equalsIgnoreCase(BankAuditConstant.STATUS_DF)
				|| maintEntityWrk.getStatus().equalsIgnoreCase(BankAuditConstant.STATUS_UNAUTH)
				){
			
			maintEntityDao.save(maintEntityWrk);
			
			// Commented for BaaSDOS, as this feature taken out from here to Mapping maintenance 
			/* if(maintEntityWrk.getMaintEntityAuditSubgroupMappings()!=null 
					 && !maintEntityWrk.getMaintEntityAuditSubgroupMappings().isEmpty()){
				
				 for (MaintEntityAuditSubgroupMappingWrk maintEntityAuditSubgroupMappingWrk  : maintEntityWrk.getMaintEntityAuditSubgroupMappings()) {
					 maintEntityAuditSubgroupMappingWrk.setId(maintEntityWrk.getUnitCode());	
					 maintEntityAuditSubgroupMappingWrk.setMaker(maintEntityWrk.getMaker());
					 maintEntityAuditSubgroupMappingWrk.setBusinessdateTimestamp(maintEntityWrk.getBusinessdateTimestamp());
					 maintEntityAuditSubgroupMappingWrk.setStatus(maintEntityWrk.getStatus());
					 maintEntityAuditSubgroupMappingWrk.setSysdateTimestamp(maintEntityWrk.getSysdateTimestamp());
					 maintEntityDao.save(maintEntityAuditSubgroupMappingWrk);
					}
			 }*/
		}else if (maintEntityWrk.getStatus().equalsIgnoreCase(BankAuditConstant.STATUS_AUTH)) {
			MaintEntity maintEntity=new MaintEntity();
			BeanUtils.copyProperties(maintEntityWrk, maintEntity);
			maintEntityDao.save(maintEntity);
			
			// Commented for BaaSDOS, as this feature taken out from here to Mapping maintenance 
			/* if(maintEntity.getMaintEntityAuditSubgroupMappings()!=null 
					 && !maintEntity.getMaintEntityAuditSubgroupMappings().isEmpty()){
				 MaintEntityAuditSubgroupMapping maintEntityAuditSubgroupMapping=null;
				 for (Object maintEntityAuditSubgroupMappingWrk : maintEntity.getMaintEntityAuditSubgroupMappings()) {
					 maintEntityAuditSubgroupMapping=new MaintEntityAuditSubgroupMapping();
					 BeanUtils.copyProperties(maintEntityAuditSubgroupMappingWrk, maintEntityAuditSubgroupMapping);
					 maintEntityAuditSubgroupMapping.setId(maintEntity.getUnitCode());	
					 maintEntityAuditSubgroupMapping.setMaker(maintEntity.getMaker());
					 maintEntityAuditSubgroupMapping.setBusinessdateTimestamp(maintEntity.getBusinessdateTimestamp());
					 maintEntityAuditSubgroupMapping.setStatus(maintEntity.getStatus());
					 maintEntityAuditSubgroupMapping.setSysdateTimestamp(maintEntity.getSysdateTimestamp());
					 maintEntityDao.save(maintEntityAuditSubgroupMapping);
					}
			 }*/
		}
	}
	
	

	/* (non-Javadoc)
	 * @see com.bankaudit.service.MaintEntityService#getUnique(java.lang.Integer, java.lang.String, java.lang.String)
	 */
	@Override
	public MaintEntity getUnique(Integer legalEntityCode, String unitCode,String status) {
		 MaintEntity maintEntity=maintEntityDao.getUnique(legalEntityCode,unitCode,status);
		 if(maintEntity!=null){
			 maintEntity.setMaintEntityAuditSubgroupMappings(maintEntityAuditSubgroupMappingService.getMaintEntityAuditSubgroupMapping(legalEntityCode, "E", unitCode,status));			 
		 }
		 return maintEntity;
	}


	/* (non-Javadoc)
	 * @see com.bankaudit.service.MaintEntityService#updateMaintEntity(com.bankaudit.model.MaintEntityWrk)
	 */
	@Override
	public void updateMaintEntity(MaintEntityWrk maintEntityWrk) {
		
		if(!maintEntityWrk.getStatus().equalsIgnoreCase(BankAuditConstant.STATUS_AUTH)){

			if(maintEntityWrk.getStatus().equalsIgnoreCase(BankAuditConstant.STATUS_UNAUTH)
					|| maintEntityWrk.getStatus().equalsIgnoreCase(BankAuditConstant.STATUS_MOD)
					|| maintEntityWrk.getStatus().equalsIgnoreCase(BankAuditConstant.STATUS_DF)){
				maintEntityWrk.setMakerTimestamp(businessDateService.getBusinessDateTimestampByLegalEntityCode(maintEntityWrk.getLegalEntityCode()));
			}
			

			if(!maintEntityWrk.getStatus().equalsIgnoreCase(BankAuditConstant.STATUS_DF)){
				// get Db object and save into the history
				MaintEntity maintEntityDb=getUnique(maintEntityWrk.getLegalEntityCode(), maintEntityWrk.getUnitCode(), BankAuditConstant.STATUS_UNAUTH);
				if(maintEntityDb!=null){
					MaintEntityHst maintEntityHst=new MaintEntityHst();
					String[] ignoreProperties={
							"maintLegalEntity",
							"entityLevelCodeDesc"
					};
					BeanUtils.copyProperties(maintEntityDb, maintEntityHst, ignoreProperties);
					maintEntityDao.save(maintEntityHst);
					
					// Commented for BaaSDOS, as this feature taken out from here to Mapping maintenance 
					/* if(maintEntityHst.getMaintEntityAuditSubgroupMappings()!=null 
							 && !maintEntityHst.getMaintEntityAuditSubgroupMappings().isEmpty()){
						
						 MaintEntityAuditSubgroupMappingHst maintEntityAuditSubgroupMappingHst=null;
						 for (Object maintEntityAuditSubgroupMapping  : maintEntityHst.getMaintEntityAuditSubgroupMappings()) {
							 maintEntityAuditSubgroupMappingHst=new MaintEntityAuditSubgroupMappingHst();
							 BeanUtils.copyProperties(maintEntityAuditSubgroupMapping, maintEntityAuditSubgroupMappingHst);
							 maintEntityAuditSubgroupMappingHst.setId(maintEntityHst.getUnitCode());
							 maintEntityAuditSubgroupMappingHst.setMaker(maintEntityHst.getMaker());
							 maintEntityAuditSubgroupMappingHst.setBusinessdateTimestamp(maintEntityHst.getBusinessdateTimestamp());
							 maintEntityAuditSubgroupMappingHst.setStatus(maintEntityHst.getStatus());
							 maintEntityAuditSubgroupMappingHst.setSysdateTimestamp(maintEntityHst.getSysdateTimestamp());
							 maintEntityDao.save(maintEntityAuditSubgroupMappingHst);
							}
					 }*/
				}
			}
			
			/*//delete the existing entity  
			maintEntityDao.deleteMaintEntityWrk(maintEntityWrk.getLegalEntityCode(),maintEntityWrk.getUnitCode());
			// delete the existing work maintEntityAuditSubgroupMapping 
			maintEntityAuditSubgroupMappingService.deleteMaintEntityAuditSubgroupMappingWrk(maintEntityWrk.getLegalEntityCode(),
					 "E", maintEntityWrk.getUnitCode());*/
			maintEntityDao.flushSession();
			// save again 
			maintEntityDao.saveOrUpdate(maintEntityWrk);
			 
			// Commented for BaaSDOS, as this feature taken out from here to Mapping maintenance  
			/*if(maintEntityWrk.getMaintEntityAuditSubgroupMappings()!=null 
					 && !maintEntityWrk.getMaintEntityAuditSubgroupMappings().isEmpty()){
				
				 for (MaintEntityAuditSubgroupMappingWrk maintEntityAuditSubgroupMappingWrk  : maintEntityWrk.getMaintEntityAuditSubgroupMappings()) {
					 maintEntityAuditSubgroupMappingWrk.setId(maintEntityWrk.getUnitCode());
					 maintEntityAuditSubgroupMappingWrk.setMaker(maintEntityWrk.getMaker());
					 maintEntityAuditSubgroupMappingWrk.setBusinessdateTimestamp(maintEntityWrk.getBusinessdateTimestamp());
					 maintEntityAuditSubgroupMappingWrk.setStatus(maintEntityWrk.getStatus());
					 maintEntityAuditSubgroupMappingWrk.setSysdateTimestamp(maintEntityWrk.getSysdateTimestamp());
					 maintEntityDao.saveOrUpdate(maintEntityAuditSubgroupMappingWrk);
					}
			 }*/
			
		}else{

			// get Db object and save into the history
			MaintEntity maintEntityDb=getUnique(maintEntityWrk.getLegalEntityCode(), maintEntityWrk.getUnitCode(), BankAuditConstant.STATUS_AUTH);
			if(maintEntityDb!=null){
				MaintEntityHst maintEntityHst=new MaintEntityHst();
				String[] ignoreProperties={
						"maintLegalEntity",
						"entityLevelCodeDesc"
				};
				BeanUtils.copyProperties(maintEntityDb, maintEntityHst, ignoreProperties);
				maintEntityDao.save(maintEntityHst);
				 if(maintEntityHst.getMaintEntityAuditSubgroupMappings()!=null 
						 && !maintEntityHst.getMaintEntityAuditSubgroupMappings().isEmpty()){
					 MaintEntityAuditSubgroupMappingHst maintEntityAuditSubgroupMappingHst=null;
					 for (Object maintEntityAuditSubgroupMapping  : maintEntityHst.getMaintEntityAuditSubgroupMappings()) {
						 maintEntityAuditSubgroupMappingHst=new MaintEntityAuditSubgroupMappingHst();
						 BeanUtils.copyProperties(maintEntityAuditSubgroupMapping, maintEntityAuditSubgroupMappingHst);
						 maintEntityAuditSubgroupMappingHst.setId(maintEntityHst.getUnitCode());
						 maintEntityAuditSubgroupMappingHst.setMaker(maintEntityHst.getMaker());
						 maintEntityAuditSubgroupMappingHst.setBusinessdateTimestamp(maintEntityHst.getBusinessdateTimestamp());
						 maintEntityAuditSubgroupMappingHst.setStatus(maintEntityHst.getStatus());
						 maintEntityAuditSubgroupMappingHst.setSysdateTimestamp(maintEntityHst.getSysdateTimestamp());
						 maintEntityDao.save(maintEntityAuditSubgroupMappingHst);
						}
				 }
				
				
			}
			
			//delete the existing entity  
		/*	maintEntityDao.deleteMaintEntity(maintEntityWrk.getLegalEntityCode(),maintEntityWrk.getUnitCode());*/
			maintEntityDao.deleteMaintEntityWrk(maintEntityWrk.getLegalEntityCode(),maintEntityWrk.getUnitCode());
			
			// delete the existing  maintEntityAuditSubgroupMapping from both table 
			maintEntityAuditSubgroupMappingService.deleteMaintEntityAuditSubgroupMappingWrk(maintEntityWrk.getLegalEntityCode(),
					 "E", maintEntityWrk.getUnitCode());
		/*	maintEntityAuditSubgroupMappingService.deleteMaintEntityAuditSubgroupMapping(maintEntityWrk.getLegalEntityCode(),
					 "E", maintEntityWrk.getUnitCode());*/
			maintEntityDao.flushSession();
			
			MaintEntity maintEntity=new MaintEntity();
			
			BeanUtils.copyProperties(maintEntityWrk, maintEntity);
			maintEntity.setCheckerTimestamp(maintEntity.getBusinessdateTimestamp());
			// save again 
			maintEntityDao.saveOrUpdate(maintEntity);
			 
			 if(maintEntity.getMaintEntityAuditSubgroupMappings()!=null 
					 && !maintEntity.getMaintEntityAuditSubgroupMappings().isEmpty()){
				 MaintEntityAuditSubgroupMapping maintEntityAuditSubgroupMapping=null; 
				 for (Object maintEntityAuditSubgroupMappingWrk  : maintEntity.getMaintEntityAuditSubgroupMappings()) {
					 maintEntityAuditSubgroupMapping=new MaintEntityAuditSubgroupMapping();
					 BeanUtils.copyProperties(maintEntityAuditSubgroupMappingWrk, maintEntityAuditSubgroupMapping);
					 maintEntityAuditSubgroupMapping.setBusinessdateTimestamp(maintEntity.getBusinessdateTimestamp());
					 maintEntityAuditSubgroupMapping.setSysdateTimestamp(maintEntity.getSysdateTimestamp());
					 maintEntityAuditSubgroupMapping.setStatus(maintEntity.getStatus());
					 maintEntityAuditSubgroupMapping.setMaker(maintEntity.getMaker());
					 maintEntityAuditSubgroupMapping.setId(maintEntity.getUnitCode());
					 maintEntityAuditSubgroupMapping.setMakerTimestamp(maintEntity.getMakerTimestamp());
					 maintEntityDao.saveOrUpdate(maintEntityAuditSubgroupMapping);
					}
				 
			 }
		}
		
	}

	/* (non-Javadoc)
	 * @see com.bankaudit.service.MaintEntityService#getMaintEntity(java.lang.Integer, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.Integer, java.lang.String, java.lang.Integer, java.lang.Integer)
	 */
	@Override
	public DataTableResponse getMaintEntity(Integer legalEntityCode, String levelCodeStr,String userId,String parentUnitCode, String search,
			Integer orderColumn, String orderDirection, Integer page, Integer size) {

		return maintEntityDao.getMaintEntity(legalEntityCode,levelCodeStr,userId,parentUnitCode,search,orderColumn,orderDirection,page,size);
	
	}

	/* (non-Javadoc)
	 * @see com.bankaudit.service.MaintEntityService#getMaintEntityByLegalEntityCodeAndLevelCode(java.lang.Integer, java.lang.String)
	 */
	@Override
	public List<MaintEntity> getMaintEntityByLegalEntityCodeAndLevelCode(Integer legalEntityCode, String levelCode) {
			
		return maintEntityDao.getMaintEntityByLegalEntityCodeAndLevelCode(legalEntityCode,levelCode);
	}

	/* (non-Javadoc)
	 * @see com.bankaudit.service.MaintEntityService#getMaintEntityByLegalEntityCode(java.lang.Integer)
	 */
	@SuppressWarnings("unchecked")
	@Override
	public List<MaintEntity> getMaintEntityByLegalEntityCode(Integer legalEntityCode) {
		
		Map<String,Object> properties=new HashMap<String,Object>();
		
		properties.put("legalEntityCode", legalEntityCode);
		properties.put("entityStatus", BankAuditConstant.STATUS_ACTIVE);
		return maintEntityDao.getEntitiesByMatchingProperties(MaintEntity.class, properties);
	}

	/* (non-Javadoc)
	 * @see com.bankaudit.service.MaintEntityService#isHeadUser(java.lang.Integer, java.lang.String, java.lang.String)
	 */
	@Override
	public Boolean isHeadUser(Integer legalEntityCode, String userId, String unitCode) {
		
		return maintEntityDao.isHeadUser( legalEntityCode,  userId,  unitCode);
	}



	/* (non-Javadoc)
	 * @see com.bankaudit.service.MaintEntityService#isMaintEntity(java.lang.Integer, java.lang.String)
	 */
	@Override
	public Boolean isMaintEntity(Integer legalEntityCode, String unitCode) {
		return maintEntityDao.isMaintEntity( legalEntityCode,  unitCode);
	}



	@Override
	public Boolean isChildUnitActivated(Integer legalEntityCode, String unitCode) {
		return maintEntityDao.isChildUnitActivated( legalEntityCode,  unitCode);
	}

	
	public List<MaintEntity> getSubBranchesGyUserIdOrUnitId(Integer legalEntityCode,String role,String type,String userIdOrUnitId){
		return maintEntityDao.getSubBranchesGyUserIdOrUnitId(legalEntityCode,role,type, userIdOrUnitId);
	}

	public List<String> getSubBranchesGyUserIdOrUnitId(Integer legalEntityCode,String type,String userIdOrUnitId){
		return maintEntityDao.getSubBranchesGyUserIdOrUnitId(legalEntityCode,type, userIdOrUnitId);
	}


	@Override
	public List<MaintEntity> getImmediateChild(Integer legalEntityCode, String userId) {
		return maintEntityDao.getImmediateChild( legalEntityCode,  userId);
	}



	@Override
	public MaintEntity getUniqueByUserId(int legalEntityCode, String userId) {
		Map<String,Object> properties=new HashMap<String,Object>();
		properties.put("legalEntityCode", legalEntityCode);
		properties.put("entityStatus", BankAuditConstant.STATUS_ACTIVE);
		properties.put("unitHeadUser", userId);
		return (MaintEntity) maintEntityDao.getUniqueEntityByMatchingProperties(MaintEntity.class, properties);
	}
	
	@Override
	public List<MaintEntity> getMaintEntityByLEAndUser(Integer legalEntityCode, String userId, String role, String unitCode){
		List<MaintEntity> mntList = null;
		List<String> unitlst = null;
		if(role != null && (role.equalsIgnoreCase("G1") || role.equalsIgnoreCase("G6"))) {
			unitlst= maintEntityDao.getSubBranchesGyUserIdOrUnitId(legalEntityCode,"unit", unitCode);
		}else {
			unitlst = new ArrayList();unitlst.add(unitCode);
		}
		mntList=maintEntityDao.getMaintEntityByLEAndUser(legalEntityCode,role, unitlst);
		System.out.println("mntList .."+mntList);
		return mntList;
	}
	
	public Map<String, String> getRiskManagerDetails(Integer legalEntityCode, String userId, String role, String unitCode){
		return maintEntityDao.getRiskManagerDetails(legalEntityCode,userId, role, unitCode);
	}
	
	@Override
	public void deleteMaintEntityByID(Integer legalEntityCode, String unitCode, String userId) {
		 maintEntityDao.deleteMaintEntityWrk(legalEntityCode, unitCode);
	}		
	
	@Override
	public List<MaintEntity> getEntityByLevelAndNotInGrpEntityMapping (Integer legalEntityCode, String levelCode, String status) {
		List<MaintEntity> entities=maintEntityDao.getEntityByLevelAndNotInGrpEntityMapping( legalEntityCode,  levelCode ,status);
	 	return entities ;
	}
	

	@Override
	public List<MaintEntity> getMaintEntityByLegalEntityCodeAndAuditTypeCode(Integer legalEntityCode, String auditTypeCode) {
		return maintEntityDao.getMaintEntityByLegalEntityCodeAndAuditTypeCode(legalEntityCode, auditTypeCode);
	}
	
	@Override
	public MaintEntity getUnitDetails(Integer legalEntityCode, String unitCode) {
		 MaintEntity maintEntity=maintEntityDao.getUnitDetails(legalEntityCode,unitCode);
		  return maintEntity;
	}
	
	public Map<String, String> getUnitCodes(Integer legalEntityCode, String userId, String role) {
		List<MaintEntity> entities=maintEntityDao.getUnitCodes( legalEntityCode,  userId , role);
		Map<String, String> unitCodes = entities.stream().collect(Collectors.toMap(MaintEntity :: getUnitCode, MaintEntity :: getUnitCode));
		return unitCodes;
	}
	
	@Override
	public List<MaintEntity> getEntityForPlanLevel(Integer legalEntityCode, String userId, String levelCode) {
		return maintEntityDao.getEntityForPlanLevel(legalEntityCode, userId, levelCode);
	}
	
	@Override
	public String getLicenseeCodeForUnitCode(Integer legalEntityCode, String unitCode) {
		return maintEntityDao.getLicenseeCodeForUnitCode(legalEntityCode, unitCode);
	}
}
