package controller.rest;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;

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.http.client.HttpComponentsAsyncClientHttpRequestFactory;
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 bean.AnnullaDistintaBean;
import bean.AppVariables;
import bean.LogModificheBean;
import bean.ModificaContoDistintaBean;
import bean.ModificaDataDisposizioneBean;
import bean.filters.DisposizioniFiltroBean;
import bean.filters.DistinteFilterBean;
import bean.query.DisposizioniBonificiDecoded;
import bean.query.DistintaBancaBean;
import common.controller.BaseController;
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.DistintaBanca;

@Controller
@RequestMapping("distinte")
public class DistinteBancaRestController extends BaseController {

	@Autowired
	DistintaBancaDAO distintaBancaDAO;

	@RequestMapping(value = "", method = RequestMethod.POST)
	@ResponseBody
	private ResponseEntity<String> save(@RequestBody DistintaBancaBean disintaBancaBean, HttpServletRequest request) {
		try {
			setRequest(request);

			if (getUserData() == null)
				return new ResponseEntity<String>(HttpStatus.UNAUTHORIZED);
			else {
				AppVariables appVariables = (AppVariables) getSessionAttribute("appVariables");
				String res = distintaBancaDAO.saveDistinta(disintaBancaBean, appVariables, false);
				return new ResponseEntity<String>(res, 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<>(
					"Si è verificato un errore imprevisto.  L'errore è stato registrato nei log di Sicura",
					HttpStatus.INTERNAL_SERVER_ERROR);
		}
	}

	@RequestMapping("/count")
	@ResponseBody
	private ResponseEntity<Integer> count(@RequestBody DistinteFilterBean filterBean, HttpServletRequest request) {
		try {
			setRequest(request);

			if (getUserData() == null)
				return new ResponseEntity<Integer>(HttpStatus.UNAUTHORIZED);
			else {
				AppVariables appVariables = (AppVariables) getSessionAttribute("appVariables");
				return new ResponseEntity<Integer>(distintaBancaDAO.getCountDistinteBanca(appVariables, filterBean),
						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("/list/{start:[\\d]+}-{length:[\\d]+}")
	@ResponseBody
	private ResponseEntity<Object> list(@PathVariable("start") int startFrom, @PathVariable("length") int length,
			@RequestBody DistinteFilterBean filterBean, HttpServletRequest request) {
		try {
			setRequest(request);

			if (getUserData() == null)
				return new ResponseEntity<Object>(HttpStatus.UNAUTHORIZED);
			else {
				AppVariables appVariables = (AppVariables) getSessionAttribute("appVariables");
				return new ResponseEntity<Object>(
						distintaBancaDAO.getDistinteBanca(appVariables, filterBean, startFrom, length), 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("/annulla")
	@ResponseBody
	private ResponseEntity<Object> annullaDistinta(@RequestBody AnnullaDistintaBean annullaDistintaBean,
			HttpServletRequest request) {
		try {
			setRequest(request);
			if (getUserData() == null)
				return new ResponseEntity<Object>(HttpStatus.UNAUTHORIZED);
			else {
				AppVariables appVariables = (AppVariables) getSessionAttribute("appVariables");
				try {
					return new ResponseEntity<Object>(
							distintaBancaDAO.annullaDistinta(annullaDistintaBean, appVariables), HttpStatus.OK);
				} catch (Exception e) {
					e.printStackTrace();
					return new ResponseEntity<Object>(e.getMessage(), 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("/firmaDistinta/{tipoFirma}/{generaFlusso}/{idDistintaBanca}")
	@ResponseBody
	private ResponseEntity<Object> firmaDistinta(@PathVariable("tipoFirma") String tipoFirma,
			@PathVariable("generaFlusso") Integer generaFlusso,
			@PathVariable("idDistintaBanca") Integer idDistintaBanca, HttpServletRequest request) {
		try {
			setRequest(request);
			if (getUserData() == null)
				return new ResponseEntity<Object>(HttpStatus.UNAUTHORIZED);
			else {
				AppVariables appVariables = (AppVariables) getSessionAttribute("appVariables");
				String res = distintaBancaDAO.firmaDistinta(tipoFirma, generaFlusso.equals(1), idDistintaBanca,
						appVariables);

				return new ResponseEntity<Object>(res, 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("/modificaConto")
	@ResponseBody
	private ResponseEntity<Object> modificaContoDistinta(
			@RequestBody ModificaContoDistintaBean modificaContoDistintaBean, HttpServletRequest request) {
		try {
			setRequest(request);
			if (getUserData() == null)
				return new ResponseEntity<Object>(HttpStatus.UNAUTHORIZED);
			else {
				AppVariables appVariables = (AppVariables) getSessionAttribute("appVariables");
				try {
					return new ResponseEntity<Object>(
							distintaBancaDAO.modificaContoDistinta(modificaContoDistintaBean, appVariables),
							HttpStatus.OK);
				} catch (Throwable e) {
					e.printStackTrace();
					return new ResponseEntity<Object>(e.getMessage(), 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("/modificaDataValuta")
	@ResponseBody
	private ResponseEntity<Object> modificaDataValuta(@RequestBody ModificaDataDisposizioneBean modificaDataValutaBean,
			HttpServletRequest request) {
		try {
			setRequest(request);
			if (getUserData() == null)
				return new ResponseEntity<Object>(HttpStatus.UNAUTHORIZED);
			else {
				AppVariables appVariables = (AppVariables) getSessionAttribute("appVariables");
				try {
					return new ResponseEntity<Object>(
							distintaBancaDAO.modificaDataValuta(modificaDataValutaBean, getUserData(), appVariables),
							HttpStatus.OK);
				} catch (Throwable e) {
					e.printStackTrace();
					return new ResponseEntity<Object>(e.getMessage(), 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("/modificaDataEsecuzione")
	@ResponseBody
	private ResponseEntity<Object> modificaDataEsecuzione(
			@RequestBody ModificaDataDisposizioneBean modificaDataValutaBean, HttpServletRequest request) {
		try {
			setRequest(request);
			if (getUserData() == null)
				return new ResponseEntity<Object>(HttpStatus.UNAUTHORIZED);
			else {
				AppVariables appVariables = (AppVariables) getSessionAttribute("appVariables");
				try {
					return new ResponseEntity<Object>(distintaBancaDAO.modificaDataEsecuzione(modificaDataValutaBean,
							getUserData(), appVariables), HttpStatus.OK);
				} catch (Throwable e) {
					e.printStackTrace();
					return new ResponseEntity<Object>(e.getMessage(), 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 = "/logStati/{id}")
	@ResponseBody
	private ResponseEntity<List<LogModificheBean>> logStati(@PathVariable("id") Integer id,
			HttpServletRequest request) {
		try {
			setRequest(request);
			AppVariables appVariables = (AppVariables) getSessionAttribute("appVariables");
			if (getUserData() == null)
				return new ResponseEntity<List<LogModificheBean>>(HttpStatus.UNAUTHORIZED);
			else
				return new ResponseEntity<List<LogModificheBean>>(distintaBancaDAO.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 = "/validaEGenera/{id}")
	@ResponseBody
	private ResponseEntity<Object> validaEGenera(@PathVariable("id") Integer id, HttpServletRequest request) {
		try {
			setRequest(request);
			AppVariables appVariables = (AppVariables) getSessionAttribute("appVariables");
			if (getUserData() == null)
				return new ResponseEntity<Object>(HttpStatus.UNAUTHORIZED);
			else {
				String res = distintaBancaDAO.validaEGenera(id, appVariables);
				return new ResponseEntity<Object>(res, 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 = "/genera/{id}")
	@ResponseBody
	private ResponseEntity<Object> genera(@PathVariable("id") Integer id, HttpServletRequest request) {
		try {
			setRequest(request);
			AppVariables appVariables = (AppVariables) getSessionAttribute("appVariables");
			if (getUserData() == null)
				return new ResponseEntity<Object>(HttpStatus.UNAUTHORIZED);
			else {
				String res = distintaBancaDAO.genera(id, appVariables);
				return new ResponseEntity<Object>(res, 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 = "/esportaTASC/{id}")
	@ResponseBody
	private ResponseEntity<Object> esportaTasc(@PathVariable("id") Integer id, HttpServletRequest request) {
		setRequest(request);
		AppVariables appVariables = (AppVariables) getSessionAttribute("appVariables");
			try {
			if (getUserData() == null)
				return new ResponseEntity<Object>(HttpStatus.UNAUTHORIZED);
			else {
				String res = distintaBancaDAO.genera(id, appVariables);
				return new ResponseEntity<Object>(res, 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<>(ex.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
		}
	}

	@RequestMapping(value = "/print", method = RequestMethod.POST)
	private void print(@RequestBody DistinteFilterBean filterBean, HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		setRequest(request);
		AppVariables appVariables = (AppVariables) getSessionAttribute("appVariables");
		if (getUserData() == null)
			response.sendError(401); // UNAUTHORIZED
		else {
			List<DistintaBancaBean> distinte = distintaBancaDAO.getDistinteBanca(appVariables, filterBean, null, null);
			if (distinte.size() > 0) {
				JRDataSource dsDistinte = new JRBeanCollectionDataSource(distinte);

				HashMap<String, Object> reportParams = new HashMap<String, Object>();
				String appPath = request.getSession().getServletContext().getRealPath("/");
				if (!appPath.endsWith("/"))
					appPath += "/";

				reportParams.put("checked", appPath + "img/checkbox.png");
				reportParams.put("unchecked", 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/repDistinteBanca.jasper",
						reportParams, dsDistinte);
				JasperExportManager.exportReportToPdfStream(jasperPrint, out);

				response.setContentType("application/pdf");
				response.setHeader("Content-Disposition", "attachment;filename=DistinteBanca.pdf");

				out.flush();
				out.close();
			} else {
				response.setStatus(404); // not found
			}
		}
	}

	@RequestMapping(value = "/esportaTASC", method = RequestMethod.POST, produces = "text/plain")
	@ResponseBody
	private ResponseEntity<Object> esportaTASC(@RequestBody DistinteFilterBean filterBean, HttpServletRequest request,
			HttpServletResponse response) {
		try {
			setRequest(request);

			if (getUserData() == null)
				return new ResponseEntity<Object>(HttpStatus.UNAUTHORIZED); // response.sendError(401); // UNAUTHORIZED
			else {
				AppVariables appVariables = (AppVariables) getSessionAttribute("appVariables");
				try {
					List<String> file = distintaBancaDAO.esportaTASC(appVariables, filterBean);
					if (file != null)
						return new ResponseEntity<Object>(HttpStatus.OK);
					else
						return new ResponseEntity<Object>(HttpStatus.NOT_FOUND);
				} catch (Exception ex) {
					ex.printStackTrace();
					return new ResponseEntity<Object>(ex.getMessage(),HttpStatus.INTERNAL_SERVER_ERROR);
				}
				// if (file==null)
				// response.sendError(404);
				// else
				// response.
				// response.setContentType("text/csv");
				// response.setHeader("Content-Disposition",String.format("attachment;filename=%s.cfg",generateTASCFileName()));
				// ServletOutputStream out = response.getOutputStream();
				// for (String str: file)
				// out.println(str);
				// out.flush();
				// out.close();

			}
		} 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="/forzaturaInviata/{id}",method=RequestMethod.GET)
	@ResponseBody
	private ResponseEntity<Integer> forzaturaInviata(@PathVariable("id") Integer id, HttpServletRequest request) {
		try {
			setRequest(request);
			AppVariables appVariables = (AppVariables) getSessionAttribute("appVariables");
			if(getUserData()==null)
				return new ResponseEntity<Integer>(HttpStatus.UNAUTHORIZED);
			else
				return new ResponseEntity<Integer>(distintaBancaDAO.forzaturaInviata(appVariables, 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<Integer>(HttpStatus.INTERNAL_SERVER_ERROR);
		}
			
	}
	
	private Object generateTASCFileName() {
		Date dt = new Date();
		SimpleDateFormat sdf = new SimpleDateFormat("ddmmyyyy_hhmmssSSS");
		return "ExportDistinteTasc_" + sdf.format(new Date());
	}


}
