
package com.bankaudit.rest.controller;

import java.sql.Timestamp;
import java.util.List;

import org.jboss.logging.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.bankaudit.constants.BankAuditConstant;
import com.bankaudit.dto.DataTableResponse;
import com.bankaudit.dto.SequenceDto;
import com.bankaudit.model.ActivityProcessFindingMapping;
import com.bankaudit.service.ActivityProcessFindingMappingService;
import com.bankaudit.service.BusinessDateService;
import com.bankaudit.service.SequenceAppenderService;
import com.bankaudit.util.BankAuditUtil;
import com.bankaudit.util.ServiceStatus;

/**
 * The Class {@link ActivityProcessFindingMappingController} provides the REST
 * services to manage the {@link ActivityProcessFindingMapping} class objects .
 *
 * @author amit.patel
 * @version 1.0
 */


@RestController

@RequestMapping("/api/activityProcessFindingMapping")
public class ActivityProcessFindingMappingController {

	/**
	 * The activity process finding mapping service is autowired and make
	 * methods available from service layer .
	 */
	@Autowired
	ActivityProcessFindingMappingService activityProcessFindingMappingService;
	
	/**
	 * The business date service is autowired and make methods available from
	 * service layer.
	 */
	@Autowired
	BusinessDateService businessDateService;
	
	/**
	 * The sequence appender service is autowired and make methods available
	 * from service layer .
	 */
	@Autowired
	SequenceAppenderService sequenceAppenderService;
	
	/** The Constant logger is used to specify the log messages in log file . */
	static final Logger logger = Logger.getLogger(ActivityProcessFindingMappingController.class);
	
	/**
	 * This method is use to Creates the activity process finding mapping.
	 *
	 * @param activityProcessFindingMapping
	 *            specify the activity process finding mapping
	 * @return the service status class object with response status and payload
	 *         .
	 */
	
@RequestMapping(method=RequestMethod.POST,consumes=MediaType.APPLICATION_JSON_VALUE,produces=MediaType.APPLICATION_JSON_VALUE)
	ServiceStatus createActivityProcessFindingMapping(@RequestBody ActivityProcessFindingMapping activityProcessFindingMapping){
		ServiceStatus serviceStatus=new ServiceStatus();
		
		try {
		if(activityProcessFindingMapping!=null
				&& activityProcessFindingMapping.getLegalEntityCode()!=null
				&& !BankAuditUtil.isEmptyString(activityProcessFindingMapping.getAuditGroupCode())
				&& !BankAuditUtil.isEmptyString(activityProcessFindingMapping.getAuditSubGroupCode())
				&& !BankAuditUtil.isEmptyString(activityProcessFindingMapping.getAuditTypeCode())
				&& !BankAuditUtil.isEmptyString(activityProcessFindingMapping.getMaker())
				&& !BankAuditUtil.isEmptyString(activityProcessFindingMapping.getFindingId())
				&& !BankAuditUtil.isEmptyString(activityProcessFindingMapping.getProcessId())
				&& !BankAuditUtil.isEmptyString(activityProcessFindingMapping.getActivityId())
				){ 
					
			activityProcessFindingMapping.setMappingId(sequenceAppenderService.getAutoSequenceId());
			activityProcessFindingMapping.setMappingCode(sequenceAppenderService.getAutoSequenceId());
			
			activityProcessFindingMapping.setBusinessdateTimestamp(businessDateService.getBusinessDateTimestampByLegalEntityCode(activityProcessFindingMapping.getLegalEntityCode()));
			activityProcessFindingMapping.setSysdateTimestamp(new Timestamp(System.currentTimeMillis()));
			activityProcessFindingMapping.setMakerTimestamp(activityProcessFindingMapping.getBusinessdateTimestamp());
			   
			activityProcessFindingMappingService.createActivityProcessFindingMapping(activityProcessFindingMapping);
			serviceStatus.setStatus("success");
			serviceStatus.setMessage("successfully created");
			serviceStatus.setResult(activityProcessFindingMapping.getMappingId());
			
		} else {
			serviceStatus.setStatus("failure");
			serviceStatus.setMessage("invalid payload");
		}}catch (Exception e) {
			serviceStatus.setStatus("failure");
			if(e instanceof org.springframework.dao.DataIntegrityViolationException) {
				serviceStatus.setMessage("DATAINTGRTY_VIOLATION");
			}else serviceStatus.setMessage("EXCP_OCCURED");
		}
		
		return serviceStatus;
	}
	
	/**
	 * This method is use to Update activity process finding mapping.
	 *
	 * @param activityProcessFindingMapping
	 *            specify the activity process finding mapping
	 * @return the service status class object with response status and payload
	 *         .
	 */
	
@RequestMapping(method=RequestMethod.PUT,consumes=MediaType.APPLICATION_JSON_VALUE,produces=MediaType.APPLICATION_JSON_VALUE)
	ServiceStatus updateActivityProcessFindingMapping(@RequestBody ActivityProcessFindingMapping activityProcessFindingMapping){
		ServiceStatus serviceStatus=new ServiceStatus();
		
		if(activityProcessFindingMapping!=null
				&& activityProcessFindingMapping.getLegalEntityCode()!=null
				&& !BankAuditUtil.isEmptyString(activityProcessFindingMapping.getActivityId())
				&& !BankAuditUtil.isEmptyString(activityProcessFindingMapping.getAuditGroupCode())
				&& !BankAuditUtil.isEmptyString(activityProcessFindingMapping.getAuditSubGroupCode())
				&& !BankAuditUtil.isEmptyString(activityProcessFindingMapping.getAuditTypeCode())
				&& !BankAuditUtil.isEmptyString(activityProcessFindingMapping.getFindingId())
				&& activityProcessFindingMapping.getMappingId()!=null
				&& !BankAuditUtil.isEmptyString(activityProcessFindingMapping.getProcessId())
				&& !BankAuditUtil.isEmptyString(activityProcessFindingMapping.getMaker())
				){
			try {

				activityProcessFindingMapping.setBusinessdateTimestamp(businessDateService.getBusinessDateTimestampByLegalEntityCode(activityProcessFindingMapping.getLegalEntityCode()));
				activityProcessFindingMapping.setSysdateTimestamp(new Timestamp(System.currentTimeMillis()));
				
				if(activityProcessFindingMapping.getStatus().equals(BankAuditConstant.STATUS_AUTH)){
					activityProcessFindingMapping.setCheckerTimestamp(businessDateService.getBusinessDateTimestampByLegalEntityCode(activityProcessFindingMapping.getLegalEntityCode()));
				}else{
					activityProcessFindingMapping.setMakerTimestamp(businessDateService.getBusinessDateTimestampByLegalEntityCode(activityProcessFindingMapping.getLegalEntityCode()));
				}
				    activityProcessFindingMappingService.updateActivityProcessFindingMapping(activityProcessFindingMapping);
				    
				    serviceStatus.setStatus("success");
				    serviceStatus.setMessage("successfully updated");
			
			} catch (Exception e) {
				e.printStackTrace();
				serviceStatus.setStatus("failure");
				serviceStatus.setMessage("failure");
				if(e instanceof org.springframework.dao.DataIntegrityViolationException) {
					serviceStatus.setMessage("DATAINTGRTY_VIOLATION");
				}
			}
			
		}else {
			serviceStatus.setStatus("failure");
			serviceStatus.setMessage("invalid payload ");
		}
		
		return serviceStatus;
	}
	
	/**
	 * This method is use to Gets the activity process finding mapping.
	 *
	 * @param legalEntityCode
	 *            specify the legal entity code
	 * @param mappingId
	 *            specify the mapping id
	 * @param status
	 *            specify the status
	 * @return the service status class object with response status and payload
	 *         .
	 */
	
@RequestMapping(value="/get/{legalEntityCode}/{mappingId}/{status}",method=RequestMethod.GET,produces=MediaType.APPLICATION_JSON_VALUE)
	ServiceStatus getActivityProcessFindingMapping(@PathVariable("legalEntityCode")Integer legalEntityCode,
			@PathVariable("mappingId") String mappingId,
			@PathVariable("status") String status
			
			){
		ServiceStatus serviceStatus=new ServiceStatus();
		
		if(legalEntityCode!=null 
				&& !BankAuditUtil.isEmptyString(mappingId)
				&& !BankAuditUtil.isEmptyString(status)
				){
			
			try {
				ActivityProcessFindingMapping activityProcessFindingMapping = activityProcessFindingMappingService
						.getActivityProcessFindingMapping(legalEntityCode,mappingId,status);
			    if(activityProcessFindingMapping!=null){
			    	serviceStatus.setResult(activityProcessFindingMapping);
				    serviceStatus.setStatus("success");
				    serviceStatus.setMessage("successfully retrieved ");	
			    }else {
					serviceStatus.setStatus("failure");
					serviceStatus.setMessage("ActivityProcessFindingMapping not found");
				}
				
			} catch (Exception e) {
				e.printStackTrace();
				serviceStatus.setStatus("failure");
				serviceStatus.setMessage("failure");
			}
			
		}else {
			serviceStatus.setStatus("failure");
			serviceStatus.setMessage("invalid payload ");
		}
		
		return serviceStatus;
	}
	

	/**
	 * This method is use to Gets the activity process finding mappings.
	 *
	 * @param drawStr
	 *            specify the draw str
	 * @param length
	 *            specify the length
	 * @param start
	 *            specify the start
	 * @param search
	 *            specify the search
	 * @param orderColumnStr
	 *            specify the order column str
	 * @param orderDirection
	 *            specify the order direction
	 * @param legalEntityCodeStr
	 *            specify the legal entity code str
	 * @return the data table response class object with response status and
	 *         payload .
	 */
	
@RequestMapping(value="/getAll",method=RequestMethod.GET,produces=MediaType.APPLICATION_JSON_VALUE) 
	DataTableResponse getActivityProcessFindingMappings(
			@RequestParam("draw") String drawStr,
			@RequestParam("length") String length,
			@RequestParam("start") String start,
			@RequestParam("search[value]") String search,
			@RequestParam("order[0][column]") String orderColumnStr,
			@RequestParam("order[0][dir]")String orderDirection,
			@RequestParam("legalEntityCode")String legalEntityCodeStr){
		
		DataTableResponse dataTableResponse=null;
		
		if(!BankAuditUtil.isEmptyString(drawStr)
				&& !BankAuditUtil.isEmptyString(length)
				&& !BankAuditUtil.isEmptyString(start)
				&& !BankAuditUtil.isEmptyString(legalEntityCodeStr)){
			try {
				Integer legalEntityCode=Integer.parseInt(legalEntityCodeStr);
				Integer draw=Integer.parseInt(drawStr);
				Integer size=Integer.parseInt(length);
				Integer page=Integer.parseInt(start)/size;
				Integer orderColumn=null;
				if(!BankAuditUtil.isEmptyString(orderColumnStr)){
					orderColumn=Integer.parseInt(orderColumnStr);
				}
				dataTableResponse = activityProcessFindingMappingService.getActivityProcessFindingMappings(legalEntityCode,search,orderColumn,orderDirection,page,size);
				dataTableResponse.setDraw(draw);    
					
			} catch (Exception e) {
                dataTableResponse=new DataTableResponse();
                dataTableResponse.setError(e.getMessage());
				e.printStackTrace();
			}
		
		}else {
			dataTableResponse=new DataTableResponse();
			dataTableResponse.setError("invalid data");
		}
		
		return dataTableResponse;
	}
	
	/**
	 * This method is use to Gets the activity process finding mapping values.
	 *
	 * @param legalEntityCode
	 *            specify the legal entity code
	 * @param auditTypeCode
	 *            specify the audit type code
	 * @param auditGroupCode
	 *            specify the audit group code
	 * @param auditSubGroupCode
	 *            specify the audit sub group code
	 * @param activityId
	 *            specify the activity id
	 * @param processId
	 *            specify the process id
	 * @param findingId
	 *            specify the finding id
	 * @return the service status class object with response status and payload
	 *         .
	 */
	
@RequestMapping(value="/getDynamicValues",method=RequestMethod.GET,produces=MediaType.APPLICATION_JSON_VALUE)
	ServiceStatus getActivityProcessFindingMappingValues(
		/*	@PathVariable("createOrUpdate")String createOrUpdate,*/
			@RequestParam(required=true,value="legalEntityCode")String legalEntityCode,
			@RequestParam(required=true,value="auditTypeCode") String auditTypeCode,
			@RequestParam(required=false,value="auditGroupCode") String auditGroupCode,
			@RequestParam(required=false,value="auditSubGroupCode") String auditSubGroupCode,
			@RequestParam(required=false,value="activityId") String activityId,
			@RequestParam(required=false,value="processId") String processId,
			@RequestParam(required=false,value="findingId") String findingId
			){
		ServiceStatus serviceStatus=new ServiceStatus();
		if(!BankAuditUtil.isEmptyString(auditTypeCode)
				&& !BankAuditUtil.isEmptyString(legalEntityCode)){
			try {
				List<String>  values = activityProcessFindingMappingService
						.getActivityProcessFindingMappingValues(legalEntityCode , auditTypeCode , auditGroupCode , 
								auditSubGroupCode ,activityId, processId,findingId,"C");
			    if(values!=null && !values.isEmpty()){
			    	serviceStatus.setResult(values);
				    serviceStatus.setStatus("success");
				    serviceStatus.setMessage("successfully retrieved ");	
			    }else {
					serviceStatus.setStatus("failure");
					serviceStatus.setMessage(" No records found ");
				}
			} catch (Exception e) {
				e.printStackTrace();
				serviceStatus.setStatus("failure");
				serviceStatus.setMessage("failure");
			}
		}else {
			serviceStatus.setStatus("failure");
			serviceStatus.setMessage("invalid payload ");
		}
		
		return serviceStatus;
	}
	
	
	/**
	 * This method is use to Checks if is maint audit finding.
	 *
	 * @param legalEntityCode
	 *            specify the legal entity code
	 * @param auditTypeCode
	 *            specify the audit type code
	 * @param auditGroupCode
	 *            specify the audit group code
	 * @param auditSubGroupCode
	 *            specify the audit sub group code
	 * @param activityCode
	 *            specify the activity code
	 * @param processCode
	 *            specify the process code
	 * @param findingCode
	 *            specify the finding code
	 * @return the service status class object with response status and payload
	 *         .
	 */
	
@RequestMapping(value="/isActivityProcessFindingMapping",method=RequestMethod.GET,produces=MediaType.APPLICATION_JSON_VALUE)
	ServiceStatus isMaintAuditFinding(
			@RequestParam(required=true,value="legalEntityCode")String legalEntityCode,
			@RequestParam(required=true,value="auditTypeCode") String auditTypeCode,
			@RequestParam(required=true,value="auditGroupCode") String auditGroupCode,
			@RequestParam(required=true,value="auditSubGroupCode") String auditSubGroupCode,
			@RequestParam(required=true,value="activityCode") String activityCode,
			@RequestParam(required=true,value="processCode") String processCode,
			@RequestParam(required=true,value="findingCode") String findingCode,
			@RequestParam(required=false,value="mappingId") String mappingId,
			@RequestParam(required=false,value="riskBelongsTo") String riskBelongsTo){
		ServiceStatus serviceStatus=new ServiceStatus();
		if(legalEntityCode!=null 
				){
			
			try {
			    Boolean activityProcessFindingMapping=activityProcessFindingMappingService.isActivityProcessFindingMapping(Integer.parseInt(legalEntityCode),auditTypeCode,
			    		auditGroupCode,auditSubGroupCode,activityCode,processCode,findingCode,mappingId,riskBelongsTo); // riskBelongsTo added to handle one more parameter in RCSA Setup
		    	serviceStatus.setResult(activityProcessFindingMapping);
			    serviceStatus.setStatus("success");
			    serviceStatus.setMessage("successfully retrieved");	
		    
				
			} catch (Exception e) {
				/*e.printStackTrace();*/
				serviceStatus.setStatus("failure");
				serviceStatus.setMessage("failure");
			}
			
		}else {
			serviceStatus.setStatus("failure");
			serviceStatus.setMessage("invalid payload ");
		}
		
		return serviceStatus;
	}
	
	//Loss event included for Risk 
	
@RequestMapping(value="/getActivityProcessFindingLosseventMapping/{legalEntityCode}/{mappingId}/{status}",method=RequestMethod.GET,produces=MediaType.APPLICATION_JSON_VALUE)
	ServiceStatus getActivityProcessFindingLosseventMapping(@PathVariable("legalEntityCode")Integer legalEntityCode,
			@PathVariable("mappingId") String mappingId,
			@PathVariable("status") String status
			
			){
		ServiceStatus serviceStatus=new ServiceStatus();
		
		if(legalEntityCode!=null 
				&& !BankAuditUtil.isEmptyString(mappingId)
				&& !BankAuditUtil.isEmptyString(status)
				){
			
			try {
				ActivityProcessFindingMapping activityProcessFindingMapping = activityProcessFindingMappingService
						.getActivityProcessFindingMapping(legalEntityCode,mappingId,status); // Need to call getActivityProcessFindingLosseventMapping for Loss event, 
			    if(activityProcessFindingMapping!=null){
			    	serviceStatus.setResult(activityProcessFindingMapping);
				    serviceStatus.setStatus("success");
				    serviceStatus.setMessage("successfully retrieved ");	
			    }else {
					serviceStatus.setStatus("failure");
					serviceStatus.setMessage("ActivityProcessFindingMapping not found");
				}
				
			} catch (Exception e) {
				e.printStackTrace();
				serviceStatus.setStatus("failure");
				serviceStatus.setMessage("failure");
			}
			
		}else {
			serviceStatus.setStatus("failure");
			serviceStatus.setMessage("invalid payload ");
		}
		
		return serviceStatus;
	}

	
@GetMapping(value = "/getDynamicValuesForFindings", produces = MediaType.APPLICATION_JSON_VALUE)
	ServiceStatus getDynamicValuesForSequence(
			@RequestParam(required = true, value = "legalEntityCode") String legalEntityCode,
			@RequestParam(required = true, value = "auditTypeCode") String auditTypeCode,
			@RequestParam(required = true, value = "auditGroupCode") String auditGroupCode,
			@RequestParam(required = true, value = "auditSubGroupCode") String auditSubGroupCode,
			@RequestParam(required = true, value = "activityId") String activityId,
			@RequestParam(required = true, value = "processId") String processId) {
		ServiceStatus serviceStatus = new ServiceStatus();
		if (!BankAuditUtil.isEmptyString(auditTypeCode) && !BankAuditUtil.isEmptyString(legalEntityCode)) {
			try {
				List<SequenceDto> values = activityProcessFindingMappingService.getDynamicValuesForSequence(legalEntityCode, auditTypeCode,
						auditGroupCode, auditSubGroupCode, activityId, processId);
				if (values != null && !values.isEmpty()) {
					serviceStatus.setResult(values);
					serviceStatus.setStatus("success");
					serviceStatus.setMessage("successfully retrieved ");
				} else {
					serviceStatus.setStatus("failure");
					serviceStatus.setMessage(" No records found ");
				}
			} catch (Exception e) {
				e.printStackTrace();
				serviceStatus.setStatus("failure");
				serviceStatus.setMessage("failure");
			}
		} else {
			serviceStatus.setStatus("failure");
			serviceStatus.setMessage("invalid payload ");
		}

		return serviceStatus;
	}
	
	
@RequestMapping(value="/deleteActivityProcessFindingMapping/{legalEntityCode}/{mappingId}/{status}",method=RequestMethod.DELETE,produces=MediaType.APPLICATION_JSON_VALUE)
	ServiceStatus deleteActivityProcessFindingMapping(
			@PathVariable("legalEntityCode")Integer legalEntityCode,
			@PathVariable("mappingId")String mappingId,
			@PathVariable("status")String status){
		ServiceStatus serviceStatus=new ServiceStatus();
		
		if(legalEntityCode!=null
				&& !BankAuditUtil.isEmptyString(mappingId)){
			try {				
				activityProcessFindingMappingService.deleteActivityProcessFindingMapping(legalEntityCode, mappingId, status);
				serviceStatus.setStatus("success"); 
				serviceStatus.setMessage("successfully deleted the rejected record ");				
			} catch (Exception e) {
				e.printStackTrace();
				serviceStatus.setStatus("failure");
				serviceStatus.setMessage("failure");
			}
		}else {
			serviceStatus.setStatus("failure");
			serviceStatus.setMessage("invalid legalEntityCode ");
		}
		
		return serviceStatus;
	}

}
