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.MaintHealthIndexDao;
import com.bankaudit.dto.DataTableResponse;
import com.bankaudit.model.MaintHealthIndex;
import com.bankaudit.model.MaintHealthIndexHst;
import com.bankaudit.model.MaintHealthIndexWrk;

@Service("maintHealthIndexService")
@Transactional("transactionManager")
public class MaintHealthIndexServiceImpl implements MaintHealthIndexService{
	
	@Autowired
	MaintHealthIndexDao maintHealthIndexDao;
	
	/**
	 * The business date service is autowired and make methods available from
	 * dao layer .
	 */
	@Autowired
	BusinessDateService businessDateService;
	@SuppressWarnings("unchecked")
	@Override
	public List<MaintHealthIndex> getMaintHealthIndexs() {
		return maintHealthIndexDao.getAll(MaintHealthIndex.class);
	}

	@Override
	public List<MaintHealthIndex> getMaintHealthIndexsExceptThis(Integer legalEntityCode, String healthIndexCode) {

		return maintHealthIndexDao.getMaintHealthIndexsExceptThis( legalEntityCode, healthIndexCode);
	}


	@Override
	public MaintHealthIndex getMaintHealthIndex(Integer legalEntityCode, String healthIndexCode,	String status) {
		Map<String , Object> properties=new HashMap<String, Object>();
		properties.put("legalEntityCode", legalEntityCode);
		properties.put("healthIndexCode", healthIndexCode);
		
		if(!BankAuditConstant.STATUS_AUTH.equalsIgnoreCase(status)){
			
			MaintHealthIndex maintHealthIndex=null;
			
			MaintHealthIndexWrk maintHealthIndexWrk=(MaintHealthIndexWrk)maintHealthIndexDao.getUniqueEntityByMatchingProperties(MaintHealthIndexWrk.class, properties);

			if(maintHealthIndexWrk!=null){
				maintHealthIndex=new MaintHealthIndex();
				BeanUtils.copyProperties(maintHealthIndexWrk, maintHealthIndex);
			}
			
			return maintHealthIndex;
			
		}else {
			return (MaintHealthIndex)maintHealthIndexDao.getUniqueEntityByMatchingProperties(MaintHealthIndex.class, properties);
		}
		
	}
	
	@Override
	public DataTableResponse getMaintHealthIndexs(Integer legalEntityCode, String search, Integer orderColumn,
			String orderDirection, Integer page, Integer size) {
		return maintHealthIndexDao.getMaintHealthIndexs( legalEntityCode,  search,  orderColumn,
				 orderDirection,  page,  size);
	}
	
	@Override
	public List<MaintHealthIndex> getMaintHealthIndexforUpdate(Integer legalEntityCode, String status){
		Map<String,Object> properties=new HashMap<String,Object>();
		properties.put("legalEntityCode", legalEntityCode);
		if(!BankAuditConstant.STATUS_AUTH.equalsIgnoreCase(status)){
			List temp2=new ArrayList<>();
			List<MaintHealthIndexWrk> temp1=maintHealthIndexDao.getEntitiesByMatchingProperties(MaintHealthIndexWrk.class, properties);
			
			List result = temp1.stream()
					.filter(o1 -> !o1.getStatus().equalsIgnoreCase("D"))
					.sorted((o1, o2)->Integer.compare( o1.getMinimunPer().intValue(),o2.getMinimunPer().intValue()))
					.collect(Collectors.toList());
			
			/*if(result!=null){
				for (MaintHealthIndexWrk maintHealthIndexWrk : result) {
					if(!maintHealthIndexWrk.getStatus().equalsIgnoreCase("D")){
						temp2.add(maintHealthIndexWrk);
					}
				}
			}*/
			//return temp2;		
			return result;
		}else {
			List<MaintHealthIndex> temp1= maintHealthIndexDao.getEntitiesByMatchingProperties(MaintHealthIndex.class, properties);	
			
			return temp1.stream()
					.filter(o1 -> !o1.getStatus().equalsIgnoreCase("D"))
					.sorted((o1, o2)->Integer.compare( o1.getMinimunPer().intValue(),o2.getMinimunPer().intValue()))
					.collect(Collectors.toList());
		}
	}

	@Override
	public void createMaintHealthIndex(List<MaintHealthIndex> maintHealthIndexs)throws Exception {
		
		if(maintHealthIndexs.get(0).getStatus().equalsIgnoreCase(BankAuditConstant.STATUS_UNAUTH)){
			MaintHealthIndexWrk maintHealthIndexWrk=null;
			for (MaintHealthIndex maintHealthIndex : maintHealthIndexs) {
				maintHealthIndexWrk=new MaintHealthIndexWrk();
				BeanUtils.copyProperties(maintHealthIndex,maintHealthIndexWrk);
				maintHealthIndexDao.save(maintHealthIndexWrk);
			}
			
		}else if (maintHealthIndexs.get(0).getStatus().equalsIgnoreCase(BankAuditConstant.STATUS_AUTH)) {
			for (MaintHealthIndex maintHealthIndex : maintHealthIndexs) {
				maintHealthIndexDao.save(maintHealthIndex);
			}
		}else{
			throw new Exception("invalid status");
		}
	}

	@Override
	public void updateMaintHealthIndexs(List<MaintHealthIndex> maintHealthIndexs) {
		if(!maintHealthIndexs.get(0).getStatus().equalsIgnoreCase(BankAuditConstant.STATUS_AUTH)){
			// get Db object and save into the history
			List<MaintHealthIndex> scorePercentagesDb=
					getMaintHealthIndexforUpdate(maintHealthIndexs.get(0).getLegalEntityCode(), BankAuditConstant.STATUS_UNAUTH);
			if(scorePercentagesDb!=null && !scorePercentagesDb.isEmpty()){
				MaintHealthIndexHst maintHealthIndexHst=null;
				for (Object maintHealthIndex : scorePercentagesDb) {
					maintHealthIndexHst=new MaintHealthIndexHst();
					BeanUtils.copyProperties(maintHealthIndex,maintHealthIndexHst);
					maintHealthIndexDao.save(maintHealthIndexHst);
				}
				
			}
			// update or save wrk 
			MaintHealthIndexWrk maintHealthIndexWrk=null;
			for (MaintHealthIndex maintHealthIndex : maintHealthIndexs) {
				maintHealthIndexWrk=new MaintHealthIndexWrk();
				BeanUtils.copyProperties(maintHealthIndex,maintHealthIndexWrk);
				maintHealthIndexDao.flushSession();
				maintHealthIndexWrk.setMakerTimestamp(businessDateService.getBusinessDateTimestampByLegalEntityCode(maintHealthIndexWrk.getLegalEntityCode()));
				maintHealthIndexDao.saveOrUpdate(maintHealthIndexWrk);
			}
			
		}else{
			// get Db object and save into the history
			List<MaintHealthIndex> scorePercentagesDb=
					getMaintHealthIndexforUpdate(maintHealthIndexs.get(0).getLegalEntityCode(), BankAuditConstant.STATUS_AUTH);
			if(scorePercentagesDb!=null && !scorePercentagesDb.isEmpty()){
				MaintHealthIndexHst maintHealthIndexHst=null;
				for (Object maintHealthIndex : scorePercentagesDb) {
					maintHealthIndexHst=new MaintHealthIndexHst();
					BeanUtils.copyProperties(maintHealthIndex,maintHealthIndexHst);
					maintHealthIndexDao.save(maintHealthIndexHst);
				}
				
			}
			
			maintHealthIndexDao.deleteMaintHealthIndexs(maintHealthIndexs.get(0).getLegalEntityCode(),BankAuditConstant.STATUS_UNAUTH);
			maintHealthIndexDao.deleteMaintHealthIndexs(maintHealthIndexs.get(0).getLegalEntityCode(),BankAuditConstant.STATUS_AUTH);
			
			
			for (MaintHealthIndex maintHealthIndex : maintHealthIndexs) {
				maintHealthIndexDao.flushSession();
				maintHealthIndexDao.save(maintHealthIndex);
			}
			 
		}
	}

	@Override
	public Boolean isMaintHealthIndex(Integer legalEntityCode) {
		
		return  maintHealthIndexDao.isMaintHealthIndex( legalEntityCode);
	}
	
	@Override
	public MaintHealthIndex getHealthIndexOnPercentage(Integer legalEntityCode, Integer riskScore) {
		
		return  maintHealthIndexDao.getHealthIndexOnPercentage( legalEntityCode,  riskScore);
	}

	@Override
	public Boolean isHealthIndexCode(Integer legalEntityCode, String healthIndexCode) {
		return maintHealthIndexDao.isHealthIndexCode( legalEntityCode,   healthIndexCode);
	}
}
