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.MaintControlClssfcBucketDao;
import com.bankaudit.dto.DataTableResponse;
import com.bankaudit.model.MaintControlClssfcBucket;
import com.bankaudit.model.MaintControlClssfcBucketHst;
import com.bankaudit.model.MaintControlClssfcBucketWrk;

@Service("maintControlClssfcBucketService")
@Transactional("transactionManager")
public class MaintControlClssfcBucketServiceImpl implements MaintControlClssfcBucketService {
	
	@Autowired
	MaintControlClssfcBucketDao maintControlClssfcBucketDao;
	
	/**
	 * The business date service is autowired and make methods available from
	 * dao layer .
	 */
	@Autowired
	BusinessDateService businessDateService;
	@SuppressWarnings("unchecked")
	@Override
	public List<MaintControlClssfcBucket> getMaintControlClssfcBuckets() {
		return maintControlClssfcBucketDao.getAll(MaintControlClssfcBucket.class);
	}

	@Override
	public List<MaintControlClssfcBucket> getMaintControlClssfcBucketsExceptThis(Integer legalEntityCode, String controlClssfcBucketCode) {

		return maintControlClssfcBucketDao.getMaintControlClssfcBucketsExceptThis( legalEntityCode, controlClssfcBucketCode);
	}


	@Override
	public MaintControlClssfcBucket getMaintControlClssfcBucket(Integer legalEntityCode, String controlClssfcBucketCode,	String status) {
		Map<String , Object> properties=new HashMap<String, Object>();
		properties.put("legalEntityCode", legalEntityCode);
		properties.put("controlClssfcBucketCode", controlClssfcBucketCode);
		
		if(!BankAuditConstant.STATUS_AUTH.equalsIgnoreCase(status)){
			
			MaintControlClssfcBucket maintControlClssfcBucket=null;
			
			MaintControlClssfcBucketWrk maintControlClssfcBucketWrk=(MaintControlClssfcBucketWrk)maintControlClssfcBucketDao.getUniqueEntityByMatchingProperties(MaintControlClssfcBucketWrk.class, properties);

			if(maintControlClssfcBucketWrk!=null){
				maintControlClssfcBucket=new MaintControlClssfcBucket();
				BeanUtils.copyProperties(maintControlClssfcBucketWrk, maintControlClssfcBucket);
			}
			
			return maintControlClssfcBucket;
			
		}else {
			return (MaintControlClssfcBucket)maintControlClssfcBucketDao.getUniqueEntityByMatchingProperties(MaintControlClssfcBucket.class, properties);
		}
		
	}
	
	@Override
	public DataTableResponse getMaintControlClssfcBuckets(Integer legalEntityCode, String search, Integer orderColumn,
			String orderDirection, Integer page, Integer size) {
		return maintControlClssfcBucketDao.getMaintControlClssfcBuckets( legalEntityCode,  search,  orderColumn,
				 orderDirection,  page,  size);
	}
	
	@Override
	public List<MaintControlClssfcBucket> getMaintControlClssfcBucketforUpdate(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<MaintControlClssfcBucketWrk> temp1=maintControlClssfcBucketDao.getEntitiesByMatchingProperties(MaintControlClssfcBucketWrk.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 (MaintControlClssfcBucketWrk maintControlClssfcBucketWrk : result) {
					if(!maintControlClssfcBucketWrk.getStatus().equalsIgnoreCase("D")){
						temp2.add(maintControlClssfcBucketWrk);
					}
				}
			}*/
			//return temp2;		
			return result;
		}else {
			List<MaintControlClssfcBucket> temp1= maintControlClssfcBucketDao.getEntitiesByMatchingProperties(MaintControlClssfcBucket.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 createMaintControlClssfcBucket(List<MaintControlClssfcBucket> maintControlClssfcBuckets)throws Exception {
		
		if(maintControlClssfcBuckets.get(0).getStatus().equalsIgnoreCase(BankAuditConstant.STATUS_UNAUTH)){
			MaintControlClssfcBucketWrk maintControlClssfcBucketWrk=null;
			for (MaintControlClssfcBucket maintControlClssfcBucket : maintControlClssfcBuckets) {
				maintControlClssfcBucketWrk=new MaintControlClssfcBucketWrk();
				BeanUtils.copyProperties(maintControlClssfcBucket,maintControlClssfcBucketWrk);
				maintControlClssfcBucketDao.save(maintControlClssfcBucketWrk);
			}
			
		}else if (maintControlClssfcBuckets.get(0).getStatus().equalsIgnoreCase(BankAuditConstant.STATUS_AUTH)) {
			for (MaintControlClssfcBucket maintControlClssfcBucket : maintControlClssfcBuckets) {
				maintControlClssfcBucketDao.save(maintControlClssfcBucket);
			}
		}else{
			throw new Exception("invalid status");
		}
	}

	@Override
	public void updateMaintControlClssfcBuckets(List<MaintControlClssfcBucket> maintControlClssfcBuckets) {
		if(!maintControlClssfcBuckets.get(0).getStatus().equalsIgnoreCase(BankAuditConstant.STATUS_AUTH)){
			// get Db object and save into the history
			List<MaintControlClssfcBucket> scorePercentagesDb=
					getMaintControlClssfcBucketforUpdate(maintControlClssfcBuckets.get(0).getLegalEntityCode(), BankAuditConstant.STATUS_UNAUTH);
			if(scorePercentagesDb!=null && !scorePercentagesDb.isEmpty()){
				MaintControlClssfcBucketHst maintControlClssfcBucketHst=null;
				for (Object maintControlClssfcBucket : scorePercentagesDb) {
					maintControlClssfcBucketHst=new MaintControlClssfcBucketHst();
					BeanUtils.copyProperties(maintControlClssfcBucket,maintControlClssfcBucketHst);
					maintControlClssfcBucketDao.save(maintControlClssfcBucketHst);
				}
				
			}
			// update or save wrk 
			MaintControlClssfcBucketWrk maintControlClssfcBucketWrk=null;
			for (MaintControlClssfcBucket maintControlClssfcBucket : maintControlClssfcBuckets) {
				maintControlClssfcBucketWrk=new MaintControlClssfcBucketWrk();
				BeanUtils.copyProperties(maintControlClssfcBucket,maintControlClssfcBucketWrk);
				maintControlClssfcBucketDao.flushSession();
				maintControlClssfcBucketWrk.setMakerTimestamp(businessDateService.getBusinessDateTimestampByLegalEntityCode(maintControlClssfcBucketWrk.getLegalEntityCode()));
				maintControlClssfcBucketDao.saveOrUpdate(maintControlClssfcBucketWrk);
			}
			
		}else{
			// get Db object and save into the history
			List<MaintControlClssfcBucket> scorePercentagesDb=
					getMaintControlClssfcBucketforUpdate(maintControlClssfcBuckets.get(0).getLegalEntityCode(), BankAuditConstant.STATUS_AUTH);
			if(scorePercentagesDb!=null && !scorePercentagesDb.isEmpty()){
				MaintControlClssfcBucketHst maintControlClssfcBucketHst=null;
				for (Object maintControlClssfcBucket : scorePercentagesDb) {
					maintControlClssfcBucketHst=new MaintControlClssfcBucketHst();
					BeanUtils.copyProperties(maintControlClssfcBucket,maintControlClssfcBucketHst);
					maintControlClssfcBucketDao.save(maintControlClssfcBucketHst);
				}
				
			}
			
			maintControlClssfcBucketDao.deleteMaintControlClssfcBuckets(maintControlClssfcBuckets.get(0).getLegalEntityCode(),BankAuditConstant.STATUS_UNAUTH);
			maintControlClssfcBucketDao.deleteMaintControlClssfcBuckets(maintControlClssfcBuckets.get(0).getLegalEntityCode(),BankAuditConstant.STATUS_AUTH);
			
			
			for (MaintControlClssfcBucket maintControlClssfcBucket : maintControlClssfcBuckets) {
				maintControlClssfcBucketDao.flushSession();
				maintControlClssfcBucketDao.save(maintControlClssfcBucket);
			}
			 
		}
	}

	@Override
	public Boolean isMaintControlClssfcBucket(Integer legalEntityCode) {
		
		return  maintControlClssfcBucketDao.isMaintControlClssfcBucket( legalEntityCode);
	}
	
	@Override
	public MaintControlClssfcBucket getControlClssfcBucketOnPercentage(Integer legalEntityCode, Integer riskScore) {
		
		return  maintControlClssfcBucketDao.getControlClssfcBucketOnPercentage( legalEntityCode,  riskScore);
	}

	@Override
	public Boolean isControlClssfcBucketCode(Integer legalEntityCode, String controlClssfcBucketCode) {
		return maintControlClssfcBucketDao.isControlClssfcBucketCode( legalEntityCode,   controlClssfcBucketCode);
	}
}
