package com.bankaudit.service;

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

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.ActivityProcessFindingMappingDao;
import com.bankaudit.dao.MaintAuditFindingDao;
import com.bankaudit.dto.DataTableResponse;
import com.bankaudit.dto.SequenceDto;
import com.bankaudit.model.ActivityProcessFindingMapping;
import com.bankaudit.model.ActivityProcessFindingMappingWrk;
import com.bankaudit.model.ActivityProcessFindingMappingHst;

@Service("activityProcessFindingMappingService")
@Transactional("transactionManager")
public class ActivityProcessFindingMappingServiceImpl  implements ActivityProcessFindingMappingService {

	@Autowired
	ActivityProcessFindingMappingDao activityProcessFindingMappingDao;
	
	@Autowired
	MaintAuditFindingDao maintAuditFindingDao;
	
	@Autowired
	BusinessDateService businessDateService;
	
	@Autowired
	SequenceAppenderService sequenceAppenderService;
	
	@Override
	public void createActivityProcessFindingMapping(ActivityProcessFindingMapping activityProcessFindingMapping) throws Exception {
		
	if(activityProcessFindingMapping.getStatus().equalsIgnoreCase(BankAuditConstant.STATUS_UNAUTH)){
		
		ActivityProcessFindingMappingWrk activityProcessFindingMappingWrk =new ActivityProcessFindingMappingWrk();
		BeanUtils.copyProperties(activityProcessFindingMapping, activityProcessFindingMappingWrk);
		activityProcessFindingMappingDao.save(activityProcessFindingMappingWrk);
		
	}else if (activityProcessFindingMapping.getStatus().equalsIgnoreCase(BankAuditConstant.STATUS_AUTH)) {
		activityProcessFindingMappingDao.save(activityProcessFindingMapping);
	}else {
		throw new Exception("invalid status");
	}
}

	@Override
	public void updateActivityProcessFindingMapping(ActivityProcessFindingMapping activityProcessFindingMapping) {

		
		if(!activityProcessFindingMapping.getStatus().equalsIgnoreCase(BankAuditConstant.STATUS_AUTH)){

			if(activityProcessFindingMapping.getStatus().equalsIgnoreCase(BankAuditConstant.STATUS_UNAUTH)
					|| activityProcessFindingMapping.getStatus().equalsIgnoreCase(BankAuditConstant.STATUS_MOD)){
				activityProcessFindingMapping.setMakerTimestamp(businessDateService.getBusinessDateTimestampByLegalEntityCode(activityProcessFindingMapping.getLegalEntityCode()));
			}

			// get Db object and save into the history
			ActivityProcessFindingMapping activityProcessFindingMappingDb=getActivityProcessFindingMapping(activityProcessFindingMapping.getLegalEntityCode(), activityProcessFindingMapping.getActivityId(), BankAuditConstant.STATUS_AUTH);
			if(activityProcessFindingMappingDb!=null){
				ActivityProcessFindingMappingHst maintEntityHst=new ActivityProcessFindingMappingHst();
				BeanUtils.copyProperties(activityProcessFindingMappingDb, maintEntityHst);
				activityProcessFindingMappingDao.save(maintEntityHst);
			}
			
			ActivityProcessFindingMappingWrk activityProcessFindingMappingWrk=new ActivityProcessFindingMappingWrk();
			BeanUtils.copyProperties(activityProcessFindingMapping, activityProcessFindingMappingWrk);
			activityProcessFindingMappingDao.saveOrUpdate(activityProcessFindingMappingWrk);
			
		}else{
			
			// get Db object and save into the history
			ActivityProcessFindingMapping activityProcessFindingMappingDb=getActivityProcessFindingMapping(activityProcessFindingMapping.getLegalEntityCode(), activityProcessFindingMapping.getActivityId(), BankAuditConstant.STATUS_AUTH);
			if(activityProcessFindingMappingDb!=null){
				activityProcessFindingMappingDb.setEntityStatus(BankAuditConstant.STATUS_EXPIRE);
				activityProcessFindingMappingDao.update(activityProcessFindingMappingDb);
			}

			// delete from work
			activityProcessFindingMappingDao.deleteActivityProcessFindingMapping(activityProcessFindingMapping.getLegalEntityCode(),activityProcessFindingMapping.getMappingId(),BankAuditConstant.STATUS_UNAUTH);
			// save again 
			String mappingId= activityProcessFindingMapping.getMappingId();
			
			activityProcessFindingMapping.setMappingId(sequenceAppenderService.getAutoSequenceId());
			activityProcessFindingMappingDao.save(activityProcessFindingMapping);
			
			activityProcessFindingMappingDao.updateStatusforAuthModify_E(activityProcessFindingMapping.getLegalEntityCode(),mappingId,BankAuditConstant.STATUS_AUTH);
			
		}
	
	}

	@Override
	public ActivityProcessFindingMapping getActivityProcessFindingMapping(Integer legalEntityCode, String mappingId,String status) {
		
		Map<String,Object> properties=new HashMap<String, Object>();
		properties.put("legalEntityCode", legalEntityCode);
		properties.put("mappingId", mappingId);
		if(!BankAuditConstant.STATUS_AUTH.equalsIgnoreCase(status)){
			ActivityProcessFindingMapping activityProcessFindingMapping=null;
			ActivityProcessFindingMappingWrk activityProcessFindingMappingWrk =(ActivityProcessFindingMappingWrk) activityProcessFindingMappingDao.getUniqueEntityByMatchingProperties(ActivityProcessFindingMappingWrk.class, properties);
			if(activityProcessFindingMappingWrk!=null){
				activityProcessFindingMapping=new ActivityProcessFindingMapping();
				BeanUtils.copyProperties(activityProcessFindingMappingWrk, activityProcessFindingMapping);
			}
			return activityProcessFindingMapping;
		}else {
			return (ActivityProcessFindingMapping) activityProcessFindingMappingDao.getUniqueEntityByMatchingProperties(ActivityProcessFindingMapping.class, properties);
		}
		
	}


	@Override
	public DataTableResponse getActivityProcessFindingMappings(Integer legalEntityCode, String search,
			Integer orderColumn, String orderDirection, Integer page, Integer size) {
		return activityProcessFindingMappingDao.getActivityProcessFindingMappings( legalEntityCode,  search,
				 orderColumn,  orderDirection,  page,  size);
	}

	@Override
	public List<String> getActivityProcessFindingMappingValues(String legalEntityCode, String auditTypeCode,
			String auditGroupCode, String auditSubGroupCode, String activityCode, String processCode,
			String findingCode,String createOrUpdate) {
		return activityProcessFindingMappingDao.getActivityProcessFindingMappingValues( legalEntityCode,  auditTypeCode,
				 auditGroupCode,  auditSubGroupCode,  activityCode,  processCode,
				 findingCode,createOrUpdate);
	}

	@Override
	public List<SequenceDto> getDynamicValuesForSequence(String legalEntityCode, String auditTypeCode,
			String auditGroupCode, String auditSubGroupCode, String activityCode, String processCode) {
		return activityProcessFindingMappingDao.getDynamicValuesForSequence( legalEntityCode,  auditTypeCode,
				 auditGroupCode,  auditSubGroupCode,  activityCode,  processCode);
	}
	
	@Override
	public Boolean isActivityProcessFindingMapping(int parseInt, String auditTypeCode, String auditGroupCode,
			String auditSubGroupCode, String activityCode, String processCode, String findingCode,String mappingId, String riskBelongsTo) {
		return activityProcessFindingMappingDao.isActivityProcessFindingMapping( parseInt,  auditTypeCode,  auditGroupCode,
				 auditSubGroupCode,  activityCode,  processCode,  findingCode, mappingId, riskBelongsTo);
	}
	
	@Override
	public HashMap<String, String> getAnyOneAuditGrpAndSubGrpForAuditType(Integer legalEntityCode,String auditTypeCode,String status) {
		HashMap<String, String> map =null;
		List<ActivityProcessFindingMapping> lstAgAsg=activityProcessFindingMappingDao.getAnyOneAuditGrpAndSubGrpForAuditType( legalEntityCode,  auditTypeCode,  "A");
		if(!lstAgAsg.isEmpty()) {
			map= new HashMap();
			map.put("AuditTypeCode", lstAgAsg.get(0).getAuditTypeCode());
			map.put("AuditGroupCode", lstAgAsg.get(0).getAuditGroupCode());
			map.put("AuditSubGroupCode", lstAgAsg.get(0).getAuditSubGroupCode());
		}else if("RMD".equalsIgnoreCase(auditTypeCode)) { // RMD is a special case, as there is no Audit type (Dept) with the name as RMD available in Audit Type table.
			map= new HashMap();
   			map.put("AuditTypeCode", "RMD");
   			map.put("AuditGroupCode", "RMD");
   			map.put("AuditSubGroupCode", "RMD");
		}
		
		return map;		
	}

	public void deleteActivityProcessFindingMapping(Integer legalEntityCode, String mappingId, String statusUnauth){
		activityProcessFindingMappingDao.deleteActivityProcessFindingMapping(legalEntityCode, mappingId, statusUnauth);
	}
}
