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.MaintResidualRiskDao;
import com.bankaudit.dto.DataTableResponse;
import com.bankaudit.model.MaintResidualRisk;
import com.bankaudit.model.MaintResidualRiskHst;
import com.bankaudit.model.MaintResidualRiskWrk;

@Service("maintResidualRiskService")
@Transactional("transactionManager")
public class MaintResidualRiskServiceImpl  implements MaintResidualRiskService{
	
	@Autowired
	MaintResidualRiskDao maintResidualRiskDao;
	
	@Autowired
	BusinessDateService businessDateService;
	@SuppressWarnings("unchecked")
	@Override
	public List<MaintResidualRisk> getMaintResidualRisks() {
		return maintResidualRiskDao.getAll(MaintResidualRisk.class);
	}

	@Override
	public List<MaintResidualRisk> getMaintResidualRisksExceptThis(Integer legalEntityCode, String residualRiskCode) {

		return maintResidualRiskDao.getMaintResidualRisksExceptThis( legalEntityCode, residualRiskCode);
	}


	@Override
	public MaintResidualRisk getMaintResidualRisk(Integer legalEntityCode, String residualRiskCode,	String status) {
		Map<String , Object> properties=new HashMap<String, Object>();
		properties.put("legalEntityCode", legalEntityCode);
		properties.put("residualRiskCode", residualRiskCode);
		
		if(!BankAuditConstant.STATUS_AUTH.equalsIgnoreCase(status)){
			
			MaintResidualRisk maintResidualRisk=null;
			
			MaintResidualRiskWrk maintResidualRiskWrk=(MaintResidualRiskWrk)maintResidualRiskDao.getUniqueEntityByMatchingProperties(MaintResidualRiskWrk.class, properties);

			if(maintResidualRiskWrk!=null){
				maintResidualRisk=new MaintResidualRisk();
				BeanUtils.copyProperties(maintResidualRiskWrk, maintResidualRisk);
			}
			
			return maintResidualRisk;
			
		}else {
			return (MaintResidualRisk)maintResidualRiskDao.getUniqueEntityByMatchingProperties(MaintResidualRisk.class, properties);
		}
		
	}
	
	@Override
	public DataTableResponse getMaintResidualRisks(Integer legalEntityCode, String search, Integer orderColumn,
			String orderDirection, Integer page, Integer size) {
		return maintResidualRiskDao.getMaintResidualRisks( legalEntityCode,  search,  orderColumn,
				 orderDirection,  page,  size);
	}
	
	@Override
	public List<MaintResidualRisk> getMaintResidualRiskforUpdate(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<MaintResidualRiskWrk> temp1=maintResidualRiskDao.getEntitiesByMatchingProperties(MaintResidualRiskWrk.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 (MaintResidualRiskWrk maintResidualRiskWrk : result) {
					if(!maintResidualRiskWrk.getStatus().equalsIgnoreCase("D")){
						temp2.add(maintResidualRiskWrk);
					}
				}
			}*/
			//return temp2;		
			return result;
		}else {
			List<MaintResidualRisk> temp1= maintResidualRiskDao.getEntitiesByMatchingProperties(MaintResidualRisk.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 createMaintResidualRisk(List<MaintResidualRisk> maintResidualRisks)throws Exception {
		
		if(maintResidualRisks.get(0).getStatus().equalsIgnoreCase(BankAuditConstant.STATUS_UNAUTH)){
			MaintResidualRiskWrk maintResidualRiskWrk=null;
			for (MaintResidualRisk maintResidualRisk : maintResidualRisks) {
				maintResidualRiskWrk=new MaintResidualRiskWrk();
				BeanUtils.copyProperties(maintResidualRisk,maintResidualRiskWrk);
				maintResidualRiskDao.save(maintResidualRiskWrk);
			}
			
		}else if (maintResidualRisks.get(0).getStatus().equalsIgnoreCase(BankAuditConstant.STATUS_AUTH)) {
			for (MaintResidualRisk maintResidualRisk : maintResidualRisks) {
				maintResidualRiskDao.save(maintResidualRisk);
			}
		}else{
			throw new Exception("invalid status");
		}
	}

	@Override
	public void updateMaintResidualRisks(List<MaintResidualRisk> maintResidualRisks) {
		if(!maintResidualRisks.get(0).getStatus().equalsIgnoreCase(BankAuditConstant.STATUS_AUTH)){
			// get Db object and save into the history
			List<MaintResidualRisk> scorePercentagesDb=
					getMaintResidualRiskforUpdate(maintResidualRisks.get(0).getLegalEntityCode(), BankAuditConstant.STATUS_UNAUTH);
			if(scorePercentagesDb!=null && !scorePercentagesDb.isEmpty()){
				MaintResidualRiskHst maintResidualRiskHst=null;
				for (Object maintResidualRisk : scorePercentagesDb) {
					maintResidualRiskHst=new MaintResidualRiskHst();
					BeanUtils.copyProperties(maintResidualRisk,maintResidualRiskHst);
					maintResidualRiskDao.save(maintResidualRiskHst);
				}
				
			}
			// update or save wrk 
			MaintResidualRiskWrk maintResidualRiskWrk=null;
			for (MaintResidualRisk maintResidualRisk : maintResidualRisks) {
				maintResidualRiskWrk=new MaintResidualRiskWrk();
				BeanUtils.copyProperties(maintResidualRisk,maintResidualRiskWrk);
				maintResidualRiskDao.flushSession();
				maintResidualRiskWrk.setMakerTimestamp(businessDateService.getBusinessDateTimestampByLegalEntityCode(maintResidualRiskWrk.getLegalEntityCode()));
				maintResidualRiskDao.saveOrUpdate(maintResidualRiskWrk);
			}
			
		}else{
			// get Db object and save into the history
			List<MaintResidualRisk> scorePercentagesDb=
					getMaintResidualRiskforUpdate(maintResidualRisks.get(0).getLegalEntityCode(), BankAuditConstant.STATUS_AUTH);
			if(scorePercentagesDb!=null && !scorePercentagesDb.isEmpty()){
				MaintResidualRiskHst maintResidualRiskHst=null;
				for (Object maintResidualRisk : scorePercentagesDb) {
					maintResidualRiskHst=new MaintResidualRiskHst();
					BeanUtils.copyProperties(maintResidualRisk,maintResidualRiskHst);
					maintResidualRiskDao.save(maintResidualRiskHst);
				}
				
			}
			
			maintResidualRiskDao.deleteMaintResidualRisks(maintResidualRisks.get(0).getLegalEntityCode(),BankAuditConstant.STATUS_UNAUTH);
			maintResidualRiskDao.deleteMaintResidualRisks(maintResidualRisks.get(0).getLegalEntityCode(),BankAuditConstant.STATUS_AUTH);
			
			
			for (MaintResidualRisk maintResidualRisk : maintResidualRisks) {
				maintResidualRiskDao.flushSession();
				maintResidualRiskDao.save(maintResidualRisk);
			}
			 
		}
	}

	@Override
	public Boolean isMaintResidualRisk(Integer legalEntityCode) {
		
		return  maintResidualRiskDao.isMaintResidualRisk( legalEntityCode);
	}
	
	@Override
	public MaintResidualRisk getResidualRiskOnPercentage(Integer legalEntityCode, Integer riskScore) {
		
		return  maintResidualRiskDao.getResidualRiskOnPercentage( legalEntityCode,  riskScore);
	}

	@Override
	public Boolean isResidualRiskCode(Integer legalEntityCode, String residualRiskCode) {
		return maintResidualRiskDao.isResidualRiskCode( legalEntityCode,   residualRiskCode);
	}
}
