package com.bankaudit.template.rest.controller;

import java.io.*;
import java.util.Date;
import java.util.List;

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

import com.bankaudit.model.ExcelUploadDataStatus;
import com.bankaudit.service.ExcelMaintEntityService;
import com.bankaudit.service.MaintAddressService;
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.service.BusinessDateService;
import com.bankaudit.template.model.MaintTemplateDtls;
import com.bankaudit.template.model.UploadStatus;
import com.bankaudit.template.rest.service.UploadDownloadService;
import com.bankaudit.util.BankAuditUtil;
import com.bankaudit.util.ServiceStatus;



@RestController

@RequestMapping("/api/uploadDownload")
public class UploadDownloadController {
	
	@Autowired
	BusinessDateService businessDateService;
	
	@Autowired
	UploadDownloadService uploadDownloadService;

	@Autowired
	MaintAddressService maintAddressService;

	@Autowired
	ExcelMaintEntityService excelMaintEntityService;

	private static final int BUFFER_SIZE = 4096;
	static final Logger logger = Logger.getLogger(UploadDownloadController.class);
	
	ServiceStatus serviceStatus=null;
	
	
@RequestMapping(value="/loadUploadTemplate" ,method=RequestMethod.POST,consumes=MediaType.MULTIPART_FORM_DATA_VALUE,produces=MediaType.APPLICATION_JSON_VALUE)
	ServiceStatus uploadTemplate(
			@RequestParam(value="maker", required=false)String maker,
			@RequestParam(value="role", required=false)String role,
			@RequestParam(value="tableName", required=false)String tableName,
			@RequestParam(value="files", required=false)CommonsMultipartFile[] files,
			@RequestParam(value="legalEntityCode", required=false)Integer legalEntityCode) {
    	serviceStatus = new ServiceStatus();
    	String message="";
    	try {
    		if (files==null) {
    			message=" No file is attached to upload.";
    		}else if(maker==null || "".equals(maker)){
    			message=" In valied Maker.";
    		}else if(role==null || "".equals(role)) {
    			message=" In valied Role.";
    		}else if(tableName==null || "".equals(tableName)) {
    			message=" In valied Template name.Please select template from Lov to uploaded.";
    		}else if(legalEntityCode==null || legalEntityCode<0) {
    			message=" In valied LegalEntity.";
    		}else {			
    			for ( CommonsMultipartFile commonsMultipartFile : files) {
    				if(commonsMultipartFile.getContentType()!=null && !BankAuditUtil.validateFileType(commonsMultipartFile, BankAuditConstant.DOC_TYPES) && 
    						!"xls".equals(BankAuditUtil.getFileExtension(commonsMultipartFile.getOriginalFilename()))){
    					message="file type : "+BankAuditUtil.getFileExtension(commonsMultipartFile.getOriginalFilename())+" not supported, Please upload xls files only.";
    				}else if ("".equals(message)  ) {
    					Date businessDate=businessDateService.getBusinessDateTimestampByLegalEntityCode(legalEntityCode);
    					//message=fileUploadReadTemplateService.readTemplate(commonsMultipartFile,tableName,maker,businessDate);
    				}
    			}
    		}
    		if(!"".equals(message)) {
    			serviceStatus.setStatus("failure");
    			serviceStatus.setMessage(message);
    		}else {
    			serviceStatus.setStatus("success");
    			serviceStatus.setMessage("successsfully uploaded...");
    		}
    	}catch (Exception e) {
    		e.printStackTrace();
    		serviceStatus.setStatus("failure");
    		serviceStatus.setMessage(e.getMessage());
    	}
    	return serviceStatus;
    }	
	
	
@RequestMapping(value="/getAllUploadStatus",method=RequestMethod.GET,produces=MediaType.APPLICATION_JSON_VALUE) 
	DataTableResponse getAllUploadStatus(
			@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(required=false)String type
			){
		
		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 = uploadDownloadService.getAllUploadStatus(legalEntityCode,search,orderColumn,orderDirection,page,size,type);
				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="/updateUserFromExcel" ,method=RequestMethod.POST,consumes=MediaType.MULTIPART_FORM_DATA_VALUE,produces=MediaType.APPLICATION_JSON_VALUE)
	ServiceStatus updateUserFromExcel(@RequestParam("legalEntityCode")Integer legalEntityCode, @RequestParam("userId")String userId,
			@RequestParam(value="userFile")CommonsMultipartFile userFile){
		ServiceStatus serviceStatus=new ServiceStatus();
		
		try {
			String status = uploadDownloadService.updateUserFromExcel(legalEntityCode, userId, userFile);
			serviceStatus.setStatus(status);
			serviceStatus.setMessage("user data successsfully updated");			
		} catch (Exception e) {
			e.printStackTrace();
			serviceStatus.setStatus("failure");
			serviceStatus.setMessage("failure");
		}
		
		return serviceStatus; 		
	}
	
	
@RequestMapping(value="/updatePlanFromExcel" ,method=RequestMethod.POST,consumes=MediaType.MULTIPART_FORM_DATA_VALUE,produces=MediaType.APPLICATION_JSON_VALUE)
	ServiceStatus updatePlanFromExcel(@RequestParam("legalEntityCode")Integer legalEntityCode, @RequestParam("userId")String userId,
			@RequestParam(value="userFile")CommonsMultipartFile planFile){
		ServiceStatus serviceStatus=new ServiceStatus();
		
		try {
			String status = uploadDownloadService.updatePlanFromExcel(legalEntityCode, userId, planFile);
			serviceStatus.setStatus(status);
			serviceStatus.setMessage("user data successsfully updated");			
		} catch (Exception e) {
			e.printStackTrace();
			serviceStatus.setStatus("failure");
			serviceStatus.setMessage("failure");
		}
		
		return serviceStatus; 		
	}
	
	
@RequestMapping(value="/downloadDocument",method = RequestMethod.GET)
    public void  downloadProfileFormat(
    		@RequestParam(value="id",required=true)Integer id,
    		@RequestParam(value="legalEntityCode",required=true)Integer legalEntityCode,
    		@RequestParam(value="userId",required=true)String userId,
    		
    		HttpServletRequest request,
            HttpServletResponse response) throws IOException {    	
    	
    	ServletContext context=request.getServletContext();
    	UploadStatus uploadStatus=uploadDownloadService.getUploadStatusById(legalEntityCode, id);
    	if(uploadStatus!=null){
			String filePath=uploadStatus.getReferencePath();
		    	if(!BankAuditUtil.isEmptyString(filePath)){
		    		File file=new File(filePath);
		    		if(file.isFile()){
		    			 FileInputStream inputStream = new FileInputStream(file);

		    			 String mimeType = context.getMimeType(filePath); // get MIME type of the file
		                 
		                 if (mimeType == null) {
		                     mimeType = "application/octet-stream"; // set to binary type if MIME mapping not found
		                 }
		              
		                 // 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("attachment; filename=\"%s\"",file.getName());
		                 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");
			}
    		
    }

	
@RequestMapping(value = "/excel-upload", method = RequestMethod.POST, consumes = MediaType.MULTIPART_FORM_DATA_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
	ServiceStatus uploadEntityExcel(
			@RequestParam(value = "userId") String userId,
			@RequestParam(value = "dataType") String dataType,
			@RequestParam(value = "file") CommonsMultipartFile file,
			@RequestParam(value = "legalEntityCode") Integer legalEntityCode) {
		ServiceStatus serviceStatus = new ServiceStatus();
		try {
			logger.info(" uploadEntityExcel Controller .. ");
			ExcelUploadDataStatus resultStatus = uploadDownloadService.uploadEntityExcel(userId, dataType, file, legalEntityCode);
			serviceStatus.setStatus("success");
			serviceStatus.setResult(resultStatus);
			if (resultStatus.getFailureCount() == 0) {
				excelMaintEntityService.createTempMaintEntity(legalEntityCode, userId, resultStatus.getUploadId());// add documentId
				excelMaintEntityService.updateMaintEntityData(resultStatus.getUploadId());
				serviceStatus.setMessage("File Uploaded Successfully. Entity Data is Updated");
			} else {
				serviceStatus.setMessage("File uploaded Successfully, resolve errors and upload again");
			}
		} catch (Exception e) {
			e.printStackTrace();
			serviceStatus.setStatus("failure");
			serviceStatus.setMessage("failure");
		}
		return serviceStatus;
	}

	
@RequestMapping(value = "/get-uploaded-excel-response", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
	void getAllChecklistForDownload(
			@RequestParam("legalEntityCode")String legalEntityCodeStr,
			@RequestParam("userId")String userId,
			@RequestParam("fileName")String fileName,
			HttpServletRequest request,      HttpServletResponse response){

		if(!BankAuditUtil.isEmptyString(legalEntityCodeStr) ){
			try {

				ByteArrayOutputStream byteData = uploadDownloadService.exportUploadedDataToExcel(legalEntityCodeStr, userId, fileName);

				if(byteData!=null){
					String excelFileName = "CheckList_"+fileName+"_"+legalEntityCodeStr+".xlsx";
					String mimeType ="application/vnd.ms-excel";
					response.setContentType(mimeType);
					String headerKey = "Content-Disposition";
					String headerValue = String.format("attachment; filename=\"%s\"", excelFileName);
					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();
			}
		}
	}
	
	
@RequestMapping(value="/getTemplateDetails",method=RequestMethod.GET,produces=MediaType.APPLICATION_JSON_VALUE)
	ServiceStatus getTemplateDetails(
			@RequestParam("legalEntityCode") Integer legalEntityCode,
			@RequestParam(value="role",required=false) String role){
		ServiceStatus serviceStatus=new ServiceStatus();
		
		if(legalEntityCode!=null && !BankAuditUtil.isEmptyString(legalEntityCode.toString()) ){
			try {
				List<MaintTemplateDtls> tmpDtlsLst= null;
				tmpDtlsLst=uploadDownloadService.getTemplateDetails(legalEntityCode, role); 
				
				if(tmpDtlsLst!=null){
					serviceStatus.setResult(tmpDtlsLst);
					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(value="/downloadTemplate",method = RequestMethod.GET)
    public void  downloadTemplate(
    		@RequestParam(value="legalEntityCode",required=true)Integer legalEntityCode,  
    		@RequestParam(value="templateCode",required=true)String templateCode,	    		
    		HttpServletRequest request,
            HttpServletResponse response) throws IOException {    	
    	
    	ServletContext context=request.getServletContext();
    	String filePath =uploadDownloadService.getTemplateReferencePath(legalEntityCode, templateCode);
    	logger.info("filePath .."+filePath);
    	 	if(!BankAuditUtil.isEmptyString(filePath)){
		    		File file=new File(filePath);
		    		if(file.isFile()){
		    			
		    			 int BUFFER_SIZE = 4096;
		    			 FileInputStream inputStream = new FileInputStream(file);

		    			 String mimeType = context.getMimeType(filePath); // get MIME type of the file
		                 
		                 if (mimeType == null) {
		                     mimeType = "application/octet-stream"; // set to binary type if MIME mapping not found
		                 }
		              
		                 // 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("attachment; filename=\"%s\"",file.getName());
		                 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");
			}
   	}


}
