package com.bankaudit.rest.process.service;

import java.time.LocalDate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.jboss.logging.Logger;
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.dto.DataTableResponse;
import com.bankaudit.process.model.AuditSchedule;
import com.bankaudit.process.model.AuditScheduleStagesStatusHst;
import com.bankaudit.process.model.AuditScheduleStatus;
import com.bankaudit.rest.process.dao.AuditObservationDao;
import com.bankaudit.rest.process.dao.AuditRespondDao;
import com.bankaudit.util.BankAuditUtil;

@Service
@Transactional("transactionManager")
public class AuditRespondServiceImpl implements AuditRespondService{

	@Autowired(required=true)
	AuditRespondDao auditRespondDao;
	
	@Autowired(required=true)
	AuditObservationDao auditObservationDao;
	
	@Autowired
	EmailService emailService;
	
	@Autowired
	AuditScheduleStagesStatusHstService auditScheduleStagesStatusHstService;
	
	static final Logger logger = Logger.getLogger(AuditRespondServiceImpl.class);
	
	@Override
	public DataTableResponse getMyRespondList(int legalEntityCode, String userId, String search, Integer orderColumn, String orderDirection, Integer page, Integer size,
			LocalDate financialYear, String auditTypeCode) {
		List<LocalDate>  financialYearStrtEndList=null;
		if(financialYear!=null) financialYearStrtEndList= BankAuditUtil.getFinancialStartEndDatesNxtFrom(financialYear);
		
		DataTableResponse ds=auditRespondDao.getMyRespondList(legalEntityCode,userId,search, orderColumn, orderDirection, page, size,
				financialYear, auditTypeCode, financialYearStrtEndList);
		return ds;
	}

	@Override
	public AuditSchedule getRespondAuditByPlanIdAndAuditId(int legalEntityCode, String auditTypeCode, String planId,
			String auditId) {
		AuditSchedule auditDtls=auditRespondDao.getRespondAuditByPlanIdAndAuditId(legalEntityCode,auditTypeCode,planId,auditId); 
		 return auditDtls; 
	}
	
	@Override
	public String isRespondObsPendingBfrRespondSubmit(AuditSchedule auditSchedule) {
		String isRespondObsPendingBfrRespondSubmit=auditRespondDao.isRespondObsPendingBfrRespondSubmit(auditSchedule); 
		 return isRespondObsPendingBfrRespondSubmit; 
	}
	
	@Override
	public void updateAuditRespondStatus(AuditSchedule auditSchedule) {
		auditRespondDao.updateAuditRespondStatus(auditSchedule); // To update the Audit status, Respond status, 
		
		//BaaSDOS Specific
		if(auditSchedule != null && "RI".equalsIgnoreCase(auditSchedule.getRespondStatus())) {
			auditObservationDao.updateAuditObservationRecordStatus(auditSchedule.getLegalEntityCode(), auditSchedule.getAuditTypeCode(), 
					auditSchedule.getPlanId(), auditSchedule.getAuditId(), "RI");
		}else if(auditSchedule != null && "RS".equalsIgnoreCase(auditSchedule.getRespondStatus())) {
			auditObservationDao.updateAuditObservationRecordStatus(auditSchedule.getLegalEntityCode(), auditSchedule.getAuditTypeCode(), 
					auditSchedule.getPlanId(), auditSchedule.getAuditId(), "RS");			
			updateAuditStatusDetailOnComplianceSubmit(auditSchedule);
			 
			AuditScheduleStagesStatusHst auditScheduleStagesStatusHst = new AuditScheduleStagesStatusHst();
			auditScheduleStagesStatusHst.setStagesStatus(auditSchedule.getRespondStatus());
			auditScheduleStagesStatusHst.setCode(auditSchedule.getRespondStatus());
			auditScheduleStagesStatusHst.setActionType(BankAuditConstant.ACTION_TYPE_SCRUTINY);
			auditScheduleStagesStatusHst.setAssigneeRole("G7");
			auditScheduleStagesStatusHstService.saveAuditStagesStatus(auditSchedule, auditScheduleStagesStatusHst);	
		}	 
		
		//Mail sending/trigger
		try {
		if(BankAuditConstant.EMAIL_INSPECTION && auditSchedule != null && "RS".equalsIgnoreCase(auditSchedule.getRespondStatus())) {
			logger.info("Before sending Email in updateAuditRespondStatus .."+ auditSchedule.getAuditId());
			logger.info("AuditStatus .. "+auditSchedule.getAuditStatus()+" ObsStatus .. "+auditSchedule.getObservationStatus() +" reportStatus .. "+auditSchedule.getReportStatus());
			logger.info("RespondStatus .. "+auditSchedule.getRespondStatus() +" ReviewStatus .. "+ auditSchedule.getReviewStatus() );
			if(auditSchedule != null && "RS".equalsIgnoreCase(auditSchedule.getRespondStatus())) {
				emailService.sendComplianceSubmission(auditSchedule.getLegalEntityCode(), auditSchedule.getAuditId());
			}
		}
		}catch(Exception e){
			e.printStackTrace(System.out);
		}//Mail trigger, End here
		
		//NABARD RCSA specific, To call the Procedures to calculate the Prob, Sev, Residual, Control and Health Index
		/*if(auditSchedule != null && "RS".equalsIgnoreCase(auditSchedule.getRespondStatus())) { 
			auditRespondDao.updateProbSevrtyRiskwise( auditSchedule.getLegalEntityCode(), auditSchedule.getAuditTypeCode(), 
					auditSchedule.getAuditId(), auditSchedule.getObservationStatus(), auditSchedule.getResponderId());

			auditRespondDao.updateResidualriskAssessmentwiseCallHealthIndexCntrlRating(auditSchedule.getLegalEntityCode(), auditSchedule.getAuditTypeCode(), 
					auditSchedule.getAuditId(), auditSchedule.getRespondStatus(), auditSchedule.getResponderId());
		}*/ //NABARD RCSA specific, end here
		
	}
	
	@Override
	public DataTableResponse getRespondObservationList(int legalEntityCode,String planId,String auditId, String search, Integer orderColumn,
			String orderDirection, Integer page, Integer size) {
		DataTableResponse ds=auditRespondDao.getRespondObservationList(legalEntityCode,planId,auditId,search,orderColumn,
				orderDirection,page,size);
		return ds;
	}
	
	private void updateAuditStatusDetailOnComplianceSubmit(AuditSchedule auditSchedule){				
		logger.info(" Inside updateAuditStatusDetailOnResponseSubmit .."+auditSchedule.getAuditId()  +" :: "+auditSchedule.getUnitId());
	 	 
		Map<String, Object> properties = new HashMap<String, Object>();
		properties.put("legalEntityCode", auditSchedule.getLegalEntityCode());
		properties.put("auditTypeCode", auditSchedule.getAuditTypeCode());
		properties.put("auditId", auditSchedule.getAuditId());
		AuditScheduleStatus auditScheduleStatus = (AuditScheduleStatus) auditObservationDao.getUniqueEntityByMatchingProperties(AuditScheduleStatus.class, properties);		
 		logger.info("auditScheduleStatus .. "+auditScheduleStatus);
		
		if(auditScheduleStatus!=null) {
			List<Object[]> statusCountList =  auditObservationDao.getObservationsCountByStatusAttributesOnSubmit(auditSchedule.getLegalEntityCode(), auditSchedule.getAuditTypeCode(), 
					auditSchedule.getAuditId(), false, true, false);
			
			if(statusCountList != null && statusCountList.size()>0){
				Object[] countsArr = statusCountList.get(0);			 		 		
				auditScheduleStatus.setPendingWithBank(0);
				auditScheduleStatus.setPendingWithScrutiniser(Integer.parseInt(countsArr[1].toString()));			
			}	 
			auditObservationDao.update(auditScheduleStatus); 
		}
	}
}
