package controller.rest;

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.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 common.controller.BaseController;
import dao.DisposizioniRidDAO;
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.DisposizioniRid;
import sicura.entities.DistintaBanca;
import utils.ConvalidaClass;
import utils.DettaglioErrori;

@Controller
@RequestMapping("DisposizioniRid")
public class DisposizioniRidRestController extends BaseController {

	@Autowired
	DisposizioniRidDAO disposizioniRidDAO;

	@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>(disposizioniRidDAO.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<>(0, 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 = disposizioniRidDAO.cancellazioneMassiva(disposizioniFiltroBean, getUserData().getOtherCode(), getUserData(), appVariables);
			
			}
		finally {
			
		}
		return new ResponseEntity<Boolean>(res, HttpStatus.OK);
	}
	 
	@RequestMapping(value="",method=RequestMethod.POST)
	@ResponseBody
	private ResponseEntity<Object> save(HttpServletRequest request, @RequestBody DisposizioniRid disposizioneRid) {
		try {
			setRequest(request);
			AppVariables appVariables = (AppVariables) getSessionAttribute("appVariables");
			if(getUserData()==null)
				return new ResponseEntity<Object>(HttpStatus.UNAUTHORIZED);
			else {
				disposizioneRid.setFlagStampa(false);
	
				if (!"Predisposta".equalsIgnoreCase(disposizioneRid.getStatoDisposizione())) {
					//ConvalidaClass controlliConvalida = new ConvalidaClass(1, "RID", condizioniCtrlDao, abiCabDao);
					
					ObjectMapper oMapper = new ObjectMapper();
					Map<String, Object> disposizione = oMapper.convertValue(disposizioneRid, Map.class);
					
					try {
						DettaglioErrori errori = convalidaClass.eseguiConvalida(appVariables, 1, "RID",disposizione, true, true);
						 disposizioneRid = oMapper.convertValue(disposizione, DisposizioniRid.class);
					} catch (Exception e) {
						// TODO Auto-generated catch block  disposizione.get("importo")   disposizione.get("flagImporto") disposizioneRid.isFlagImporto()
						e.printStackTrace();
					}
					
				}
	
				
				int res = disposizioniRidDAO.saveDisposizione(disposizioneRid, getUserData(), appVariables);
				if (res==0)
					return new ResponseEntity<Object> (disposizioneRid, HttpStatus.OK);
				else
					return new ResponseEntity<Object> (res, 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<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
		}
		
	}
	
	@RequestMapping(value="/list/{start:[\\d]+}-{length:[\\d]+}")
	@ResponseBody
	private ResponseEntity<List<DisposizioniRid>> 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<DisposizioniRid>>(HttpStatus.UNAUTHORIZED);
			else
				return new ResponseEntity<List<DisposizioniRid>>(disposizioniRidDAO.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="/export")
	@ResponseBody
	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= disposizioniRidDAO.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= disposizioniRidDAO.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="/print",method=RequestMethod.POST)
	private void print(@RequestBody DisposizioniFiltroBean disposizioniFiltroBean, @RequestParam(value="label", required=false) String label, HttpServletRequest request,HttpServletResponse response) throws Exception {
		setRequest(request);
		AppVariables appVariables = (AppVariables) getSessionAttribute("appVariables");
		if(getUserData()==null)
			response.sendError(401); // UNAUTHORIZED
		else {
			List<DisposizioniRid> disposizioni = disposizioniRidDAO.list(0,0,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);
				HashMap<String, Object> reportParams = new HashMap<String, Object>();
				
				String appPath = request.getSession().getServletContext().getRealPath("/");
				if (!appPath.endsWith("/"))
					appPath += "/";
				
				if ("DistinteBanca".equalsIgnoreCase(disposizioniFiltroBean.getTipoChiamata())) {
					DistintaBanca distinta = distintaBancaDAO.getByIdDistintaBanca(disposizioniFiltroBean.getIdDistintaBanca());
					if (distinta!=null) {
						
						if (distinta.getDenominazioneDelegatoFirma()!=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 );
				
				if (label!=null && !"".equals(label)) {
					reportParams.put("titoloReport",label);
				} else {
								
					if ("ListaDisposizioniEst".equalsIgnoreCase(disposizioniFiltroBean.getTipoChiamata())|| request.getRequestURL().toString().toLowerCase().contains("incassi sdd esteri")) 
						reportParams.put("titoloReport","Stampa Disposizioni SDD Esteri");
					else if ("ListaDisposizioni".equalsIgnoreCase(disposizioniFiltroBean.getTipoChiamata()) || request.getRequestURL().toString().toLowerCase().contains("incassi sdd")) 
						reportParams.put("titoloReport","Stampa Disposizioni SDD");
					else
						reportParams.put("titoloReport","Stampa Disposizioni SDD");	
				}
				
				JasperPrint jasperPrint = JasperFillManager.fillReport(appPath+"Reports/repDisposizioniRid.jasper" ,reportParams, dsDisposizioni);
				JasperExportManager.exportReportToPdfStream(jasperPrint, out);
				
				response.setContentType("application/pdf");
				response.setHeader("Content-Disposition","attachment;filename=DisposizioniRid.pdf");
				
			    out.flush();
			    out.close();
			} else {
				response.setStatus(404); // not found
			}
		} 
	}

	@RequestMapping(value="/printFiltered",method=RequestMethod.POST)
	private void printFiltered(@RequestBody RicercaDisposizioniFilterBean ricercaDisposizioniFilterBean, @RequestParam(value="label", required=false) String label, HttpServletRequest request,HttpServletResponse response) throws Exception {
		setRequest(request);
		AppVariables appVariables = (AppVariables) getSessionAttribute("appVariables");
		if(getUserData()==null)
			response.sendError(401); // UNAUTHORIZED
		else {
			List<DisposizioniRid> disposizioni = disposizioniRidDAO. filter(0,0,null,ricercaDisposizioniFilterBean,null);
			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 );
				
				if (label!=null && !"".equals(label)) {
					reportParams.put("titoloReport",label);
				} else {
					if ("Incassi SDD".equalsIgnoreCase(ricercaDisposizioniFilterBean.getTipoDisposizione()))
						reportParams.put("titoloReport","Stampa Disposizioni SDD");
					else if ("sdd esteri".equalsIgnoreCase(ricercaDisposizioniFilterBean.getTipoDisposizione()))
						reportParams.put("titoloReport","Stampa Disposizioni SDD Esteri");
					else
						reportParams.put("titoloReport","Stampa Disposizioni SDD");
				}
				
				JasperPrint jasperPrint = JasperFillManager.fillReport(appPath + "Reports/repDisposizioniRid.jasper" ,reportParams, dsDisposizioni);
				JasperExportManager.exportReportToPdfStream(jasperPrint, response.getOutputStream());
				
				response.setContentType("application/pdf");
				response.setHeader("Content-Disposition","attachment;filename=DisposizioniRid.pdf");
				ServletOutputStream out = response.getOutputStream();
			    out.flush();
			    out.close();
			} else {
				response.setStatus(404); // not found
			}
		} 
	}

	
	@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>(disposizioniRidDAO.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<>(0, 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>>(disposizioniRidDAO.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>>(disposizioniRidDAO.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="/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>(disposizioniRidDAO.filter(startFrom, length, orderField, filtro.getFiltroRicerca(), filtro.getFiltro()),HttpStatus.OK);
		} catch(Exception ex) {
			ex.printStackTrace();
			Logger.getRootLogger().error(ex);
			return new ResponseEntity<>(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>(disposizioniRidDAO.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<>(0, HttpStatus.INTERNAL_SERVER_ERROR);
		}
	}
	
}
