package com.bankaudit.rest.process.controller;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletContext;
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.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import com.bankaudit.constants.BankAuditConstant;
import com.bankaudit.dto.DataTableResponse;
import com.bankaudit.process.model.AuditDocumentDetails;
import com.bankaudit.rest.process.service.AuditOffsetService;
import com.bankaudit.util.BankAuditUtil;
import com.bankaudit.util.ServiceStatus;



@RestController

@RequestMapping("/api/auditOffset")
public class AuditOffsetController {
	@Autowired
	AuditOffsetService auditOffsetService;

	private static final int BUFFER_SIZE = 4096; 
	 
	static final Logger logger = Logger.getLogger(AuditOffsetController.class);

	
@RequestMapping(value = "/getAuditsforOffset", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
	DataTableResponse getAuditsforOffset(
			@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){

		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 +" userId:: "+ userId);
				dataTableResponse = auditOffsetService.getAuditsforOffset(Integer.parseInt(legalEntityCodeStr),userId,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 = "/uploadDocument", method = RequestMethod.POST, consumes = MediaType.MULTIPART_FORM_DATA_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
	ServiceStatus uploadDocument(@RequestParam(value = "legalEntityCode") String legalEntityCodeStr,
			@RequestParam(value = "auditTypeCode") String auditTypeCode,
			@RequestParam(value = "planId") String planId,
			@RequestParam(value = "auditId") String auditId,
			@RequestParam(value = "userId") String userId,
			@RequestParam(value = "documentName") String documentName,
			@RequestParam(value = "files") CommonsMultipartFile[] files) {

		Integer legalEntityCode = null;
		if (!BankAuditUtil.isEmptyString(legalEntityCodeStr)) {
			legalEntityCode = Integer.parseInt(legalEntityCodeStr);
		}

		ServiceStatus serviceStatus = new ServiceStatus();
		Map<String, Object> result = new HashMap<>();
		try {
			logger.info("Inside AuditOffSetController uploadDocument():: "+legalEntityCode + " auditTypeCode:: "+auditTypeCode+" planId:: "+planId+" auditId:: "+auditId+" userId:: "+userId);
			if (files != null) {
				List<AuditDocumentDetails> auditDocumentDetails = auditOffsetService
						.getAuditDocumentDetails(legalEntityCode, auditTypeCode, planId, auditId, userId);

				Boolean isWarning = false;
				String duplicateFileNames = "";

				for (CommonsMultipartFile commonsMultipartFile : files) {

					if (!BankAuditUtil.validateFileType(commonsMultipartFile, BankAuditConstant.DOC_TYPES)) {
						serviceStatus.setStatus("failure");
						serviceStatus.setMessage("file type : "
								+ BankAuditUtil.getFileExtension(commonsMultipartFile.getOriginalFilename())
								+ " not supported");
						return serviceStatus;
					}

					if (auditDocumentDetails != null) {
						String existingPath = "";
						for (AuditDocumentDetails auditDocumentDetail : auditDocumentDetails) {
							existingPath = auditDocumentDetail.getReferencePath();
							existingPath = existingPath.substring(existingPath.lastIndexOf("/") + 1);
							existingPath = existingPath.substring(existingPath.indexOf("_")+1);
							if (existingPath.equalsIgnoreCase(commonsMultipartFile.getOriginalFilename())) {
								isWarning = true;
								duplicateFileNames = duplicateFileNames + " "+ commonsMultipartFile.getOriginalFilename();
							}
						}
					}
				}
				if (isWarning) {
					serviceStatus.setStatus("warning");
					serviceStatus.setMessage("file " + duplicateFileNames + "  already exist , please delete before update ");
					return serviceStatus;
				}
				serviceStatus.setResult(auditOffsetService.uploadDocument(legalEntityCode, auditTypeCode, planId,auditId, userId, files, documentName));
				serviceStatus.setStatus("success");
				serviceStatus.setMessage("successfully uploaded");
			} else {
				serviceStatus.setStatus("failure");
				serviceStatus.setMessage("Invalid payload");
			}

		} catch (Exception e) {
			serviceStatus.setStatus("failure");
			serviceStatus.setMessage("failure");
		}
		return serviceStatus;
	}*/
	
	/*
@RequestMapping(value="/deleteAuditOffsetDocument" ,method=RequestMethod.DELETE,produces=MediaType.APPLICATION_JSON_VALUE)
	ServiceStatus  deleteAuditOffsetDocument(				  
			@RequestParam(value="legalEntityCode") Integer legalEntityCode, 
			@RequestParam(value="id") Integer id, 
			@RequestParam(value="auditTypeCode") String auditTypeCode, 
			@RequestParam(value="planId") String planId,
			@RequestParam(value="auditId") String auditId)  {
		ServiceStatus serviceStatus=new ServiceStatus();
		
		if(!BankAuditUtil.isEmptyString(auditTypeCode) && !BankAuditUtil.isEmptyString(auditId) 
				&& id!=null && id>0
				&& legalEntityCode!=null && legalEntityCode>0){
			try{
			   String updateStatus =	auditOffsetService.deleteAuditOffsetDocumentDetails(legalEntityCode, id, auditTypeCode, planId, auditId);
				if(updateStatus.equals(BankAuditConstant.SUCCESS)){
					serviceStatus.setStatus("success");
					serviceStatus.setMessage("successfully deleted the selected document");
				}else{
					serviceStatus.setStatus("failure");
					serviceStatus.setMessage("failed to delete the selected document");
				}
			}catch (Exception e) {
				logger.error(e.getStackTrace());
				serviceStatus.setStatus("failure");
				serviceStatus.setMessage("failure");
			}
		}else{
			serviceStatus.setStatus("failure");
			serviceStatus.setMessage("missing parameter value document id");
		} 			
		
		return serviceStatus;
	}
	*/
	
	/*
@RequestMapping(value = "/getAuditDocumentDetails", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
	ServiceStatus getAuditDocumentDetails(@RequestParam(value = "legalEntityCode") String legalEntityCodeStr,
			@RequestParam(value = "auditTypeCode") String auditTypeCode, @RequestParam(value = "planId") String planId,
			@RequestParam(value = "auditId") String auditId, @RequestParam(value = "userId") String userId) {
		ServiceStatus serviceStatus = new ServiceStatus();

		if (!BankAuditUtil.isEmptyString(legalEntityCodeStr) && !BankAuditUtil.isEmptyString(auditTypeCode)
				&& !BankAuditUtil.isEmptyString(planId) && !BankAuditUtil.isEmptyString(auditId)
				&& !BankAuditUtil.isEmptyString(userId)) {

			try {
				logger.info("Inside AuditOffSetController getAuditDocumentDetails():: "+legalEntityCodeStr + " auditTypeCode:: "+auditTypeCode+" planId:: "+planId+" auditId:: "+auditId+" userId:: "+userId);
				List<AuditDocumentDetails> auditAdhocDocuments = auditOffsetService.getAuditDocumentDetails(
						Integer.parseInt(legalEntityCodeStr), auditTypeCode, planId, auditId, userId);

				if (auditAdhocDocuments != null && !auditAdhocDocuments.isEmpty()) {
					serviceStatus.setResult(auditAdhocDocuments);
					serviceStatus.setStatus("success");
					serviceStatus.setMessage("successfully retrieved");
				} else {
					serviceStatus.setStatus("failure");
					serviceStatus.setMessage("no documents found ");
				}

			} catch (Exception e) {

				e.printStackTrace();
				serviceStatus.setStatus("failure");
				serviceStatus.setMessage("failure");

			}
		} else {

			serviceStatus.setStatus("failure");
			serviceStatus.setMessage("Invalid payload");
		}

		return serviceStatus;
	}*/
	
	
@RequestMapping(value = "/downloadDocumentById", method = RequestMethod.GET)
	public void downloadAuditAdhocDocument(@RequestParam(value = "id", required = true) Integer id,
			HttpServletRequest request, HttpServletResponse response) throws IOException {
		
		logger.info("Inside AuditOffSetController downloadAuditAdhocDocument():: id .. "+id );
		ServletContext context = request.getServletContext();
		AuditDocumentDetails auditDocumentDetails =auditOffsetService.getAuditDocumentDetailsById(id) ;

		if (auditDocumentDetails != null 
				&& !auditDocumentDetails.getStatus().equals("D")) {

			String filePath = auditDocumentDetails.getReferencePath();
			if (!BankAuditUtil.isEmptyString(filePath)) {
				File file = new File(filePath);
				if (file.isFile()) {
					FileInputStream inputStream = new FileInputStream(file);
					// get MIME type of the file
					String mimeType = context.getMimeType(filePath);
					if (mimeType == null) {
						// set to binary type if MIME mapping not found
						mimeType = "application/octet-stream";
					}
					// set content attributes for the response
					response.setContentType(mimeType);
					response.setContentLength((int) file.length());
					// set headers for the response
					String headerKey = "Content-Disposition";
					//String headerValue = String.format("inline; filename=\"%s\"", file.getName()); 
					String headerValue = String.format("attachment; filename=\"%s\"", file.getName()); //modified to attachment instead of inline to download all the files, instead of opening on the browser.
					response.setHeader(headerKey, headerValue);

					// get output stream of the response
					OutputStream outStream = response.getOutputStream();

					byte[] buffer = new byte[BUFFER_SIZE];
					int bytesRead = -1;

					// write bytes read from the input stream into the output
					// stream
					while ((bytesRead = inputStream.read(buffer)) != -1) {
						outStream.write(buffer, 0, bytesRead);
					}

					inputStream.close();
					outStream.close();

				} else {
					response.getWriter().print("Document not exist");
				}

			}

		} else {
			response.getWriter().print("Document not exist");
		}

	}
}
