package com.ejie.ab61.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 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.ab61.comun.Constantes;
import com.ejie.ab61.exceptions.Ab61Exception;
import com.ejie.ab61.model.inicio.InitForm;
import com.ejie.ab61.model.listados.Listados;
import com.ejie.ab61.model.procedimientos.Procedimientos;
import com.ejie.ab61.model.usuario.Usuario;
import com.ejie.ab61.service.listados.ListadosClienteService;
import com.ejie.ab61.service.procedimientos.ProcedimientosService;
import com.ejie.ab61.tramita.adapter.PifAdapterService;

@Controller
@SessionAttributes("usuario")
@RequestMapping(value = "/listadosCliente")
public class ListadosClienteController {

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

	@Autowired
	private ListadosClienteService listadosClienteService;
	@Autowired
	private PifAdapterService pifAdapterService;

	@Autowired
	private ProcedimientosService procedimentosService;
	/*
	 * OPERACIONES CRUD (Create, Read, Update, Delete)
	 * 
	 */

	/**
	 * Metodo de presentacion del RUP_TABLE.
	 * 
	 * @param model
	 *            Model
	 * @return String
	 */
	@RequestMapping(value = "/maint", method = RequestMethod.POST)
	public ModelAndView mostrar(Model model, Usuario usuario, InitForm datosTramitagune) {
		ListadosClienteController.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();
		}
		// sacar el idProcediemento del ProcedureId;

		Procedimientos procedimientosAux = this.procedimentosService
				.findByProcedimento(datosTramitagune.getProcedureId());

		usuario.setNombreUsuario(username);
		model.addAttribute("usuario", usuario);
		model.addAttribute("idProcedimientoInitForm", procedimientosAux.getIdProcedimiento());
		model.addAttribute("origen", Constantes.origen.EXPEDIENTES);
		return new ModelAndView("listadoCliente", "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) {
		ListadosClienteController.logger.info("[GET - find_ALL] : Obtener Listados por filtro");
		Procedimientos procedimiento = new Procedimientos();
		procedimiento.setIdProcedimiento(idProcedimiento);
		// filterListados.setProcedimientos(procedimiento);
		return this.listadosClienteService.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.listadosClienteService.find(listados);
		ListadosClienteController.logger.info("[GET - findBy_PK] : Obtener Listados por PK");
		return listados;
	}

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

		return this.listadosClienteService.gerenarXLS(listados, idProcedimiento);

	}

	/**
	 * 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.Language.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.ms-excel");

		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 filterListados
	 *            Listados Objeto que contiene los parametros de filtrado
	 *            utilizados en la busqueda.
	 * @return List<RelLisPro> Lista de objetos correspondientes a la busqueda
	 *         realizada.
	 */
	@RequestMapping(value = "/getAllRelLisProByProc/{idProcedimiento}", method = RequestMethod.GET)
	public @ResponseBody List<Listados> getAllRelLisProByProc(@PathVariable Integer idProcedimiento) {
		ListadosClienteController.logger.info("[GET - find_ALL] : Obtener Listados por filtro");

		return this.listadosClienteService.findAllRelLisProByProc(idProcedimiento);
	}
}
