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.MaintInherentRiskDao;
import com.bankaudit.dto.DataTableResponse;
import com.bankaudit.model.MaintInherentRisk;
import com.bankaudit.model.MaintInherentRiskHst;
import com.bankaudit.model.MaintInherentRiskWrk;

@Service("maintInherentRiskService")
@Transactional("transactionManager")
public class MaintInherentRiskServiceImpl implements MaintInherentRiskService {
	@Autowired
	MaintInherentRiskDao maintInherentRiskDao;
	
	/**
	 * The business date service is autowired and make methods available from
	 * dao layer .
	 */
	@Autowired
	BusinessDateService businessDateService;
	@SuppressWarnings("unchecked")
	@Override
	public List<MaintInherentRisk> getMaintInherentRisks() {
		return maintInherentRiskDao.getAll(MaintInherentRisk.class);
	}

	@Override
	public List<MaintInherentRisk> getMaintInherentRisksExceptThis(Integer legalEntityCode, String inherentRiskCode) {

		return maintInherentRiskDao.getMaintInherentRisksExceptThis( legalEntityCode, inherentRiskCode);
	}


	@Override
	public MaintInherentRisk getMaintInherentRisk(Integer legalEntityCode, String inherentRiskCode,	String status) {
		Map<String , Object> properties=new HashMap<String, Object>();
		properties.put("legalEntityCode", legalEntityCode);
		properties.put("inherentRiskCode", inherentRiskCode);
		
		if(!BankAuditConstant.STATUS_AUTH.equalsIgnoreCase(status)){
			
			MaintInherentRisk maintInherentRisk=null;
			
			MaintInherentRiskWrk maintInherentRiskWrk=(MaintInherentRiskWrk)maintInherentRiskDao.getUniqueEntityByMatchingProperties(MaintInherentRiskWrk.class, properties);

			if(maintInherentRiskWrk!=null){
				maintInherentRisk=new MaintInherentRisk();
				BeanUtils.copyProperties(maintInherentRiskWrk, maintInherentRisk);
			}
			
			return maintInherentRisk;
			
		}else {
			return (MaintInherentRisk)maintInherentRiskDao.getUniqueEntityByMatchingProperties(MaintInherentRisk.class, properties);
		}
		
	}
	
	@Override
	public DataTableResponse getMaintInherentRisks(Integer legalEntityCode, String search, Integer orderColumn,
			String orderDirection, Integer page, Integer size) {
		return maintInherentRiskDao.getMaintInherentRisks( legalEntityCode,  search,  orderColumn,
				 orderDirection,  page,  size);
	}
	
	@Override
	public List<MaintInherentRisk> getMaintInherentRiskforUpdate(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<MaintInherentRiskWrk> temp1=maintInherentRiskDao.getEntitiesByMatchingProperties(MaintInherentRiskWrk.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 (MaintInherentRiskWrk maintInherentRiskWrk : result) {
					if(!maintInherentRiskWrk.getStatus().equalsIgnoreCase("D")){
						temp2.add(maintInherentRiskWrk);
					}
				}
			}*/
			//return temp2;		
			return result;
		}else {
			List<MaintInherentRisk> temp1= maintInherentRiskDao.getEntitiesByMatchingProperties(MaintInherentRisk.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 createMaintInherentRisk(List<MaintInherentRisk> maintInherentRisks)throws Exception {
		
		if(maintInherentRisks.get(0).getStatus().equalsIgnoreCase(BankAuditConstant.STATUS_UNAUTH)){
			MaintInherentRiskWrk maintInherentRiskWrk=null;
			for (MaintInherentRisk maintInherentRisk : maintInherentRisks) {
				maintInherentRiskWrk=new MaintInherentRiskWrk();
				BeanUtils.copyProperties(maintInherentRisk,maintInherentRiskWrk);
				maintInherentRiskDao.save(maintInherentRiskWrk);
			}
			
		}else if (maintInherentRisks.get(0).getStatus().equalsIgnoreCase(BankAuditConstant.STATUS_AUTH)) {
			for (MaintInherentRisk maintInherentRisk : maintInherentRisks) {
				maintInherentRiskDao.save(maintInherentRisk);
			}
		}else{
			throw new Exception("invalid status");
		}
	}

	@Override
	public void updateMaintInherentRisks(List<MaintInherentRisk> maintInherentRisks) {
		if(!maintInherentRisks.get(0).getStatus().equalsIgnoreCase(BankAuditConstant.STATUS_AUTH)){
			// get Db object and save into the history
			List<MaintInherentRisk> scorePercentagesDb=
					getMaintInherentRiskforUpdate(maintInherentRisks.get(0).getLegalEntityCode(), BankAuditConstant.STATUS_UNAUTH);
			if(scorePercentagesDb!=null && !scorePercentagesDb.isEmpty()){
				MaintInherentRiskHst maintInherentRiskHst=null;
				for (Object maintInherentRisk : scorePercentagesDb) {
					maintInherentRiskHst=new MaintInherentRiskHst();
					BeanUtils.copyProperties(maintInherentRisk,maintInherentRiskHst);
					maintInherentRiskDao.save(maintInherentRiskHst);
				}
				
			}
			// update or save wrk 
			MaintInherentRiskWrk maintInherentRiskWrk=null;
			for (MaintInherentRisk maintInherentRisk : maintInherentRisks) {
				maintInherentRiskWrk=new MaintInherentRiskWrk();
				BeanUtils.copyProperties(maintInherentRisk,maintInherentRiskWrk);
				maintInherentRiskDao.flushSession();
				maintInherentRiskWrk.setMakerTimestamp(businessDateService.getBusinessDateTimestampByLegalEntityCode(maintInherentRiskWrk.getLegalEntityCode()));
				maintInherentRiskDao.saveOrUpdate(maintInherentRiskWrk);
			}
			
		}else{
			// get Db object and save into the history
			List<MaintInherentRisk> scorePercentagesDb=
					getMaintInherentRiskforUpdate(maintInherentRisks.get(0).getLegalEntityCode(), BankAuditConstant.STATUS_AUTH);
			if(scorePercentagesDb!=null && !scorePercentagesDb.isEmpty()){
				MaintInherentRiskHst maintInherentRiskHst=null;
				for (Object maintInherentRisk : scorePercentagesDb) {
					maintInherentRiskHst=new MaintInherentRiskHst();
					BeanUtils.copyProperties(maintInherentRisk,maintInherentRiskHst);
					maintInherentRiskDao.save(maintInherentRiskHst);
				}
				
			}
			
			maintInherentRiskDao.deleteMaintInherentRisks(maintInherentRisks.get(0).getLegalEntityCode(),BankAuditConstant.STATUS_UNAUTH);
			maintInherentRiskDao.deleteMaintInherentRisks(maintInherentRisks.get(0).getLegalEntityCode(),BankAuditConstant.STATUS_AUTH);
			
			
			for (MaintInherentRisk maintInherentRisk : maintInherentRisks) {
				maintInherentRiskDao.flushSession();
				maintInherentRiskDao.save(maintInherentRisk);
			}
			 
		}
	}

	@Override
	public Boolean isMaintInherentRisk(Integer legalEntityCode) {
		
		return  maintInherentRiskDao.isMaintInherentRisk( legalEntityCode);
	}
	
	@Override
	public MaintInherentRisk getInherentRiskOnPercentage(Integer legalEntityCode, Integer riskScore) {
		
		return  maintInherentRiskDao.getInherentRiskOnPercentage( legalEntityCode,  riskScore);
	}

	@Override
	public Boolean isInherentRiskCode(Integer legalEntityCode, String inherentRiskCode) {
		return maintInherentRiskDao.isInherentRiskCode( legalEntityCode,   inherentRiskCode);
	}
}
