package com.ejie.ab78.control.listados;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.util.List;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ModelAttribute;
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.ResponseBody;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.servlet.ModelAndView;

import com.ejie.ab78.clientesWS.ab61WebService.Ab61Exception;
import com.ejie.ab78.comun.Constantes;
import com.ejie.ab78.model.listados.Listados;
import com.ejie.ab78.model.procedimientos.Procedimientos;
import com.ejie.ab78.model.usuario.Usuario;
import com.ejie.ab78.service.listados.ListadosService;
import com.ejie.ab78.tramita.adapter.PifAdapterService;

@Controller
@SessionAttributes("usuario")
@RequestMapping(value = "/listados")
public class ListadosController {

	private static final Logger logger = LoggerFactory.getLogger(ListadosController.class);

	@Autowired
	private ListadosService listadosService;

	@Autowired
	private PifAdapterService pifAdapterService;

	/*
	 * OPERACIONES CRUD (Create, Read, Update, Delete)
	 * 
	 */

	/**
	 * Metodo de presentacion del RUP_TABLE.
	 * 
	 * @param model
	 *            Model
	 * @return String
	 */
	@RequestMapping(value = "/maint", method = RequestMethod.GET)
	public ModelAndView mostrar(Model model, Usuario usuario, HttpSession httpSession) {
		ListadosController.logger.info("[GET - View] : listados");
		Authentication aut = SecurityContextHolder.getContext().getAuthentication();
		/** Dejamos el usuario logueado en session */
		String username = "";
		if (null != aut) {
			username = (String) aut.getPrincipal();
		}

		usuario.setNombreUsuario(username);
		model.addAttribute("usuario", usuario);

		if (httpSession.getAttribute(Constantes.SESSIONKEY_ULTIMO_EXPEDIENTE) != null) {
			Object folderIdUltimoExpediente = httpSession.getAttribute(Constantes.SESSIONKEY_ULTIMO_EXPEDIENTE);

			model.addAttribute("ultimoExpediente", folderIdUltimoExpediente);
		}
		if (httpSession.getAttribute(Constantes.SESSIONKEY_ULTIMO_EXPEDIENTE_MIGRADO) != null) {
			Object IdDenunciaUltimoExpediente = httpSession
					.getAttribute(Constantes.SESSIONKEY_ULTIMO_EXPEDIENTE_MIGRADO);

			model.addAttribute("IdDenunciaUltimoExpediente", IdDenunciaUltimoExpediente);
		}

		return new ModelAndView("listadoExpedientes", "model", model);
	}

	/** maint creado para cambio de idioma con metodo POST **/
	/**
	 * Metodo de presentacion del RUP_TABLE.
	 * 
	 * @param model
	 *            Model
	 * @return String
	 */
	@RequestMapping(value = "/maint", method = RequestMethod.POST)
	public ModelAndView mostrarPOST(Model model, Usuario usuario) {
		ListadosController.logger.info("[GET - View] : listados");
		Authentication aut = SecurityContextHolder.getContext().getAuthentication();
		/** Dejamos el usuario logueado en session */
		String username = "";
		if (null != aut) {
			username = (String) aut.getPrincipal();
		}

		usuario.setNombreUsuario(username);
		model.addAttribute("usuario", usuario);

		return new ModelAndView("listadoExpedientes", "model", model);
	}

	/**
	 * Devuelve una lista de beans correspondientes a los valores de filtrados
	 * indicados en el objeto pasado como parametro.
	 *
	 * @param filterListados
	 *            Listados Objeto que contiene los parametros de filtrado
	 *            utilizados en la busqueda.
	 * @return List<Listados> Lista de objetos correspondientes a la busqueda
	 *         realizada.
	 */
	@RequestMapping(value = "/getAllListadoProc/{idProcedimiento}", method = RequestMethod.GET)
	public @ResponseBody List<Listados> getAll(@PathVariable Integer idProcedimiento,
			@ModelAttribute Listados filterListados) {
		ListadosController.logger.info("[GET - find_ALL] : Obtener Listados por filtro");
		Procedimientos procedimiento = new Procedimientos();
		procedimiento.setIdProcedimiento(idProcedimiento);
		filterListados.setProcedimientos(procedimiento);
		return this.listadosService.findAllLike(filterListados, null, null);
	}

	/**
	 * Operacion CRUD Read. Devuelve el bean correspondiente al identificador
	 * indicado.
	 * 
	 * @param idListado
	 *            Integer
	 * @return Listados Objeto correspondiente al identificador indicado.
	 */
	@RequestMapping(value = "/{idListado}", method = RequestMethod.GET)
	public @ResponseBody Listados get(@PathVariable Integer idListado) {
		Listados listados = new Listados();
		listados.setIdListado(idListado);
		listados = this.listadosService.find(listados);
		ListadosController.logger.info("[GET - findBy_PK] : Obtener Listados por PK");
		return listados;
	}

	@RequestMapping(value = "/llamarWebService", method = RequestMethod.POST)
	public @ResponseBody String get(HttpServletResponse httpResponse, @RequestBody() Listados listados)
			throws Exception {

		return this.listadosService.gerenarXLS(listados);
	}

	/**
	 * Captura las excepciones AB61Exception.
	 *
	 */
	@ExceptionHandler(value = { Ab61Exception.class })
	public void handleSQLException(HttpServletRequest request, HttpServletResponse response, Exception ex)
			throws Exception {

		String mensajeError = "";

		if (LocaleContextHolder.getLocale().getLanguage().equalsIgnoreCase(Constantes.CASTELLANO))
			mensajeError = ((Ab61Exception) ex).getFaultInfo().getMensajeCastellano();
		else
			mensajeError = ((Ab61Exception) ex).getFaultInfo().getMensajeEuskera();

		// stated Content-Length
		response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
		response.setContentType("text/html;charset=UTF-8");
		response.getWriter().write(mensajeError);
		response.flushBuffer();
	}

	@RequestMapping(value = "/descargar", method = RequestMethod.POST)
	public @ResponseBody String descargar(HttpServletResponse httpResponse, @ModelAttribute Listados listado)
			throws Exception {

		String rutaPIF = listado.getRutaPIF();
		BufferedInputStream contenidoXml = this.pifAdapterService.getFile(rutaPIF);
		int numRead;
		final int bufferSize = 1024;
		byte[] buffer = new byte[bufferSize];
		ByteArrayOutputStream outString = new ByteArrayOutputStream();
		try {
			while ((numRead = contenidoXml.read(buffer)) != -1) {
				outString.write(buffer, 0, numRead);
			}
		} finally {
			contenidoXml.close();
		}
		byte[] strbase64Doc1 = outString.toByteArray();

		String nombreDocumento = rutaPIF.substring(rutaPIF.indexOf("/"));
		httpResponse.setHeader("Content-Disposition", "attachment; filename=\"" + nombreDocumento + "\"");
		Cookie cookie = new Cookie("fileDownload", "true");
		cookie.setMaxAge(2);
		cookie.setPath("/");
		httpResponse.addCookie(cookie);
		// httpResponse.setContentType("application/rtf");
		httpResponse.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");

		httpResponse.setContentLength(strbase64Doc1.length);
		httpResponse.getOutputStream().write(strbase64Doc1);

		httpResponse.getOutputStream().flush();
		httpResponse.getOutputStream().close();
		return null;
	}

	/**
	 * Devuelve una lista de beans correspondientes a los valores de filtrados
	 * indicados en el objeto pasado como parametro.
	 *
	 * @param idProcedimiento
	 *            Integer.
	 * @return List<Listados> Lista de objetos correspondientes a la busqueda
	 *         realizada.
	 */
	@RequestMapping(value = "/getRelLisProByProc/{idProcedimiento}", method = RequestMethod.GET)
	public @ResponseBody List<Listados> getRelLisProByProc(@PathVariable Integer idProcedimiento) {
		ListadosController.logger.info("[GET - find_ALL] : Obtener Listados por filtro");

		return this.listadosService.findRelLisProByProc(idProcedimiento);
	}
}
