
package com.bankaudit.rest.controller;

import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.jboss.logging.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
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.dto.DataTableResponse;
import com.bankaudit.dto.process.AuditObservationDto;
import com.bankaudit.model.ActivityProcessFindingMapping;
import com.bankaudit.process.model.AuditDocumentDetails;
import com.bankaudit.process.model.AuditObservation;
import com.bankaudit.service.ChecklistService;
import com.bankaudit.util.BankAuditUtil;
import com.bankaudit.util.ServiceStatus;

import com.fasterxml.jackson.annotation.JsonInclude;

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


@RestController

@RequestMapping("/api/checklist")
public class ChecklistController {

	 
	
	@Autowired
	ChecklistService checklistService;
	
	
	/** The Constant logger is used to specify the log messages in log file . */
	static final Logger logger = Logger.getLogger(ChecklistController.class);
	 
	
@RequestMapping(value = "/getChapter", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
	ServiceStatus getChapter(			 
			@RequestParam("legalEntityCode")String legalEntityCodeStr,		
			@RequestParam("auditId")String auditId,
			@RequestParam("auditTypeCode")String auditTypeCode,
			@RequestParam("userId")String userId){

		ServiceStatus serviceStatus=new ServiceStatus();		
		List<String> listData=null;
			try { 
				checklistService.getChapter(legalEntityCodeStr, auditId, auditTypeCode);	
				listData = checklistService.getChapter(legalEntityCodeStr, auditId, auditTypeCode);				 
				if(listData!=null && !listData.isEmpty()){
					serviceStatus.setResult(listData);
					serviceStatus.setStatus("success");
					serviceStatus.setMessage("successfully got the result ");					
				}else {
					serviceStatus.setStatus("failure");
					serviceStatus.setMessage("No Data found ");
				}
			} catch (Exception e) {
				serviceStatus.setStatus("failure");
				serviceStatus.setMessage("No Data found "); 
				logger.error(e.getStackTrace());
				
			}
		return serviceStatus;
	}
	
	
	
@RequestMapping(value = "/getSection", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
	ServiceStatus getSection(	
			@RequestParam("legalEntityCode")String legalEntityCodeStr,
			@RequestParam("auditId")String auditId,
			@RequestParam("auditTypeCode")String auditTypeCode,
			@RequestParam("userId")String userId,
			@RequestParam("auditGroupCode")String auditGroupCode){

		ServiceStatus serviceStatus=new ServiceStatus();		
		List<String> listData=null;
		if (!BankAuditUtil.isEmptyString(auditGroupCode)) {
			try {
				listData = checklistService.getSection(legalEntityCodeStr, auditId, auditTypeCode, auditGroupCode);	 
				if(listData!=null && !listData.isEmpty()){
					serviceStatus.setResult(listData);
					serviceStatus.setStatus("success");
					serviceStatus.setMessage("successfully got the result ");					
				}else {
					serviceStatus.setStatus("failure");
					serviceStatus.setMessage("No Data found ");
				}
			} catch (Exception e) {
				serviceStatus.setStatus("failure");
				serviceStatus.setMessage("No Data found "); 
				logger.error(e.getStackTrace());
			}
		} else {
			serviceStatus.setStatus("failure");
			serviceStatus.setMessage("Audit Group Code is missing");
		}

		return serviceStatus;
	}
	
	
@RequestMapping(value = "/getProduct", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
	ServiceStatus getProduct(	
			@RequestParam("legalEntityCode")String legalEntityCodeStr,
			@RequestParam("auditId")String auditId,
			@RequestParam("auditTypeCode")String auditTypeCode,
			@RequestParam("userId")String userId,
			@RequestParam("auditGroupCode")String auditGroupCode,
			@RequestParam("auditSubGroupCode")String auditSubGroupCode){
 
		ServiceStatus serviceStatus=new ServiceStatus();		
		List<String> listData=null;
		 
			try {
				listData = checklistService.getProduct(legalEntityCodeStr, auditId, auditTypeCode, auditGroupCode, auditSubGroupCode);	 
				if(listData!=null && !listData.isEmpty()){
					serviceStatus.setResult(listData);
					serviceStatus.setStatus("success");
					serviceStatus.setMessage("successfully got the result ");					
				}else {
					serviceStatus.setStatus("failure");
					serviceStatus.setMessage("No Data found ");
				}
			} catch (Exception e) {
				serviceStatus.setStatus("failure");
				serviceStatus.setMessage("No Data found ");
				System.out.println(e.getMessage());
				logger.error(e.getStackTrace());
			}
		 

		return serviceStatus;
	}
	
	
@RequestMapping(value = "/getProcess", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
	ServiceStatus getProcess(	
			@RequestParam("legalEntityCode")String legalEntityCodeStr,
			@RequestParam("auditId")String auditId,
			@RequestParam("auditTypeCode")String auditTypeCode,
			@RequestParam("userId")String userId,
			@RequestParam("auditGroupCode")String auditGroupCode,
			@RequestParam("auditSubGroupCode")String auditSubGroupCode,
			@RequestParam("activityCode")String activityCode){

		ServiceStatus serviceStatus=new ServiceStatus();		
		List<String> listData=null;
		 
			try {
				listData = checklistService.getProcess(legalEntityCodeStr, auditId, auditTypeCode, auditGroupCode, auditSubGroupCode, activityCode);
				if(listData!=null && !listData.isEmpty()){
					serviceStatus.setResult(listData);
					serviceStatus.setStatus("success");
					serviceStatus.setMessage("successfully got the result ");					
				}else {
					serviceStatus.setStatus("failure");
					serviceStatus.setMessage("No Data found ");
				}
			} catch (Exception e) {
				serviceStatus.setStatus("failure");
				serviceStatus.setMessage("No Data found ");
				System.out.println(e.getMessage());
				logger.error(e.getStackTrace());
			} 

		return serviceStatus;
	}
	
	
@RequestMapping(value = "/getChecklist", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
	DataTableResponse getChecklist(
			@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,
			@RequestParam("auditId")String auditId,
		//	@RequestParam("planId")String planId,
			@RequestParam("auditTypeCode")String auditTypeCode,
		//	@RequestParam("userId")String userId,
			@RequestParam("auditGroupCode")String auditGroupCode,
			@RequestParam("auditSubGroupCode")String auditSubGroupCode,
			@RequestParam("activityCode")String activityCode,
			@RequestParam("processCode")String processCode,
			@RequestParam("complianceCategory")String complianceCategory,
			@RequestParam(value="submissionStatus", required=false)String submissionStatus,
			@RequestParam(value="responseStatus", required=false)String responseStatus,
			@RequestParam(value="reviewStatus", required=false)String reviewStatus,
			@RequestParam(value="flag", required=false)String flag,
			@RequestParam(value="criticalityToggle", required=false)String criticalityToggle,
			@RequestParam(value="reportRvwFedbk", required=false)String reportRvwFedbk,
			@RequestParam(value="role", required=false)String role,
			@RequestParam(value="documentType", required=false)String documentType,
			@RequestParam(value="documentSubType", required=false)String documentSubType,
			@RequestParam(value="nonCompliancePersistence", required=false)String nonCompliancePersistence){

		DataTableResponse dataTableResponse = null;
		//List<String> listData=null;
		if (!BankAuditUtil.isEmptyString(drawStr) && !BankAuditUtil.isEmptyString(length)
				&& !BankAuditUtil.isEmptyString(start)) {
			try {
				logger.info("Inside Checklist controller getChecklist() .. " +drawStr+" :: " +length + " :: "+start +" :: "+ orderColumnStr);
				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 = auditObservationService.getAuditObservationList(Integer.parseInt(legalEntityCodeStr),planId,auditId,search, orderColumn, orderDirection, page, size, userId);
				dataTableResponse = checklistService.getChecklist(legalEntityCodeStr, auditId, auditTypeCode, auditGroupCode, 
						auditSubGroupCode, activityCode, processCode, search, orderColumn, orderDirection, page, size,
						complianceCategory, submissionStatus, responseStatus, reviewStatus,  flag, criticalityToggle, reportRvwFedbk, role,
						documentType, documentSubType, nonCompliancePersistence);
				// (legalEntityCodeStr, auditId, auditTypeCode, auditGroupCode, auditSubGroupCode, activityCode, processCode, page, size);
				dataTableResponse.setDraw(draw);

			} catch (Exception e) {
				e.printStackTrace(System.out);
				dataTableResponse = new DataTableResponse();
				dataTableResponse.setError(e.getMessage());
				logger.error(e.getStackTrace());
			}

		} else {
			dataTableResponse = new DataTableResponse();
			dataTableResponse.setError("invalid data");
		}

		//return listData;
		return dataTableResponse;
	}
	

	/*
@RequestMapping(value="/getCheckListAuditDocumentDetails" ,method=RequestMethod.GET,produces=MediaType.APPLICATION_JSON_VALUE)
	ServiceStatus getCheckListAuditDocumentDetails(
			@RequestParam(value="legalEntityCode")Integer legalEntityCodeStr,
			@RequestParam(value="auditTypeCode")String auditTypeCode,
			@RequestParam(value="planId")String planId,
			@RequestParam(value="auditId")String auditId,
			@RequestParam(value="observationId")String observationId,
			@RequestParam(value="documentType")String documentType
			){
	
		ServiceStatus serviceStatus=new ServiceStatus();
		
		try {
			
			List<AuditDocumentDetails> auditDocumentDetails=checklistService.getAuditDocumentDetails(legalEntityCodeStr,auditTypeCode,planId,
					auditId,observationId,documentType);
			
			if(auditDocumentDetails!=null && !auditDocumentDetails.isEmpty()){
				serviceStatus.setResult(auditDocumentDetails);
				serviceStatus.setStatus("success");
				serviceStatus.setMessage("successfully got the result ");
				
			}else {
				serviceStatus.setStatus("failure");
				serviceStatus.setMessage("No docs found ");
			}
			
		} catch (Exception e) {
			logger.error(e.getStackTrace());
			serviceStatus.setStatus("failure");
			serviceStatus.setMessage("failure");
		}
		return serviceStatus;
	}*/
	
	
	/*
@RequestMapping(value="/getAuditObservation" ,method=RequestMethod.GET,produces=MediaType.APPLICATION_JSON_VALUE)
	ServiceStatus getAuditObservation(
			@RequestParam(value="legalEntityCode")String legalEntityCodeStr,
			@RequestParam(value="auditTypeCode")String auditTypeCode, 
			@RequestParam(value="groupObservationId")String groupObservationId
			){
	
		ServiceStatus serviceStatus=new ServiceStatus();
		
		try {			
			AuditObservation auditObservation=checklistService.getAuditObservation(legalEntityCodeStr, auditTypeCode, groupObservationId);			
			if(auditObservation!=null){
				serviceStatus.setResult(auditObservation);
				serviceStatus.setStatus("success");
				serviceStatus.setMessage("successfully got the result ");
				
			}else {
				serviceStatus.setStatus("failure");
				serviceStatus.setMessage("No docs found ");
			}
			
		} catch (Exception e) {
			logger.error(e.getStackTrace());
			serviceStatus.setStatus("failure");
			serviceStatus.setMessage("failure");
		}
		return serviceStatus;
	}*/
	
	
@RequestMapping(value="/updateObservation", method=RequestMethod.PUT,consumes=MediaType.APPLICATION_JSON_VALUE,produces=MediaType.APPLICATION_JSON_VALUE)
	ServiceStatus updateObservation(@RequestBody AuditObservationDto auditObservationDto){
		ServiceStatus serviceStatus=new ServiceStatus();
		
		if(auditObservationDto!=null
				&& auditObservationDto.getAuditObservations()!=null
				&& !auditObservationDto.getAuditObservations().isEmpty()){
			try {
				
				serviceStatus.setResult(checklistService.updateObservation(auditObservationDto));
				serviceStatus.setStatus("success");
				serviceStatus.setMessage("successsfully updated");
			} catch (Exception e) {
				logger.error(e.getStackTrace());
				serviceStatus.setStatus("failure");
				serviceStatus.setMessage("failure");
			}
		}else {
			serviceStatus.setStatus("failure");
			serviceStatus.setMessage("at least one observation is required ");
		}
		
		return serviceStatus; 
	}
	
	
@RequestMapping(value="/getChapterDetailsOfChecklist" ,method=RequestMethod.GET,produces=MediaType.APPLICATION_JSON_VALUE)
	ServiceStatus getChapterDetailsOfChecklist(
			@RequestParam(value="legalEntityCode")String legalEntityCodeStr, 
			@RequestParam(value="auditTypeCode")String auditTypeCode,
			@RequestParam(value="auditId")String auditId,
			@RequestParam(value="observationId")String observationId,
			@RequestParam(value="groupObservationId")String groupObservationId){
		
		
		 ServiceStatus serviceStatus=new ServiceStatus();
			
			if(legalEntityCodeStr!=null && auditTypeCode!=null && auditId!=null
					&& observationId!=null && groupObservationId!=null){
				try {
					
					serviceStatus.setResult(checklistService.getChapterDetailsOfChecklist(legalEntityCodeStr, auditTypeCode, auditId, observationId, groupObservationId));
					serviceStatus.setStatus("success");
					serviceStatus.setMessage("success");
				} catch (Exception e) {
					logger.error(e.getStackTrace());
					serviceStatus.setStatus("failure");
					serviceStatus.setMessage("failure");
				}
			}else {
				serviceStatus.setStatus("failure");
				serviceStatus.setMessage("invalid Parameter");
			}			
		 
		 return serviceStatus;
	}
	
	/*
@RequestMapping(value="/getDynamicValues",method=RequestMethod.GET,produces=MediaType.APPLICATION_JSON_VALUE)
	ServiceStatus getActivityProcessFindingMappingValues( 
			@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;
	}*/

	
	/*
@RequestMapping(value = "/getAllChecklistForDownload", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
	DataTableResponse getAllChecklistForDownload(
			@RequestParam("legalEntityCode")String legalEntityCodeStr,
			@RequestParam("auditId")String auditId,
			@RequestParam("planId")String planId,
			@RequestParam("auditTypeCode")String auditTypeCode,
			@RequestParam("userId")String userId,
			@RequestParam(value="role", required=false)String role){

		DataTableResponse dataTableResponse = null;
		List<String> listData=null;
		if (!BankAuditUtil.isEmptyString(auditId) && !BankAuditUtil.isEmptyString(auditTypeCode)
				&& !BankAuditUtil.isEmptyString(legalEntityCodeStr)) {
			try {
				logger.info("" +legalEntityCodeStr+" :: " +auditId + " :: "+planId +" :: "+ auditTypeCode+" :: "+role);
				Integer legalEntityCode = Integer.parseInt(legalEntityCodeStr);
				dataTableResponse = checklistService.getAllChecklistForDownload(legalEntityCodeStr, auditId, auditTypeCode, role);
				//dataTableResponse.setDraw(draw);

			} catch (Exception e) {
				e.printStackTrace(System.out);
				dataTableResponse = new DataTableResponse();
				dataTableResponse.setError(e.getMessage());
				logger.error(e.getStackTrace());
			}

		} else {
			dataTableResponse = new DataTableResponse();
			dataTableResponse.setError("invalid data");
		}

		//return listData;
		return dataTableResponse;
	}*/
	
	
@RequestMapping(value = "/getAllChecklistForDownload", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
	void getAllChecklistForDownload( 
			@RequestParam("search[value]") String search,			 
			@RequestParam("legalEntityCode")String legalEntityCodeStr,
			@RequestParam("auditId")String auditId, 
			@RequestParam("auditTypeCode")String auditTypeCode, 
			@RequestParam("auditGroupCode")String auditGroupCode,
			@RequestParam("auditSubGroupCode")String auditSubGroupCode,
			@RequestParam("activityCode")String activityCode,
			@RequestParam("processCode")String processCode,
			@RequestParam("complianceCategory")String complianceCategory,
			@RequestParam(value="submissionStatus", required=false)String submissionStatus,
			@RequestParam(value="responseStatus", required=false)String responseStatus,
			@RequestParam(value="reviewStatus", required=false)String reviewStatus,
			@RequestParam(value="flag", required=false)String flag,
			@RequestParam(value="criticalityToggle", required=false)String criticalityToggle,
			@RequestParam(value="reportRvwFedbk", required=false)String reportRvwFedbk,
			@RequestParam(value="role", required=false)String role,
			@RequestParam(value="documentType", required=false)String documentType,
			@RequestParam(value="documentSubType", required=false)String documentSubType,
			@RequestParam(value="nonCompliancePersistence", required=false)String nonCompliancePersistence,
			@RequestParam("reportLanguage")String reportLanguage,
			@RequestParam("userId")String userId,
			HttpServletRequest request,      HttpServletResponse response){

		if(!BankAuditUtil.isEmptyString(legalEntityCodeStr) && (auditId!=null && !BankAuditUtil.isEmptyString(auditId)) ){ 
			try { 	 
				
				ByteArrayOutputStream byteData = checklistService.exportChecklistToExcel(legalEntityCodeStr, auditId, auditTypeCode, auditGroupCode, 
						 auditSubGroupCode, activityCode, processCode, search, complianceCategory, submissionStatus, responseStatus, reviewStatus, 
						 flag, criticalityToggle, reportRvwFedbk, role, documentType, documentSubType, nonCompliancePersistence, reportLanguage); 
					
				if(byteData!=null){ 	
					 String fileName = "CheckList_"+auditId+"_"+legalEntityCodeStr+".xlsx"; 	 					
					 String mimeType ="application/vnd.ms-excel";  						 
		             response.setContentType(mimeType); 
		             String headerKey = "Content-Disposition";
		             String headerValue = String.format("attachment; filename=\"%s\"", fileName);
		             response.setHeader(headerKey, headerValue); 
		             OutputStream outStream = response.getOutputStream();
		             outStream.write(byteData.toByteArray());		    
		             outStream.close();               
		    	}else {
					 response.getWriter().print("Document not exist");
				}			     
			} catch (Exception e) {
				e.printStackTrace();					
			}
		}		
	} 
	
}
