package com.ejie.ab61.control.inicio;

import java.util.List;
import java.util.Locale;
import java.util.Properties;
import java.util.Vector;

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.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.i18n.CookieLocaleResolver;
import org.springframework.web.servlet.support.RequestContextUtils;

import com.ejie.ab61.clientesWS.X43ExpedienteElectronico.TFolderList;
import com.ejie.ab61.comun.Constantes;
import com.ejie.ab61.comun.SeguridadAplicacion;
import com.ejie.ab61.comun.utilidades.config.Config;
import com.ejie.ab61.model.expedientes.Expedientes;
import com.ejie.ab61.model.inicio.InitForm;
import com.ejie.ab61.model.moduloAdministrativo.ModuloAdministracion;
import com.ejie.ab61.model.plantillas.Plantillas;
import com.ejie.ab61.model.terceros.VistaDatosExpediente;
import com.ejie.ab61.model.usuario.Usuario;
import com.ejie.ab61.service.expedientes.ExpedientesService;
import com.ejie.ab61.service.expedientes.RelExpTerService;

/**
 * Acceso a la aplicacion
 * 
 *  
 */
@Controller()
@SessionAttributes("usuario")
@RequestMapping(value = "/inicio")
public class InitController {

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

	@Autowired
	private ExpedientesService expedientesService;

	@Autowired
	private RelExpTerService relExpTerService;

	@RequestMapping(method = { RequestMethod.POST })
	public ModelAndView postAccess(HttpServletRequest httpRequest, HttpServletResponse response,
			@RequestParam(value = "procedureId") String procedureId, @RequestParam(value = "folderId") String folderId,
			@RequestParam(value = "folderNumber") String folderNumber,
			@RequestParam(value = "fechaSolicitud") String fechaSolicitud,
			@RequestParam(value = "folderDescription") String folderDescription,
			@RequestParam(value = "dni") String dni, @RequestParam(value = "expConv") String tipoExpediente,
			@RequestParam(value = "tramite") String tramite, @RequestParam(value = "tarea") String tarea,
			@RequestParam(value = "idioma") String idioma, Model model) throws Exception {

		// Se cambia el idioma para que se entre en la aplicacion con el que
		// llega como parametro
		Locale locale = new Locale(idioma);
		LocaleContextHolder.setLocale(locale);
		// Sobreescribir cookie
		((CookieLocaleResolver) RequestContextUtils.getLocaleResolver(httpRequest)).setLocale(httpRequest, response,
				locale);

		Authentication aut = SecurityContextHolder.getContext().getAuthentication();
		InitController.logger.info("autotenticaciÃ³n:getAuthentication" + aut);

		/** Dejamos el usuario logueado en session */
		Usuario usuario = new Usuario();
		String username = "";
		if (null != aut) {

			username = (String) aut.getPrincipal();
		}

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

		InitForm init = this.guardarDatosTramitagune(procedureId, folderId, folderNumber, fechaSolicitud,
				folderDescription, dni, tipoExpediente, tramite, tarea, idioma);

		return this.getAccess(httpRequest, model, init, usuario);

	}

	private InitForm guardarDatosTramitagune(String procedureId, String folderId, String folderNumber,
			String fechaSolicitud, String folderDescription, String dni, String tipoExpediente, String tramite,
			String tarea, String idioma) {
		InitController.logger.info("[procedureId = " + procedureId + ", folderId = " + folderId + ", folderNumber = "
				+ folderNumber + ", fechaSolicitud = " + fechaSolicitud + ", folderDescription = " + folderDescription
				+ ", dni = " + dni + ", tramite = " + tramite + ", tarea = " + tarea + ", tipoExpediente = "
				+ tipoExpediente + ", idioma = " + idioma);

		InitForm datosTramitagune = new InitForm();
		datosTramitagune.setProcedureId(procedureId);
		datosTramitagune.setFolderId(folderId);
		datosTramitagune.setFolderNumber(folderNumber);
		datosTramitagune.setFechaSolicitud(fechaSolicitud);
		datosTramitagune.setFolderDescription(folderDescription);
		datosTramitagune.setDni(dni);
		datosTramitagune.setTramite(tramite);
		datosTramitagune.setTarea(tarea);
		datosTramitagune.setTipoExpediente(tipoExpediente);
		datosTramitagune.setIdioma(idioma);

		return datosTramitagune;
	}

	@RequestMapping(method = RequestMethod.GET)
	private ModelAndView getAccess(HttpServletRequest httpRequest, Model model, InitForm datosTramitagune,
			Usuario usuario) throws Exception {

		InitController.logger.info("[INICIO] Acceso a la aplicacion por Init");

		model.addAttribute("initForm", datosTramitagune);
		if ((datosTramitagune.getFolderNumber() == null || "".equals(datosTramitagune.getFolderNumber()))) {
			InitController.logger.info("[INICIO] No hay un FolderNumber valido.");
			return new ModelAndView("folderNoExiste");
		}

		Expedientes expedientes = new Expedientes();

		expedientes = this.expedientesService.findByFolderId(datosTramitagune.getFolderId());
		if (expedientes == null) {
			return new ModelAndView("folderNoExiste");
		} else {

			datosTramitagune.setIdExpediente(expedientes.getIdExpediente());
			datosTramitagune.setTituloExpediente(expedientes.getTitulo());

			Expedientes expedienteFilter = new Expedientes();

			expedientes.setFolderNumber(datosTramitagune.getFolderNumber());
			expedientes.setFolderId(datosTramitagune.getFolderId());
			expedienteFilter = this.expedientesService.updateFolder(expedientes);

			expedienteFilter.setIdExpediente(datosTramitagune.getIdExpediente());
			return this.initExpedientes(model, datosTramitagune, usuario);

		}

	}

	private ModelAndView initExpedientes(Model model, InitForm datosTramitagune, Usuario usuario) throws Exception {

		String idioma = LocaleContextHolder.getLocale().getLanguage();
		Expedientes expediente = new Expedientes();
		expediente = this.expedientesService.findByFolderId(datosTramitagune.getFolderId());

		model.addAttribute("origen", Constantes.origen.EXPEDIENTES);
		if (null != expediente) {

			if (expediente.getProcedimientos() != null
					&& expediente.getProcedimientos().getDescripcionCastellano() != null) {
				model.addAttribute("desProcedureCasCompleta",
						expediente.getProcedimientos().getDescripcionCastellano());
				if (expediente.getProcedimientos().getDescripcionCastellano().length() > 100) {
					model.addAttribute("desProcedureCas",
							expediente.getProcedimientos().getDescripcionCastellano().substring(0, 100) + "...");
				} else {
					model.addAttribute("desProcedureCas", expediente.getProcedimientos().getDescripcionCastellano());
				}
			}

			// Si la desccipción del procedimiento ocupa más de 100
			// caracteres
			// se acorta y se muestra en el tooltip la descripción completa
			if (expediente.getProcedimientos() != null
					&& expediente.getProcedimientos().getDescripcionEuskera() != null) {
				model.addAttribute("desProcedureEusCompleta", expediente.getProcedimientos().getDescripcionEuskera());
				if (expediente.getProcedimientos().getDescripcionEuskera().length() > 100) {
					model.addAttribute("desProcedureEus",
							expediente.getProcedimientos().getDescripcionEuskera().substring(0, 100) + "...");
				} else {
					model.addAttribute("desProcedureEus", expediente.getProcedimientos().getDescripcionEuskera());
				}
			}

			TFolderList resultado = expedientesService.obtenerInfoPlatea(datosTramitagune.getFolderId());

			if (null != resultado) {
				try {
					// Actualizamos el titulo de expediente que viene de Platea
					// en
					// BD y en InitForm.
					this.expedientesService.actualizarTituloExpediente(resultado, usuario);

					expediente.setTitulo(resultado.getFolder().get(0).getFolderTitle());

					// // Lista de personas de la Participacion
					int idExpediente = expediente.getIdExpediente();
					relExpTerService.actulizarListParticipantesPorParticipacion(resultado, idExpediente, usuario);
					model.addAttribute("flagSearchFolder", true);
				} catch (Exception e) {
					InitController.logger.error(e.getMessage());
					model.addAttribute("flagSearchFolder", false);
				}

			} else {
				// el flag es false cuando ha fallado el servicio para
				// buscar
				// solicitantes y titulares
				model.addAttribute("flagSearchFolder", false);
			}
			// Primero obtengo la lista de participaciones de mi BBDD,
			// ya
			// actualiza previamente desde el webServic
			List<VistaDatosExpediente> listaParticipantesParticipacion = relExpTerService
					.findParticipaciones(expediente.getIdExpediente());
			InitController.logger.info("[INICIO] Participantes " + listaParticipantesParticipacion.size());
			Integer idTercero = 0;

			// Sacamos el idTercero del solicitante titular
			for (int i = 0; i < listaParticipantesParticipacion.size(); i++) {

				model.addAttribute("listaSearch", listaParticipantesParticipacion.get(0).getVistaTercerosList());
				/// Sacamos el id tercero del solicitante titular
				for (int k = 0; k < listaParticipantesParticipacion.get(0).getVistaTercerosList().size(); k++) {
					if (null != listaParticipantesParticipacion.get(0).getVistaTercerosList().get(k)
							.getIdTipoTercero()) {
						if (listaParticipantesParticipacion.get(0).getVistaTercerosList().get(k).getIdTipoTercero()
								.compareTo(Constantes.PARTICIPACION_SOLICITANTE) == 0) {
							for (int h = 0; h < listaParticipantesParticipacion.get(0).getVistaTercerosList().get(k)
									.getDatosTercerosList().size(); h++) {

								if (listaParticipantesParticipacion.get(0).getVistaTercerosList().get(k)
										.getDatosTercerosList().get(h).getTipoParticipante()
										.compareTo(Constantes.PARTICIPANTE_TITULAR) == 0) {
									idTercero = listaParticipantesParticipacion.get(0).getVistaTercerosList().get(k)
											.getDatosTercerosList().get(h).getIdTercero();

								}

							}

						}

					}
				}

			}

			String nombreExpediente = "";
			if (datosTramitagune.getFolderNumber() == null) {// venimos del
																// cambio de
																// idioma
				nombreExpediente = expediente.getFolderNumber() + " - " + expediente.getTitulo();
			} else {
				nombreExpediente = datosTramitagune.getFolderNumber() + " - " + expediente.getTitulo();
			}

			model.addAttribute("lenguaje", idioma);
			model.addAttribute("nombreExpediente", nombreExpediente);
			model.addAttribute("expediente", expediente);

			// el flag es true cuando no ha fallado el servicio para
			// buscar
			// solicitantes y titulares
			model.addAttribute("idTercero", idTercero);

			Properties prop = Config.loadProperties(Constantes.FICHERO_CONFIGURACION);
			String url = prop.getProperty("urlVerDocumento");
			url = url.replace("[folderID]", datosTramitagune.getFolderId());
			model.addAttribute("urlVerDocumentos", url);

			return new ModelAndView("datosExpediente", "model", model);
		} else {// Se cambia el idioma para que se entre en la aplicacion
				// con el que llega como parametro

			model.addAttribute("folderNumber", datosTramitagune.getFolderNumber());
			return new ModelAndView("folderNoExiste");
		}

	}

	@RequestMapping(value = "/mantenimientos", method = { RequestMethod.POST, RequestMethod.GET })
	public String inicioMantenimientos(Model model, Usuario usuario) throws Exception {
		InitController.logger.info("[POST - INICIO] Acceso a la aplicacion por Init Con datos: ");
		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);

		Vector<String> rolesUsuario = SeguridadAplicacion
				.getRolesUsuario(SecurityContextHolder.getContext().getAuthentication());

		if (rolesUsuario.contains(SeguridadAplicacion.ROLE_AB61_IN_0008)) {

			model.addAttribute("roleAb61In0008", true);

			if (rolesUsuario.contains(SeguridadAplicacion.ROLE_TECNICO_TURISMO)) {
				model.addAttribute("roleTecnicoTurismo", true);
			} else {
				model.addAttribute("roleTecnicoTurismo", false);
			}

			if (rolesUsuario.contains(SeguridadAplicacion.ROLE_TECNICO_COMERCIO)) {
				model.addAttribute("roleTecnicoComercio", true);
			} else {
				model.addAttribute("roleTecnicoComercio", false);
			}

			if (rolesUsuario.contains(SeguridadAplicacion.ROLE_TECNICO_CONSUMO)) {
				model.addAttribute("roleTecnicoConsumo", true);
			} else {
				model.addAttribute("roleTecnicoConsumo", false);
			}

			model.addAttribute("plantillas", new Plantillas());
			model.addAttribute("origen", Constantes.origen.GESTION_PLANTILLAS);
			return "mantenimientoPlantillas";
		} else {

			model.addAttribute("roleAb61In0008", false);

			model.addAttribute("mantenimientoModuloAdministrativo", new ModuloAdministracion());
			model.addAttribute("origen", Constantes.origen.GESTION_MODULO_ADMINISTRACION);
			return "mantenimientoModuloAdministrativo";
		}
	}

	// private void cargarIdiomaTramitagune(String idioma, HttpServletRequest
	// httpRequest, HttpServletResponse response) {
	// // Se cambia el idioma para que se entre en la aplicacion
	// // con el que llega como parametro
	// Locale locale = new Locale(idioma);
	// LocaleContextHolder.setLocale(locale);
	// // Sobreescribir cookie
	// ((CookieLocaleResolver)
	// RequestContextUtils.getLocaleResolver(httpRequest)).setLocale(httpRequest,
	// response,
	// locale);
	// }

	/**
	 * 
	 * @param httpRequest
	 *            HttpServletRequest
	 * @param model
	 *            Model
	 * @param datosTramitagune
	 *            InitForm
	 * 
	 * @return ModelAndView
	 * @throws Exception
	 */
	@RequestMapping(value = "/initCambioIdioma", method = RequestMethod.POST)
	public ModelAndView initCambioIdioma(HttpServletRequest httpRequest, Model model, InitForm datosTramitagune,
			Usuario usuario) throws Exception {

		InitController.logger.info("[INICIO initCambioIdioma] Cambio de idioma.");

		return this.getAccess(httpRequest, model, datosTramitagune, usuario);

	}

}
