package com.bankaudit.rest.process.controller;

import java.sql.Timestamp;
import java.time.LocalDate;

import org.jboss.logging.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.MediaType;
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.process.AuditDto;
import com.bankaudit.process.model.AuditSchedule;
import com.bankaudit.rest.process.service.AuditReviewService;
import com.bankaudit.rest.process.service.MyAuditsService;
import com.bankaudit.service.BusinessDateService;
import com.bankaudit.util.BankAuditUtil;
import com.bankaudit.util.ServiceStatus;



@RestController

@RequestMapping("/api/auditReview")
public class AuditReviewController {

	@Autowired
	AuditReviewService auditReviewService;
	ServiceStatus serviceStatus;
	
	@Autowired
	MyAuditsService myAuditsService;
	
	@Autowired
	BusinessDateService businessDateService;
	
	static final Logger logger = Logger.getLogger(AuditReviewController.class);
	
	
@RequestMapping(value = "/getMyReview", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
	DataTableResponse getAuditReview(
			@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("userId")String userId,
			@RequestParam(required = false, value = "financialYear") @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate financialYear,
			@RequestParam(required = false, value = "auditTypeCode") String auditTypeCode){

		DataTableResponse dataTableResponse = null;

		if (!BankAuditUtil.isEmptyString(drawStr) && !BankAuditUtil.isEmptyString(length)
				&& !BankAuditUtil.isEmptyString(start)) {
			try {
				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);
				}
				logger.info("Inside getAuditReview legalEntityCode:: "+legalEntityCodeStr +" userId:: "+ userId+" financialYear:: "+financialYear+" auditTypeCode::"+auditTypeCode);
				dataTableResponse = auditReviewService.getMyReviewList(Integer.parseInt(legalEntityCodeStr),userId,search, orderColumn, orderDirection, page, size, financialYear, auditTypeCode);
				logger.info("Inside controller dataTableResponse .... "+dataTableResponse);
				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;
	}
	
	
@RequestMapping(value="/getReviewByPlanIdAndAuditId/{legalEntityCode}/{auditTypeCode}/{planId}/{auditId}",method=RequestMethod.GET,produces=MediaType.APPLICATION_JSON_VALUE)
	ServiceStatus getReviewByPlanIdAndAuditId(
			@PathVariable("legalEntityCode") Integer legalEntityCode,
			@PathVariable("auditTypeCode") String auditTypeCode,
			@PathVariable("planId") String planId,
			@PathVariable("auditId")String auditId){
		ServiceStatus serviceStatus=new ServiceStatus();
		
		if(legalEntityCode!=null
				&& !BankAuditUtil.isEmptyString(auditTypeCode) && !BankAuditUtil.isEmptyString(planId) && !BankAuditUtil.isEmptyString(auditId)){
			try {
				AuditSchedule auditDtl=auditReviewService.getReviewAuditByPlanIdAndAuditId(legalEntityCode,auditTypeCode,planId,auditId); 
				
				if(auditDtl!=null){
					serviceStatus.setResult(auditDtl);
					serviceStatus.setStatus("success");
					serviceStatus.setMessage("successfuly retrieved ");
				}else {
					serviceStatus.setStatus("failure");
					serviceStatus.setMessage("ids not found");
				}
				
			} catch (Exception e) {
				serviceStatus.setStatus("failure");
				serviceStatus.setMessage("failure");
				e.printStackTrace();
			}
			
		}else {
			serviceStatus.setStatus("failure");
			serviceStatus.setMessage("invalid parameter");
		}
				return serviceStatus;
	}
	
	
@RequestMapping(method = RequestMethod.PUT, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
	ServiceStatus updateMyReviewStatus(@RequestBody AuditSchedule auditSchedule) {
		ServiceStatus serviceStatus = new ServiceStatus();

		if (auditSchedule != null && auditSchedule.getLegalEntityCode() != null
				&& !BankAuditUtil.isEmptyString(auditSchedule.getAuditTypeCode())
				&& !BankAuditUtil.isEmptyString(auditSchedule.getPlanId())
				&& !BankAuditUtil.isEmptyString(auditSchedule.getAuditId())
				&& !BankAuditUtil.isEmptyString(auditSchedule.getRespondStatus())
				&& !BankAuditUtil.isEmptyString(auditSchedule.getMaker())) {
			try {
				logger.info("LegalEntCode:: "+auditSchedule.getLegalEntityCode()+" AuditType:: "+auditSchedule.getAuditTypeCode()+" PanId:: "+auditSchedule.getPlanId() +" AuditId:: "+auditSchedule.getAuditId()+ " audit Status :: "+auditSchedule.getAuditStatus());
				auditSchedule.setBusinessdateTimestamp(businessDateService.getBusinessDateTimestampByLegalEntityCode(auditSchedule.getLegalEntityCode()));
				auditSchedule.setSysdateTimestamp(new Timestamp(System.currentTimeMillis()));
				auditSchedule.setMakerTimestamp(auditSchedule.getBusinessdateTimestamp());
				
				logger.info("ReviewStatus .. "+auditSchedule.getReviewStatus() +"RespStatus .. " +auditSchedule.getRespondStatus() +" ObsSts.. "+ auditSchedule.getObservationStatus());
				if(("WS").equalsIgnoreCase(auditSchedule.getReviewStatus())) { //instead of auditStatus, compared with RespondStatus
					if("AS".equalsIgnoreCase(auditSchedule.getObservationStatus()) && "RS".equalsIgnoreCase(auditSchedule.getRespondStatus())) {
						String isReviewObsPendingBfrReviewSubmit= "N";
						AuditDto auditDto = new AuditDto();
						auditDto.setLegalEntityCode(auditSchedule.getLegalEntityCode());
						auditDto.setAuditId(auditSchedule.getAuditId());
						auditDto.setAuditTypeCode(auditSchedule.getAuditTypeCode());
						
						isReviewObsPendingBfrReviewSubmit= myAuditsService.isAuditObsPending(auditDto, "WS");
						logger.info("isReviewObsPendingBfrReviewSubmit:: "+ isReviewObsPendingBfrReviewSubmit);
						if(isReviewObsPendingBfrReviewSubmit.equals("N")) {
							logger.info("in sts N:: "+ isReviewObsPendingBfrReviewSubmit);
							auditReviewService.updateAuditReviewStatus(auditSchedule);
							serviceStatus.setStatus("success");
							serviceStatus.setMessage("successfully updated");
						}else {
							serviceStatus.setStatus("failure");
							serviceStatus.setMessage("Please attend all the Non compliance checklists, before submitting the Scrutiny.");
						}
					}else {
						serviceStatus.setStatus("failure");
						serviceStatus.setMessage("Please submit the Inspection & Compliance before submitting the Scrutiny.");
					}
				}else if(("WI").equalsIgnoreCase(auditSchedule.getReviewStatus())) {
					auditReviewService.updateAuditReviewStatus(auditSchedule);
					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;
	}
	
	
@RequestMapping(value ="/updateScrutinyReviewer", method = RequestMethod.PUT, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
	ServiceStatus updateScrutinyReviewer(@RequestBody AuditSchedule auditSchedule) {
		ServiceStatus serviceStatus = new ServiceStatus();
		  
		if (auditSchedule != null && auditSchedule.getLegalEntityCode() != null
				&& !BankAuditUtil.isEmptyString(auditSchedule.getAuditTypeCode())
				&& !BankAuditUtil.isEmptyString(auditSchedule.getPlanId())
				&& !BankAuditUtil.isEmptyString(auditSchedule.getAuditId())
				&& !BankAuditUtil.isEmptyString(auditSchedule.getRespondStatus())
				&& !BankAuditUtil.isEmptyString(auditSchedule.getMaker())) {
			try {
				logger.info("LegalEntCode:: "+auditSchedule.getLegalEntityCode()+" AuditType:: "+auditSchedule.getAuditTypeCode()+" PanId:: "+auditSchedule.getPlanId() +" AuditId:: "+auditSchedule.getAuditId()+ " audit Status :: "+auditSchedule.getAuditStatus());
				logger.info("AuditStatus .. "+auditSchedule.getAuditStatus() +" ReviewerId .. " +auditSchedule.getReviewerId());
				 	auditReviewService.updateAuditReviewerId(auditSchedule);
					serviceStatus.setStatus("success");
					serviceStatus.setMessage("successfully updated the reviewer");				
			} 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;
	}
	
	
@RequestMapping(value = "/updateAuditClosureStatus",method = RequestMethod.PUT, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
	ServiceStatus updateAuditClosureStatus(@RequestBody AuditSchedule auditSchedule) {
		ServiceStatus serviceStatus = new ServiceStatus();

		if (auditSchedule != null && auditSchedule.getLegalEntityCode() != null
				&& !BankAuditUtil.isEmptyString(auditSchedule.getAuditTypeCode())
				&& !BankAuditUtil.isEmptyString(auditSchedule.getPlanId())
				&& !BankAuditUtil.isEmptyString(auditSchedule.getAuditId())
				&& !BankAuditUtil.isEmptyString(auditSchedule.getRespondStatus())
				&& !BankAuditUtil.isEmptyString(auditSchedule.getMaker())) {
			try {
				logger.info("Inside updateAuditClosureStatus LE:: "+auditSchedule.getLegalEntityCode()+" AuditType:: "+auditSchedule.getAuditTypeCode()+" PanId:: "+auditSchedule.getPlanId() +" AuditId:: "+auditSchedule.getAuditId()+ " audit Status :: "+auditSchedule.getAuditStatus());
				logger.info("AuditStatus .. "+auditSchedule.getAuditStatus() +" ClosureUserId .. " +auditSchedule.getClosureUserId());
				if(("AC").equalsIgnoreCase(auditSchedule.getAuditStatus())) { // Included as part of BaaS, for closure  // verifying during closure
					
					String isReviewObsPendingBfrAuditClosure= "N";
					AuditDto auditDto = new AuditDto();
					auditDto.setLegalEntityCode(auditSchedule.getLegalEntityCode());
					auditDto.setAuditId(auditSchedule.getAuditId());
					auditDto.setAuditTypeCode(auditSchedule.getAuditTypeCode());
					
					isReviewObsPendingBfrAuditClosure= myAuditsService.isAuditReviewPending(auditDto, "AC");
					logger.info("isReviewObsPendingBfrAuditClosure:: "+ isReviewObsPendingBfrAuditClosure);
					if(isReviewObsPendingBfrAuditClosure.equals("N")) {
						auditReviewService.updateAuditClosureStatus(auditSchedule);
						serviceStatus.setStatus("success");
						serviceStatus.setMessage("successfully updated");
					}else {
						serviceStatus.setStatus("failure");
						serviceStatus.setMessage("An inspection is closed only when all observations are either in the \"Carry forward\" or \"Accepted\" stage.");
					}					
					
				}else {
					serviceStatus.setStatus("failure");
					serviceStatus.setMessage("The Inspection status suppose to be Closed");
				}
				
			} 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;
	}
	
	
@RequestMapping(value = "/getReviewObservations", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
	DataTableResponse getReviewObservations(
			@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){

		DataTableResponse dataTableResponse = null;

		if (!BankAuditUtil.isEmptyString(drawStr) && !BankAuditUtil.isEmptyString(length)
				&& !BankAuditUtil.isEmptyString(start)) {
			try {
				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);
				}
				System.out.println("legalEntityCode:: "+legalEntityCodeStr +" auditId:: "+ auditId+" planId:: "+planId);
				dataTableResponse = auditReviewService.getReviewObservationList(Integer.parseInt(legalEntityCodeStr),planId,auditId,search, orderColumn, orderDirection, page, size);
				System.out.println("Inside controller dataTableResponse .... "+dataTableResponse);
				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;
	}
	
	
@RequestMapping(value="/isRatingsGiven",method=RequestMethod.GET,produces=MediaType.APPLICATION_JSON_VALUE) 
	ServiceStatus isRatingsGiven(
			@RequestParam("legalEntityCode")String legalEntityCodeStr,
			@RequestParam("auditId") String auditId
			){
		ServiceStatus serviceStatus=new ServiceStatus();
				
		if(!BankAuditUtil.isEmptyString(legalEntityCodeStr)){
			try {
				Integer legalEntityCode=Integer.parseInt(legalEntityCodeStr);
				String isRatingsGiven = auditReviewService.isRatingsGiven(legalEntityCode,auditId); 
				if(isRatingsGiven !=null && isRatingsGiven.equalsIgnoreCase(BankAuditConstant.SUCCESS)){
					serviceStatus.setStatus("success");
					serviceStatus.setMessage("successfuly retrieved");
				}else if(BankAuditConstant.VALIDATION_FAILED.equalsIgnoreCase(isRatingsGiven)){
					serviceStatus.setStatus("modified");
					serviceStatus.setMessage("The modified rating awaiting approval, you want to proceed with overriding with the current Approved rating?");
				}else {
					serviceStatus.setStatus("failure");
					serviceStatus.setMessage("The desk compliance rating not yet given. ");
				}
					
			} catch (Exception e) {
				serviceStatus.setStatus("failure");
				serviceStatus.setMessage("failure");
				e.printStackTrace();
			}
		
		}else {
			serviceStatus.setStatus("failure");
			serviceStatus.setMessage("invalid payload");
		}
		return serviceStatus;
	}
	
	
@RequestMapping(value="/deleteDeskComplianceDataFromWrkTmp/{legalEntityCode}/{auditTypeCode}/{planId}/{auditId}",method=RequestMethod.DELETE,produces=MediaType.APPLICATION_JSON_VALUE)
	ServiceStatus deleteDeskComplianceDataFromWrkTmp(
			@PathVariable("legalEntityCode") Integer legalEntityCode,
			@PathVariable("auditTypeCode") String auditTypeCode,
			@PathVariable("planId") String planId,
			@PathVariable("auditId")String auditId 
			){
		ServiceStatus serviceStatus=new ServiceStatus();
		if(legalEntityCode!=null
				&& !BankAuditUtil.isEmptyString(auditTypeCode) && !BankAuditUtil.isEmptyString(planId) && !BankAuditUtil.isEmptyString(auditId)){
			try {
					auditReviewService.deleteDeskComplianceDataFromWrkTmp(legalEntityCode,auditTypeCode,planId,auditId); 				 
					serviceStatus.setStatus("success");
					serviceStatus.setMessage("successfully deleted the modified record");
				 
			}catch (Exception e) {
				serviceStatus.setStatus("failure");
				serviceStatus.setMessage("failure");
				e.printStackTrace();
			}
		}else {
			serviceStatus.setStatus("failure");
			serviceStatus.setMessage("invalid parameter");
		}
		return serviceStatus;
	}
	
}
