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

import java.util.Comparator;
import java.util.List;
import java.util.stream.Collector;
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.RiskScoreAuditGrpDao;
import com.bankaudit.dto.DataTableResponse;
import com.bankaudit.model.RiskScoreAuditGrp;
import com.bankaudit.model.RiskScoreAuditGrpHst;
import com.bankaudit.model.RiskScoreAuditGrpWrk;
import com.bankaudit.model.RiskScoreAuditSubgrp;
import com.bankaudit.model.RiskScoreAuditSubgrpHst;
import com.bankaudit.model.RiskScoreAuditSubgrpWrk;

/**
 * The Class {@link RiskScoreAuditGrpServiceIml} Implements the business logic
 * method.
 *
 * @author amit.patel
 * @version 1.0
 */
@Service("riskScoreAuditGrpService")
@Transactional("transactionManager")
public class RiskScoreAuditGrpServiceIml implements RiskScoreAuditGrpService{

	
	/**
	 * The risk score audit grp dao is autowired and make methods available from
	 * dao layer .
	 */
	@Autowired
	RiskScoreAuditGrpDao riskScoreAuditGrpDao;
	
	/**
	 * The risk score audit subgrp service is autowired and make methods
	 * available from dao layer .
	 */
	@Autowired
	RiskScoreAuditSubgrpService riskScoreAuditSubgrpService;
	
	/**
	 * The business date service is autowired and make methods available from
	 * dao layer .
	 */
	@Autowired
	BusinessDateService businessDateService;
	

	/* (non-Javadoc)
	 * @see com.bankaudit.service.RiskScoreAuditGrpService#updateRiskScoreAuditGrp(com.bankaudit.model.RiskScoreAuditGrp)
	 */
	@Override
	public void updateRiskScoreAuditGrp(RiskScoreAuditGrp riskScoreAuditGrp) {
		riskScoreAuditGrpDao.update(riskScoreAuditGrp);
	}

	/* (non-Javadoc)
	 * @see com.bankaudit.service.RiskScoreAuditGrpService#getRiskScoreAuditGrp(java.lang.Integer, java.lang.String, java.lang.String)
	 */
	@Override
	public List<RiskScoreAuditGrp> getRiskScoreAuditGrp(Integer legalEntityCode, String auditGroupCode,
			String auditTypeCode) {
	    return riskScoreAuditGrpDao.getRiskScoreAuditGrp( legalEntityCode,  auditGroupCode,
				 auditTypeCode);
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<RiskScoreAuditGrp> getRiskScoreAuditGrps() {
		return riskScoreAuditGrpDao.getAll(RiskScoreAuditGrp.class);
	}

	/* (non-Javadoc)
	 * @see com.bankaudit.service.RiskScoreAuditGrpService#createRiskScoreAuditGrp(java.util.List)
	 */
	@Override
	public void createRiskScoreAuditGrp(List<RiskScoreAuditGrp> riskScoreAuditGrps) throws Exception {
		
		if(riskScoreAuditGrps.get(0).getStatus().equalsIgnoreCase(BankAuditConstant.STATUS_UNAUTH)){
			RiskScoreAuditGrpWrk riskScoreAuditGrpWrk=null;
			RiskScoreAuditSubgrpWrk riskScoreAuditSubgrpWrk=null; 
		
			for (RiskScoreAuditGrp riskScoreAuditGrp : riskScoreAuditGrps) {
				riskScoreAuditGrpWrk  = new RiskScoreAuditGrpWrk();
				BeanUtils.copyProperties(riskScoreAuditGrp, riskScoreAuditGrpWrk);
				riskScoreAuditGrpDao.flushSession();
				riskScoreAuditGrpDao.save(riskScoreAuditGrpWrk);
				for (RiskScoreAuditSubgrp riskScoreAuditSubgrp : riskScoreAuditGrp.getRiskScoreAuditSubgrps()) {
					riskScoreAuditSubgrpWrk  = new RiskScoreAuditSubgrpWrk();
					BeanUtils.copyProperties(riskScoreAuditSubgrp, riskScoreAuditSubgrpWrk);
					riskScoreAuditGrpDao.save(riskScoreAuditSubgrpWrk);
				}
				
			}
		}else if (riskScoreAuditGrps.get(0).getStatus().equalsIgnoreCase(BankAuditConstant.STATUS_AUTH)) {
		
			for (RiskScoreAuditGrp riskScoreAuditGrp : riskScoreAuditGrps) {
				riskScoreAuditGrpDao.save(riskScoreAuditGrp);
				for (RiskScoreAuditSubgrp riskScoreAuditSubgrp : riskScoreAuditGrp.getRiskScoreAuditSubgrps()) {
					riskScoreAuditGrpDao.save(riskScoreAuditSubgrp);
				}
				
			}
		
		}else{
			throw new Exception("invalid status");
		}
	}

	/* (non-Javadoc)
	 * @see com.bankaudit.service.RiskScoreAuditGrpService#updateRiskScoreAuditGrp(java.util.List)
	 */
	@Transactional(value="transactionManager")
	@Override
	public void updateRiskScoreAuditGrp(List<RiskScoreAuditGrp> riskScoreAuditGrps) {
		

		if(!riskScoreAuditGrps.get(0).getStatus().equalsIgnoreCase(BankAuditConstant.STATUS_AUTH)){
			
		/*	you have to set maker date 
		 * 
		 * if(riskScoreAuditGrps.get(0).getStatus().equalsIgnoreCase(BankAuditConstant.STATUS_UNAUTH)
					|| riskScoreAuditGrps.get(0).getStatus().equalsIgnoreCase(BankAuditConstant.STATUS_MOD)){
				maintCriticality.setMakerTimestamp(businessDateService.getBusinessDateTimestampByLegalEntityCode(maintCriticality.getLegalEntityCode()));
			}*/
			// get Db object and save into the history
			List<RiskScoreAuditGrp> riskScoreAuditGrpsDb=
					getRiskScoreAuditGrpByLegalEntityCodeAndAuditTypeCode(riskScoreAuditGrps.get(0).getLegalEntityCode(), riskScoreAuditGrps.get(0).getAuditTypeCode() , BankAuditConstant.STATUS_UNAUTH);
			//if(riskScoreAuditGrpsDb!=null ){
			
			// Commented to avoid save data into history table
			/*if(riskScoreAuditGrpsDb!=null && riskScoreAuditGrpsDb.size() > 0 && riskScoreAuditGrpsDb.get(0).getWeightage() !=null){
				riskScoreAuditGrpDao.flushSession();
				RiskScoreAuditGrpHst riskScoreAuditGrpHst=null;
				RiskScoreAuditSubgrpHst riskScoreAuditSubgrpHst=null; 
				for (RiskScoreAuditGrp riskScoreAuditGrp : riskScoreAuditGrpsDb) {
					riskScoreAuditGrpHst  = new RiskScoreAuditGrpHst();
					String[] ignoreProperties={
							"riskScoreAuditSubgrps"
					};
					BeanUtils.copyProperties(riskScoreAuditGrp, riskScoreAuditGrpHst,ignoreProperties);
					riskScoreAuditGrpHst.setAuditGroupCode(riskScoreAuditGrpHst.getAuditGroupCode()!=null ? riskScoreAuditGrpHst.getAuditGroupCode().split("-")[0] : null);
					riskScoreAuditGrpHst.setAuditTypeCode(riskScoreAuditGrpHst.getAuditTypeCode()!=null ? riskScoreAuditGrpHst.getAuditTypeCode().split("-")[0] : null);
					riskScoreAuditGrpDao.save(riskScoreAuditGrpHst);
					for (RiskScoreAuditSubgrp riskScoreAuditSubgrp : riskScoreAuditGrp.getRiskScoreAuditSubgrps()) {
						riskScoreAuditSubgrpHst  = new RiskScoreAuditSubgrpHst();
						BeanUtils.copyProperties(riskScoreAuditSubgrp, riskScoreAuditSubgrpHst);
						riskScoreAuditSubgrpHst.setAuditTypeCode(riskScoreAuditSubgrpHst.getAuditTypeCode()!=null ? riskScoreAuditSubgrpHst.getAuditTypeCode().split("-")[0] : null);
						riskScoreAuditSubgrpHst.setAuditGroupCode(riskScoreAuditSubgrpHst.getAuditGroupCode()!=null ? riskScoreAuditSubgrpHst.getAuditGroupCode().split("-")[0] : null);
						riskScoreAuditSubgrpHst.setAuditSubGroupCode(riskScoreAuditSubgrpHst.getAuditSubGroupCode()!=null ? riskScoreAuditSubgrpHst.getAuditSubGroupCode().split("-")[0] : null);
						riskScoreAuditGrpDao.save(riskScoreAuditSubgrpHst);
					}
				}
			}	*/		
			riskScoreAuditGrpDao.flushSession();
			
			
		    // update or save the record in work 
			RiskScoreAuditGrpWrk riskScoreAuditGrpWrk=null;
			RiskScoreAuditSubgrpWrk riskScoreAuditSubgrpWrk=null; 
			for (RiskScoreAuditGrp riskScoreAuditGrp : riskScoreAuditGrps) {
				riskScoreAuditGrpWrk  = new RiskScoreAuditGrpWrk();
				BeanUtils.copyProperties(riskScoreAuditGrp, riskScoreAuditGrpWrk);
				riskScoreAuditGrpWrk.setMakerTimestamp(businessDateService.getBusinessDateTimestampByLegalEntityCode(riskScoreAuditGrp.getLegalEntityCode()));
				riskScoreAuditGrpDao.saveOrUpdate(riskScoreAuditGrpWrk);
				riskScoreAuditGrpDao.flushSession();
				for (RiskScoreAuditSubgrp riskScoreAuditSubgrp : riskScoreAuditGrp.getRiskScoreAuditSubgrps()) {
					riskScoreAuditSubgrpWrk  = new RiskScoreAuditSubgrpWrk();
					BeanUtils.copyProperties(riskScoreAuditSubgrp, riskScoreAuditSubgrpWrk);
					riskScoreAuditGrpDao.saveOrUpdate(riskScoreAuditSubgrpWrk);
				}
				
			}
			
		}else{
			// get Db object and save into the history
			/*List<RiskScoreAuditGrp> riskScoreAuditGrpsDb=
					getRiskScoreAuditGrpByLegalEntityCodeAndAuditTypeCode(riskScoreAuditGrps.get(0).getLegalEntityCode(), riskScoreAuditGrps.get(0).getAuditTypeCode() , BankAuditConstant.STATUS_AUTH);
			if(riskScoreAuditGrpsDb!=null){
				riskScoreAuditGrpDao.flushSession();
				RiskScoreAuditGrpHst riskScoreAuditGrpHst=null;
				RiskScoreAuditSubgrpHst riskScoreAuditSubgrpHst=null; 
				for (RiskScoreAuditGrp riskScoreAuditGrp : riskScoreAuditGrpsDb) {
					riskScoreAuditGrpHst  = new RiskScoreAuditGrpHst();
					String[] ignoreProperties={
							"riskScoreAuditSubgrps"
					};
					BeanUtils.copyProperties(riskScoreAuditGrp, riskScoreAuditGrpHst,ignoreProperties);
					riskScoreAuditGrpHst.setAuditGroupCode(riskScoreAuditGrpHst.getAuditGroupCode()!=null ? riskScoreAuditGrpHst.getAuditGroupCode().split("-")[0] : null);
					riskScoreAuditGrpHst.setAuditTypeCode(riskScoreAuditGrpHst.getAuditTypeCode()!=null ? riskScoreAuditGrpHst.getAuditTypeCode().split("-")[0] : null);
					riskScoreAuditGrpDao.save(riskScoreAuditGrpHst);
					
					
					for (RiskScoreAuditSubgrp riskScoreAuditSubgrp : riskScoreAuditGrp.getRiskScoreAuditSubgrps()) {
						riskScoreAuditSubgrpHst  = new RiskScoreAuditSubgrpHst();
						BeanUtils.copyProperties(riskScoreAuditSubgrp, riskScoreAuditSubgrpHst);
						riskScoreAuditSubgrpHst.setAuditTypeCode(riskScoreAuditSubgrpHst.getAuditTypeCode()!=null ? riskScoreAuditSubgrpHst.getAuditTypeCode().split("-")[0] : null);
						riskScoreAuditSubgrpHst.setAuditGroupCode(riskScoreAuditSubgrpHst.getAuditGroupCode()!=null ? riskScoreAuditSubgrpHst.getAuditGroupCode().split("-")[0] : null);
						riskScoreAuditSubgrpHst.setAuditSubGroupCode(riskScoreAuditSubgrpHst.getAuditSubGroupCode()!=null ? riskScoreAuditSubgrpHst.getAuditSubGroupCode().split("-")[0] : null);
						riskScoreAuditGrpDao.save(riskScoreAuditSubgrpHst);
					}
				}
			}*/
			//delete the existing object from work table
			riskScoreAuditGrpDao.deleteRiskScoreAuditGrp(riskScoreAuditGrps.get(0).getLegalEntityCode(),riskScoreAuditGrps.get(0).getAuditTypeCode(), BankAuditConstant.STATUS_UNAUTH);
			riskScoreAuditGrpDao.flushSession();
			// save again 
			for (RiskScoreAuditGrp riskScoreAuditGrp : riskScoreAuditGrps) {
				riskScoreAuditGrp.setCheckerTimestamp(businessDateService.getBusinessDateTimestampByLegalEntityCode(riskScoreAuditGrp.getLegalEntityCode()));
				for (RiskScoreAuditSubgrp riskScoreAuditSubgrp : riskScoreAuditGrp.getRiskScoreAuditSubgrps()) {
					riskScoreAuditGrpDao.saveOrUpdate(riskScoreAuditSubgrp);
					riskScoreAuditGrpDao.flushSession();
				}
				riskScoreAuditGrp.setRiskScoreAuditSubgrps(null);
				riskScoreAuditGrpDao.saveOrUpdate(riskScoreAuditGrp);
				riskScoreAuditGrpDao.flushSession();
			}
			 
		}
	
	}

	/* (non-Javadoc)
	 * @see com.bankaudit.service.RiskScoreAuditGrpService#getRiskScoreAuditGrps(java.lang.Integer, java.lang.String, java.lang.Integer, java.lang.String, java.lang.Integer, java.lang.Integer)
	 */
	@Override
	public DataTableResponse getRiskScoreAuditGrps(Integer legalEntityCode, String search, Integer orderColumn,
			String orderDirection, Integer page, Integer size) {
		return riskScoreAuditGrpDao.getRiskScoreAuditGrps( legalEntityCode,  search,  orderColumn,
				 orderDirection,  page,  size);
	}

	/* (non-Javadoc)
	 * @see com.bankaudit.service.RiskScoreAuditGrpService#getRiskScoreAuditGrpByLegalEntityCodeAndAuditTypeCode(int, java.lang.String, java.lang.String)
	 */
	@Override
	public List<RiskScoreAuditGrp> getRiskScoreAuditGrpByLegalEntityCodeAndAuditTypeCode(int parseInt,
			String auditTypeCode,String status) {
		/*return riskScoreAuditGrpDao.getRiskScoreAuditGrpByLegalEntityCodeAndAuditTypeCode( parseInt,
				 auditTypeCode,status);*/
		
		List<RiskScoreAuditGrp> listRiskScoreAuditGrp  = riskScoreAuditGrpDao.getRiskScoreAuditGrpByLegalEntityCodeAndAuditTypeCode( parseInt,
				 auditTypeCode,status);
				
		List<RiskScoreAuditGrp> listRiskScoreAuditGrpsorted = listRiskScoreAuditGrp.stream()
				.sorted((o1,o2)->{
					if(o1.getRiskScoreAuditSubgrps().size()>=o2.getRiskScoreAuditSubgrps().size()){
						return 1;
					}else return -1;
				}).collect(Collectors.toList()); 		
		
		return listRiskScoreAuditGrpsorted;
	}

	/* (non-Javadoc)
	 * @see com.bankaudit.service.RiskScoreAuditGrpService#isRiskScoreAuditGrp(java.lang.Integer, java.lang.String)
	 */
	@Override
	public Boolean isRiskScoreAuditGrp(Integer legalEntityCode, String auditTypeCode) {
		
		return riskScoreAuditGrpDao.isRiskScoreAuditGrp( legalEntityCode,  auditTypeCode) ;
	}
	
}
