package com.ejie.ab78.control.plantillas;

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

import javax.annotation.Resource;
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.context.support.ReloadableResourceBundleMessageSource;
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.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.SessionAttributes;

import com.ejie.ab78.adaptadores.ab61WebServiceAdaptadorService;
import com.ejie.ab78.clientesWS.ab61WebService.Ab61Exception;
import com.ejie.ab78.clientesWS.ab61WebService.Origen;
import com.ejie.ab78.clientesWS.ab61WebService.Usuario;
import com.ejie.ab78.comun.Constantes;
import com.ejie.ab78.comun.UtilUsuario;
import com.ejie.ab78.comun.UtilsXlnets;
import com.ejie.ab78.model.expedientes.Expedientes;
import com.ejie.ab78.model.plantillas.Documentos;
import com.ejie.ab78.model.plantillas.ParametrosConfig;
import com.ejie.ab78.model.plantillas.Plantillas;
import com.ejie.ab78.model.plantillas.RelExpPla;
import com.ejie.ab78.model.procedimientos.Procedimientos;
import com.ejie.ab78.model.terceros.DatosTerceros;
import com.ejie.ab78.model.terceros.RelDenunciaTercero;
import com.ejie.ab78.model.terceros.RelExpTer;
import com.ejie.ab78.model.terceros.TiposTercero;
import com.ejie.ab78.model.terceros.VistaDatosExpediente;
import com.ejie.ab78.model.terceros.VistaTerceros;
import com.ejie.ab78.service.expedientes.ExpedientesService;
import com.ejie.ab78.service.plantillas.ParametrosConfigService;
import com.ejie.ab78.service.plantillas.PlantillasService;
import com.ejie.ab78.service.terceros.RelExpTerService;
import com.ejie.ab78.tramita.adapter.PifAdapterService;
import com.ejie.x38.control.bind.annotation.RequestJsonBody;
import com.ejie.x38.dto.TableRequestDto;
import com.ejie.x38.dto.TableResponseDto;
import com.ejie.x38.security.UserCredentials;

/**
 * PlantillasController  
 * 
 *  
 */

@Controller
@SessionAttributes("usuario")
@RequestMapping(value = "/plantillas")

public class PlantillasController {

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

	@Autowired
	private PlantillasService plantillasService;

	@Autowired
	private RelExpTerService relExpTerService;

	@Autowired
	private ab61WebServiceAdaptadorService ab61WebServiceAdaptadorService;

	@Resource
	ReloadableResourceBundleMessageSource appMessageSource;

	@Autowired
	private ParametrosConfigService parametrosConfigService;

	@Autowired
	private PifAdapterService pifAdapterService;
	
	@Autowired
	private ExpedientesService expedientesService;

	/**
	 * Metodo de presentacion del RUP_TABLE.
	 * 
	 * @param model
	 *            Model
	 * @return String
	 */
	@RequestMapping(value = "/maint/{procedureId}/{idExpediente}/{isExpedienteOficio}", method = RequestMethod.GET)
	public String getFormEditPlantilla(@PathVariable String procedureId, @PathVariable String idExpediente,
			@PathVariable Boolean isExpedienteOficio, Model model) {
		PlantillasController.logger.info("[GET - View] : plantillas");
		model.addAttribute("idProcedimiento", procedureId);
		model.addAttribute("idExpediente", idExpediente);
		model.addAttribute("isExpedienteOficio", isExpedienteOficio);

		model.addAttribute("origen", Constantes.ORIGEN_EXPEDIENTE);

		ParametrosConfig parametrosConfig = new ParametrosConfig();
		parametrosConfig.setDescripcion(Constantes.CONFIGURACION_DOCUMENTOS);
		parametrosConfig = this.parametrosConfigService.find(parametrosConfig);

		model.addAttribute("parametroConfig", parametrosConfig.getValor());

		model.addAttribute("plantilla", new Plantillas());

		// Idioma
		String idioma = LocaleContextHolder.getLocale().getLanguage();
		model.addAttribute("lenguaje", idioma);

		// Participantes
		int comboIdioma = Constantes.IDIOMA_TODOS;
		Boolean hayRepresentante = false;
		Long tipoParticipantePrincipal = (long) Constantes.PARTICIPACION_SOLICITANTE;
		if (isExpedienteOficio) {
			tipoParticipantePrincipal = (long) Constantes.PARTICIPACION_AFECTADO;
		}
		List<VistaDatosExpediente> listaParticipantesParticipacion = relExpTerService
				.findParticipaciones2(Integer.parseInt(idExpediente), tipoParticipantePrincipal);
		List<VistaTerceros> afectadosList = new ArrayList<VistaTerceros>();
		if (!isExpedienteOficio) {
			List<DatosTerceros> dataTerceroList = listaParticipantesParticipacion.get(0).getVistaTercerosList().get(0)
					.getDatosTercerosList();
			for (DatosTerceros dataTercero : dataTerceroList) {
				if (dataTercero.getTipoParticipante() == Constantes.ID_TIPO_TERCERO_SOLICITANTE) {
					if (dataTercero.getIdioma() != null) {
						comboIdioma = dataTercero.getIdioma();
					}
					hayRepresentante = true;
				}
			}
			if (!hayRepresentante) {
				for (DatosTerceros dataTercero : dataTerceroList) {
					if (dataTercero.getTipoParticipante() == Constantes.PARTICIPANTE_TITULAR) {
						if (dataTercero.getIdioma() != null) {
							comboIdioma = dataTercero.getIdioma();
						}
					}
				}
			}
			List<VistaTerceros> afectadosTerceroList = listaParticipantesParticipacion.get(0).getVistaTercerosList();
			for (int i = 0; i < afectadosTerceroList.size(); i++) {
				if (afectadosTerceroList.get(i).getIdTipoTercero() == Constantes.ID_TIPO_TERCERO_AFECTADO) {
					afectadosList.add(afectadosTerceroList.get(i));
				}
			}
		}

		List<RelExpTer> listaParticipantes = relExpTerService.findParticipaciones(Integer.parseInt(idExpediente));
		List<RelDenunciaTercero> listaAuxRelDenunciaTercero = new ArrayList<RelDenunciaTercero>();
		for (RelExpTer relExpTer : listaParticipantes) {
			if (null != relExpTer.getDatosTercerosList() && !relExpTer.getDatosTercerosList().isEmpty()
					&& relExpTer.getDatosTercerosList().size() > 1) {
				for (int i = 0; i < relExpTer.getDatosTercerosList().size(); i++) {
					TiposTercero tipoTercero = new TiposTercero(relExpTer.getTiposTercero().getIdTipoTercero());
					DatosTerceros datosTerceros = relExpTer.getDatosTercerosList().get(i);
					datosTerceros.setTiposTercero(tipoTercero);
					datosTerceros.setParticipantId(relExpTer.getParticipantId());

					RelDenunciaTercero denunciaTercero = new RelDenunciaTercero();
					denunciaTercero.setIdRelRecTer(relExpTer.getIdRelExpTer());
					denunciaTercero.setDatosTerceros(datosTerceros);
					denunciaTercero.setIdTipoTercero(tipoTercero.getIdTipoTercero());
					denunciaTercero.setParticipantId(relExpTer.getParticipantId());
					denunciaTercero.setIdSubtipo(relExpTer.getIdSubtipo());
					listaAuxRelDenunciaTercero.add(denunciaTercero);
				}
			} else {
				DatosTerceros datosTerceros = relExpTer.getDatosTercerosList().get(0);
				TiposTercero tipoTercero = new TiposTercero(relExpTer.getTiposTercero().getIdTipoTercero());
				datosTerceros.setTiposTercero(tipoTercero);
				datosTerceros.setParticipantId(relExpTer.getParticipantId());

				RelDenunciaTercero denunciaTercero = new RelDenunciaTercero();
				denunciaTercero.setIdRelRecTer(relExpTer.getIdRelExpTer());
				denunciaTercero.setDatosTerceros(datosTerceros);
				denunciaTercero.setIdTipoTercero(tipoTercero.getIdTipoTercero());
				denunciaTercero.setParticipantId(relExpTer.getParticipantId());
				denunciaTercero.setIdSubtipo(relExpTer.getIdSubtipo());
				listaAuxRelDenunciaTercero.add(denunciaTercero);
			}
		}

		List<RelDenunciaTercero> listaDenunciantes = new ArrayList<RelDenunciaTercero>();
		List<RelDenunciaTercero> listaDenunciados = new ArrayList<RelDenunciaTercero>();
		List<RelDenunciaTercero> listaAfectados = new ArrayList<RelDenunciaTercero>();

		for (RelDenunciaTercero relDenunciaTercero : listaAuxRelDenunciaTercero) {
			if (null != relDenunciaTercero.getIdTipoTercero()) {
				if (Constantes.ID_TIPO_TERCERO_SOLICITANTE == relDenunciaTercero.getIdTipoTercero()) {
					listaDenunciantes.add(relDenunciaTercero);
				} else if (Constantes.ID_TIPO_TERCERO_DENUNCIADO == relDenunciaTercero.getIdTipoTercero()) {
					listaDenunciados.add(relDenunciaTercero);
				} else if (Constantes.ID_TIPO_TERCERO_AFECTADO == relDenunciaTercero.getIdTipoTercero()) {
					listaAfectados.add(relDenunciaTercero);
				}
			}
		}

		model.addAttribute("listaAfectados", listaAfectados);
		model.addAttribute("listaDenunciantes", listaDenunciantes);
		model.addAttribute("listaDenunciados", listaDenunciados);

		model.addAttribute("comboIdiomaValue", comboIdioma);
		model.addAttribute("listaSearch", listaParticipantesParticipacion.get(0).getVistaTercerosList());
		
		Expedientes expediente = new Expedientes(Integer.parseInt(idExpediente));
		boolean expedienteCerrado = this.expedientesService.esExpedienteCerrado(expediente);
		model.addAttribute("esExpedienteCerrado", expedienteCerrado);
		
		return "plantillas";
	}

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

		String rutaDocumento = plantilla.getRutaDocumento();
		BufferedInputStream contenidoXml = this.pifAdapterService
				.getFile("/" + Constantes.CODIGO_APLICACION + "/" + rutaDocumento);
		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 =
		// rutaDocumento.substring(rutaDocumento.indexOf("/"));
		String nombreDocumento = rutaDocumento;
		httpResponse.setHeader("Content-Disposition", "attachment; filename=\"" + nombreDocumento + "\"");
		Cookie cookie = new Cookie("fileDownload", "true");
		cookie.setMaxAge(2);
		cookie.setPath("/");
		httpResponse.addCookie(cookie);
		httpResponse.setContentType("application/doc");

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

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

	/**
	 * Operacion de filtrado del componente RUP_TABLE.
	 * 
	 * @param filterPlantillas
	 *            Plantillas Bean que contiene los parametros de filtrado a
	 *            emplear.
	 * @param TableRequestDto
	 *            Dto que contiene los parametros de configuracion propios del
	 *            RUP_TABLE a aplicar en el filtrado.
	 * @return TableResponseDto<Plantillas> Dto que contiene el resultado del
	 *         filtrado realizado por el componente RUP_TABLE.
	 */
	@RequestMapping(value = "/tabla/{IdProcedimiento}/{IdExpediente}/{idiomaBusq}/filter", method = RequestMethod.POST)
	public @ResponseBody TableResponseDto<Plantillas> filter(
			@RequestJsonBody(param = "filter") Plantillas filterPlantillas, @PathVariable Integer IdProcedimiento,
			@PathVariable Integer idiomaBusq,
			// @PathVariable Integer origen,
			@PathVariable Integer IdExpediente, @RequestJsonBody TableRequestDto TableRequestDto) {

		if (IdExpediente == Constantes.MAGIC_NUMBER_0) {
			IdExpediente = null;
		}
		PlantillasController.logger.info("[POST - filter] : Obtener Plantillass");

		filterPlantillas.setProcedimientos(new Procedimientos(IdProcedimiento));
		filterPlantillas.setOrigen(Constantes.ORIGEN_EXPEDIENTE);
		RelExpPla relExpPla = new RelExpPla();
		relExpPla.setIdExpediente(IdExpediente);
		relExpPla.setIdProcedimiento(IdProcedimiento);
		filterPlantillas.setRelExpPla(relExpPla);
		Documentos documentoAux = new Documentos();
		documentoAux.setIdioma(idiomaBusq);
		filterPlantillas.setDocumento(documentoAux);
		return this.plantillasService.filter(filterPlantillas, TableRequestDto, false);

	}

	/**
	 * 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 = "/llamarWebService/descargarDocumentoNegocio/{idDenuncia}/{idPlantilla}/{folderId}", method = RequestMethod.GET)
	public @ResponseBody String descargarDocumentoNegocio(@PathVariable String idDenuncia,
			@PathVariable Integer idPlantilla, @PathVariable String folderId) throws Ab61Exception {
		PlantillasController.logger.info("[GET - generarDocumento] : generarDocumento");

		Origen origen = Origen.EXPEDIENTE;
		return ab61WebServiceAdaptadorService.descargarDocumentoNegocio(idPlantilla, folderId, origen,
				Constantes.CODIGO_APLICACION, false);

	}

	@RequestMapping(value = "/aportarDocumentoNegocio/{idPlantilla}/{procedureId}/{folderId}", method = RequestMethod.GET)
	public @ResponseBody String aportarDocumentoNegocio(HttpServletRequest httpRequest,
			@PathVariable Integer idPlantilla, @PathVariable String procedureId, @PathVariable String folderId)
			throws Ab61Exception {

		Authentication aut = SecurityContextHolder.getContext().getAuthentication();
		UserCredentials userCredentials = (UserCredentials) aut.getCredentials();

		Usuario usurio61 = new Usuario();
		usurio61.setBuzon(UtilsXlnets.obtenerLogin(httpRequest));
		usurio61.setNombreUsuario(userCredentials.getName());
		usurio61.setPrimerApellido(userCredentials.getSurname());
		usurio61.setIdentificador(UtilUsuario.fncDni(httpRequest));
		usurio61.setUsuario(UtilUsuario.getUserConnected());

		return ab61WebServiceAdaptadorService.aportarDocumentoPlatea(idPlantilla, procedureId, folderId, usurio61);
	}

	@RequestMapping(value = "/llamarWebService/modificarDocumentoNegocio/{idPlantilla}/{idDenuncia}/{folderId}", method = RequestMethod.GET)
	public @ResponseBody String modificarDocumentoNegocio(HttpServletRequest httpRequest,
			@PathVariable Integer idPlantilla, @PathVariable String idDenuncia, @PathVariable String folderId)
			throws Ab61Exception {

		PlantillasController.logger.info("[GET - modificarDocumento] : modificarDocumento");

		String nombre = UtilUsuario.getUserConnected();

		return ab61WebServiceAdaptadorService.modificarDocumentoNegocio(idPlantilla, folderId, nombre);
	}

	@RequestMapping(value = "/llamarWebService/eliminarDocumentoNegocio/{idPlantilla}/{idDenuncia}/{folderId}", method = RequestMethod.GET)
	public @ResponseBody void eliminarDocumentoNegocio(HttpServletRequest httpRequest,
			@PathVariable Integer idPlantilla, @PathVariable String idDenuncia, @PathVariable String folderId)
			throws Ab61Exception {

		PlantillasController.logger.info("Entrada a eliminarDocumento");
		ab61WebServiceAdaptadorService.eliminarDocumentoNegocio(idPlantilla, folderId);

	}

	@RequestMapping(value = "/llamarWebService/generarDocumentoNegocio/{idDenuncia}/{idPlantilla}/{folderId}", method = RequestMethod.GET)
	public @ResponseBody String generarDocumentoNegocio(@PathVariable String idDenuncia,
			@PathVariable Integer idPlantilla, @PathVariable String folderId) throws Ab61Exception {
		PlantillasController.logger.info("[GET - generarDocumento] : generarDocumento");

		Origen origen = Origen.EXPEDIENTE;

		return ab61WebServiceAdaptadorService.generarDocumentoNegocio(idPlantilla, folderId, origen,
				UtilUsuario.getUserConnected());

	}
}
