package controller.rest;

import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

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

import org.apache.commons.io.IOUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
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.ResponseBody;

import com.fasterxml.jackson.databind.ObjectMapper;

import bean.AppVariables;
import bean.FiltroRicerceComplesse;
import bean.LogModificheBean;
import bean.filters.DisposizioniFiltroBean;
import bean.filters.RicercaDisposizioniFilterBean;
import bean.query.DisposizioniAeaDecoded;
import common.controller.BaseController;
import dao.DisposizioneAeaDAO;
import dao.DistintaBancaDAO;
import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.JRParameter;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import sicura.entities.DisposizioniAea;
import sicura.entities.DisposizioniRid;
import sicura.entities.DistintaBanca;
import utils.ConvalidaClass;
import utils.DettaglioErrori;

@Controller
@RequestMapping("DisposizioniAea")
public class DisposizioneAeaRestController extends BaseController {

	@Autowired
	DisposizioneAeaDAO disposizioniAeaDAO;
	
	@Autowired
	DistintaBancaDAO distintaBancaDAO;
	
	@Autowired
	ConvalidaClass convalidaClass;

	@RequestMapping(value="/{id}",method=RequestMethod.GET)
	@ResponseBody
	private ResponseEntity<Object> get(@PathVariable("id") Integer id, HttpServletRequest request) {
		try {
			setRequest(request);
			AppVariables appVariables = (AppVariables) getSessionAttribute("appVariables");
			if(getUserData()==null)
				return new ResponseEntity<Object>(HttpStatus.UNAUTHORIZED);
			else
				return new ResponseEntity<Object>(disposizioniAeaDAO.read(id), HttpStatus.OK);
		} catch(Exception ex) {
			AppVariables appVariables = (AppVariables) getSessionAttribute("appVariables");
			ex.printStackTrace();
			Logger.getRootLogger().error((appVariables!=null? appVariables.getUserId(): "utente sconosciuto: ") + ex);
			return new ResponseEntity<Object>(null, HttpStatus.INTERNAL_SERVER_ERROR);
		}
			
	}
	

	@RequestMapping(value="/list/{start:[\\d]+}-{length:[\\d]+}")
	@ResponseBody
	private ResponseEntity<List<DisposizioniAea>> list(HttpServletRequest request, 
				@PathVariable("start") int startFrom, 
				@PathVariable("length") int length,
				@RequestBody DisposizioniFiltroBean disposizioniFiltroBean
				) {
		try {
			setRequest(request);
			AppVariables appVariables = (AppVariables) getSessionAttribute("appVariables");
			if(getUserData()==null)
				return new ResponseEntity<List<DisposizioniAea>>(HttpStatus.UNAUTHORIZED);
			else
				return new ResponseEntity<List<DisposizioniAea>>(disposizioniAeaDAO.list(startFrom,length,disposizioniFiltroBean,getUserData().getOtherCode(), appVariables,getUserData().getLogin()), HttpStatus.OK);
		} catch(Exception ex) {
			AppVariables appVariables = (AppVariables) getSessionAttribute("appVariables");
			ex.printStackTrace();
			Logger.getRootLogger().error((appVariables!=null? appVariables.getUserId(): "utente sconosciuto: ") + ex);
			return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
		}

	}
	
	@RequestMapping(value="/count")
	@ResponseBody
	private ResponseEntity<Integer> count(HttpServletRequest request, @RequestBody DisposizioniFiltroBean disposizioniFiltroBean) {
		try {
			setRequest(request);
			AppVariables appVariables = (AppVariables) getSessionAttribute("appVariables");
			if(getUserData()==null)
				return new ResponseEntity<Integer>(HttpStatus.UNAUTHORIZED);
			else
				return new ResponseEntity<Integer>(disposizioniAeaDAO.count(disposizioniFiltroBean,getUserData().getOtherCode(),appVariables,getUserData().getLogin()), HttpStatus.OK);
		} catch(Exception ex) {
			AppVariables appVariables = (AppVariables) getSessionAttribute("appVariables");
			ex.printStackTrace();
			Logger.getRootLogger().error((appVariables!=null? appVariables.getUserId(): "utente sconosciuto: ") + ex);
			return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
		}			
	}
	
	
	@RequestMapping(value="/massDelete",method=RequestMethod.POST)
	@ResponseBody
	private ResponseEntity<Boolean> cancellazioneMassiva(HttpServletRequest request, @RequestBody DisposizioniFiltroBean disposizioniFiltroBean){
		Boolean res = false;
		try {
			setRequest(request);
			AppVariables appVariables = (AppVariables) getSessionAttribute("appVariables");
			if(getUserData()==null)
				return new ResponseEntity<Boolean>(HttpStatus.UNAUTHORIZED);
			else 
				res = disposizioniAeaDAO.cancellazioneMassiva(disposizioniFiltroBean, getUserData().getOtherCode(), getUserData(), appVariables);
			
			}
		finally {
			
		}
		return new ResponseEntity<Boolean>(res, HttpStatus.OK);
	}
	
	@RequestMapping(value="/export",method=RequestMethod.POST)
	private void export(@RequestBody DisposizioniFiltroBean disposizioniFiltroBean, HttpServletRequest request,HttpServletResponse response) throws Exception {
		setRequest(request);
		AppVariables appVariables = (AppVariables) getSessionAttribute("appVariables");
		if(getUserData()==null)
			response.sendError(401); // UNAUTHORIZED
		else {
			List<String> res= disposizioniAeaDAO.export(disposizioniFiltroBean,getUserData().getOtherCode(), appVariables,getUserData().getLogin());
			if (res.size()>1) {
				response.setContentType("text/csv");
				response.setHeader("Content-Disposition","attachment;filename=export.csv");
				ServletOutputStream out = response.getOutputStream();
				for (String str: res)
					out.println(str);
			    out.flush();
			    out.close();
			} else {
				response.setStatus(404); // not found
			}			    
		} 
	}

	@RequestMapping(value="/exportFiltered",method=RequestMethod.POST)
	private void exportFiltered(@RequestBody RicercaDisposizioniFilterBean ricercaDisposizioniFilterBean, HttpServletRequest request,HttpServletResponse response) throws Exception {
		setRequest(request);
		AppVariables appVariables = (AppVariables) getSessionAttribute("appVariables");
		if(getUserData()==null)
			response.sendError(401); // UNAUTHORIZED
		else {
			List<String> res= disposizioniAeaDAO.exportFiltered(ricercaDisposizioniFilterBean,getUserData().getOtherCode(), appVariables,getUserData().getLogin());
			if (res.size()>1) {
				response.setContentType("text/csv");
				response.setHeader("Content-Disposition","attachment;filename=export.csv");
				ServletOutputStream out = response.getOutputStream();
				for (String str: res)
					out.println(str);
			    out.flush();
			    out.close();
			} else {
				response.setStatus(404); // not found
			}			    
		} 
	}

	
	@RequestMapping(value="",method=RequestMethod.POST)
	@ResponseBody
	private ResponseEntity<Object> save(HttpServletRequest request, @RequestBody DisposizioniAea disposizione) {
		try {
			setRequest(request);
			AppVariables appVariables = (AppVariables) getSessionAttribute("appVariables");
			if(getUserData()==null)
				return new ResponseEntity<Object>(HttpStatus.UNAUTHORIZED);
			else {
				disposizione.setFlagStampa(false);
				try {
					
					ObjectMapper oMapper = new ObjectMapper();
					Map<String, Object> DisposizioniAea = oMapper.convertValue(disposizione, Map.class);
					
					try {
						DettaglioErrori errori = convalidaClass.eseguiConvalida(appVariables, 1, "AEA",DisposizioniAea, true, true);
						 disposizione = oMapper.convertValue(DisposizioniAea, DisposizioniAea.class);
					} catch (Exception e) {
						// TODO Auto-generated catch block  disposizione.get("importo")   disposizione.get("flagImporto") disposizioneRid.isFlagImporto()
						e.printStackTrace();
					}
					
					int res = disposizioniAeaDAO.save(disposizione, getUserData(), appVariables);
					if (res==0)
						return new ResponseEntity<Object>(disposizione, HttpStatus.OK);
					else
						return new ResponseEntity<Object>(res, HttpStatus.INTERNAL_SERVER_ERROR);
					
				} catch (Exception ex) {
					return new ResponseEntity<Object>(ex.getLocalizedMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
				}
			}
		} catch(Exception ex) {
			AppVariables appVariables = (AppVariables) getSessionAttribute("appVariables");
			ex.printStackTrace();
			Logger.getRootLogger().error((appVariables!=null? appVariables.getUserId(): "utente sconosciuto: ") + ex);
			return new ResponseEntity<Object>(null, HttpStatus.INTERNAL_SERVER_ERROR);
		}
	}
	
	
	@RequestMapping(value="/filter/{start:[\\d]+}-{length:[\\d]+}")
	@ResponseBody
	private ResponseEntity<Object> filter(
			@PathVariable("start") int startFrom, 
			@PathVariable("length") int length,
			@RequestParam(value="orderField", required=false) String orderField,
			@RequestBody FiltroRicerceComplesse filtro, 
			HttpServletRequest request) {
		try {
			setRequest(request);
			if(getUserData()==null)
				return new ResponseEntity<Object>(HttpStatus.UNAUTHORIZED);
			else
				return new ResponseEntity<Object>(disposizioniAeaDAO.filter(startFrom, length, orderField, filtro.getFiltroRicerca(), filtro.getFiltro()),HttpStatus.OK);
		} catch(Exception ex) {
			AppVariables appVariables = (AppVariables) getSessionAttribute("appVariables");
			ex.printStackTrace();
			Logger.getRootLogger().error((appVariables!=null? appVariables.getUserId(): "utente sconosciuto: ") + ex);
			return new ResponseEntity<Object>(null, HttpStatus.INTERNAL_SERVER_ERROR);
		}
			
	}
	
	
	@RequestMapping(value="/countfilter")
	@ResponseBody
	private ResponseEntity<Integer> countFilter(@RequestBody FiltroRicerceComplesse filtro, HttpServletRequest request) {
		try {
			setRequest(request);
			if(getUserData()==null)
				return new ResponseEntity<Integer>(HttpStatus.UNAUTHORIZED);
			else
				return new ResponseEntity<Integer>(disposizioniAeaDAO.countFilter(filtro.getFiltroRicerca(), filtro.getFiltro()),HttpStatus.OK);
		} catch(Exception ex) {
			AppVariables appVariables = (AppVariables) getSessionAttribute("appVariables");
			ex.printStackTrace();
			Logger.getRootLogger().error((appVariables!=null? appVariables.getUserId(): "utente sconosciuto: ") + ex);
			return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
		}
			
	}
	
	
	

	@RequestMapping(value="/logStati/{id}")
	@ResponseBody
	private ResponseEntity<List<LogModificheBean>> logStati(HttpServletRequest request, @PathVariable("id") Integer id) {
		try {
			setRequest(request);
			AppVariables appVariables = (AppVariables) getSessionAttribute("appVariables");
			if(getUserData()==null)
				return new ResponseEntity<List<LogModificheBean>>(HttpStatus.UNAUTHORIZED);
			else
				return new ResponseEntity<List<LogModificheBean>>(disposizioniAeaDAO.logStati(id), HttpStatus.OK);
		} catch(Exception ex) {
			AppVariables appVariables = (AppVariables) getSessionAttribute("appVariables");
			ex.printStackTrace();
			Logger.getRootLogger().error((appVariables!=null? appVariables.getUserId(): "utente sconosciuto: ") + ex);
			return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
		}
	}

	@RequestMapping(value="/logVariazioni/{id}")
	@ResponseBody
	private ResponseEntity<List<LogModificheBean>> logVariazioni(HttpServletRequest request, @PathVariable("id") Integer id) {
		try {
			setRequest(request);
			if(getUserData()==null)
				return new ResponseEntity<List<LogModificheBean>>(HttpStatus.UNAUTHORIZED);
			else
				return new ResponseEntity<List<LogModificheBean>>(disposizioniAeaDAO.logVariazioni(id), HttpStatus.OK);
		} catch(Exception ex) {
			AppVariables appVariables = (AppVariables) getSessionAttribute("appVariables");
			ex.printStackTrace();
			Logger.getRootLogger().error((appVariables!=null? appVariables.getUserId(): "utente sconosciuto: ") + ex);
			return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
		}
	}
	
	@RequestMapping(value="/print",method=RequestMethod.POST)
	private void print(@RequestBody DisposizioniFiltroBean disposizioniFiltroBean, HttpServletRequest request,HttpServletResponse response) throws Exception {
		setRequest(request);
		AppVariables appVariables = (AppVariables) getSessionAttribute("appVariables");
		if(getUserData()==null)
			response.sendError(401); // UNAUTHORIZED
		else {
			List<DisposizioniAeaDecoded> disposizioni = disposizioniAeaDAO.listDecoded(disposizioniFiltroBean,getUserData().getOtherCode(), appVariables,getUserData().getLogin());
			
			if (disposizioni.size()>0) {
				JRDataSource dsDisposizioni = new JRBeanCollectionDataSource(disposizioni);
				
	//			JasperDesign design = JRXmlLoader.load(request.getSession().getServletContext().getRealPath("/")+"Reports/repDisposizioniRid.jrxml");
	//			JasperReport report =  JasperCompileManager.compileReport(design);
	
				String appPath = request.getSession().getServletContext().getRealPath("/");
				if (!appPath.endsWith("/"))
					appPath += "/";
				
				HashMap<String, Object> reportParams = new HashMap<String, Object>();
				
				if ("DistinteBanca".equalsIgnoreCase(disposizioniFiltroBean.getTipoChiamata())) {
					DistintaBanca distinta = distintaBancaDAO.getByIdDistintaBanca(disposizioniFiltroBean.getIdDistintaBanca());
					if (distinta!=null) {
						if (distinta.getDenominazioneDelegatoFirma()!=null)
							reportParams.put("delegatoAllaFirma", "Delegato alla firma: " + distinta.getDenominazioneDelegatoFirma());
						reportParams.put("numeroDistinta","N. distinta banca: "+  distinta.getIddistintaBanca());
						reportParams.put("flagBir", distinta.isFlagBir());
						reportParams.put("abiCabConto", String.format("ABI: %s CAB: %s Conto: %s",
								(distinta.getCodiceAbiOrdinante()!=null?	distinta.getCodiceAbiOrdinante():" "), 
								(distinta.getCabOrdinante()!=null?distinta.getCabOrdinante(): " "),
								(distinta.getContoOrdinante()!=null?distinta.getContoOrdinante(): " ")));
						reportParams.put("checkimage", appPath+"img/checkbox.png");
						reportParams.put("uncheckimage", appPath+"img/uncheckbox.png");
					}
				}			
				ServletOutputStream out = response.getOutputStream();
				
				java.util.Locale locale = new Locale( "it", "IT" );
				reportParams.put( JRParameter.REPORT_LOCALE, locale );
				
				JasperPrint jasperPrint = JasperFillManager.fillReport(appPath+"Reports/repDisposizioniAea.jasper" ,reportParams, dsDisposizioni);
				JasperExportManager.exportReportToPdfStream(jasperPrint, out);
				
				response.setContentType("application/pdf");
				response.setHeader("Content-Disposition","attachment;filename=DisposizioniAea.pdf");
				
			    out.flush();
			    out.close();
			} else {
				response.setStatus(404); // not found
			}
		} 
	}

	@RequestMapping(value="/printFiltered",method=RequestMethod.POST)
	private void printFiltered(@RequestBody RicercaDisposizioniFilterBean ricercaDisposizioniFilterBean, HttpServletRequest request,HttpServletResponse response) throws Exception {
		setRequest(request);
		AppVariables appVariables = (AppVariables) getSessionAttribute("appVariables");
		if(getUserData()==null)
			response.sendError(401); // UNAUTHORIZED
		else {
			List<DisposizioniAeaDecoded> disposizioni = disposizioniAeaDAO. filterDecoded(ricercaDisposizioniFilterBean);
			if (disposizioni.size()>0) {
				JRDataSource dsDisposizioni = new JRBeanCollectionDataSource(disposizioni);
				
				//JasperDesign design = JRXmlLoader.load(request.getSession().getServletContext().getRealPath("/") + "Reports/repDisposizioniRid.jrxml");
				//JasperReport report = JasperCompileManager.compileReport(design);
				HashMap reportParams = new HashMap();
				
				String appPath = request.getSession().getServletContext().getRealPath("/");
				if (!appPath.endsWith("/"))
					appPath += "/";
				
				java.util.Locale locale = new Locale( "it", "IT" );
				reportParams.put( JRParameter.REPORT_LOCALE, locale );

				JasperPrint jasperPrint = JasperFillManager.fillReport(appPath + "Reports/repDisposizioniAea.jasper" ,reportParams, dsDisposizioni);
				JasperExportManager.exportReportToPdfStream(jasperPrint, response.getOutputStream());
				
				response.setContentType("application/pdf");
				response.setHeader("Content-Disposition","attachment;filename=DisposizioniAea.pdf");
				ServletOutputStream out = response.getOutputStream();
			    out.flush();
			    out.close();
			} else {
				response.setStatus(404); // not found
			}
		} 
	}
}
