package com.ejie.ab61.control.expedientes;

import java.util.List;
import java.util.Properties;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
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.ResponseStatus;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.servlet.ModelAndView;

import com.ejie.ab61.clientesWS.X43ExpedienteElectronico.TFolderList;
import com.ejie.ab61.comun.Constantes;
import com.ejie.ab61.comun.utilidades.config.Config;
import com.ejie.ab61.model.expedientes.Expedientes;
import com.ejie.ab61.model.expedientes.RelExpTer;
import com.ejie.ab61.model.inicio.InitForm;
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;
import com.ejie.x38.control.bind.annotation.RequestJsonBody;
import com.ejie.x38.dto.JQGridRequestDto;
import com.ejie.x38.dto.JQGridResponseDto;
import com.ejie.x38.dto.JerarquiaDto;
import com.ejie.x38.dto.TableRowDto;

/**
 * RelExpTerController  
 * 
 *  
 */

@Controller
@SessionAttributes("usuario")
@RequestMapping(value = "/relexpter")
public class RelExpTerController {

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

	@Autowired
	private RelExpTerService relExpTerService;

	@Autowired
	private ExpedientesService expedientesService;

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

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

	/**
	 * Devuelve una lista de beans correspondientes a los valores de filtrados
	 * indicados en el objeto pasado como parametro.
	 *
	 * @param filterRelExpTer
	 *            RelExpTer Objeto que contiene los parametros de filtrado
	 *            utilizados en la busqueda.
	 * @return List<RelExpTer> Lista de objetos correspondientes a la busqueda
	 *         realizada.
	 */
	@RequestMapping(method = RequestMethod.GET)
	public @ResponseBody List<RelExpTer> getAll(@ModelAttribute RelExpTer filterRelExpTer) {
		RelExpTerController.logger.info("[GET - find_ALL] : Obtener RelExpTer por filtro");
		return this.relExpTerService.findAll(filterRelExpTer, null);
	}

	/**
	 * Operacion CRUD Edit. Modificacion del bean indicado.
	 *
	 * @param relExpTer
	 *            RelExpTer Bean que contiene la informacion a modificar.
	 * @return RelExpTer Bean resultante de la modificacion.
	 */
	@RequestMapping(method = RequestMethod.PUT)
	public @ResponseBody RelExpTer edit(@RequestBody RelExpTer relExpTer) {
		RelExpTer relExpTerAux = this.relExpTerService.update(relExpTer);
		RelExpTerController.logger.info("[PUT] : RelExpTer actualizado correctamente");
		return relExpTerAux;
	}

	/**
	 * @param model
	 *            Model
	 * @param initForm
	 *            initForm
	 * 
	 * @return ModelAndView
	 * @throws Exception
	 */
	@RequestMapping(value = "/maint", method = RequestMethod.POST)
	public ModelAndView mostrarInit(Model model, @ModelAttribute(value = "initForm") InitForm initForm, Usuario usuario)
			throws Exception {

		Integer idExpediente = initForm.getIdExpediente();
		String nombreExpediente = initForm.getFolderNumber() + " - " + initForm.getTituloExpediente();
		model.addAttribute("idExpediente", idExpediente);
		model.addAttribute("nombreExpediente", nombreExpediente);

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

		return mostrar(model, initForm, usuario);

	}

	private ModelAndView mostrar(Model model, InitForm initForm, Usuario usuario) throws Exception {

		String idioma;
		Expedientes expediente = new Expedientes();
		expediente = this.expedientesService.findByFolderId(initForm.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
			// caracteresi
			// 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());
				}
			}

			model.addAttribute("expediente", expediente);

			TFolderList resultado = expedientesService.obtenerInfoPlatea(initForm.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) {
					RelExpTerController.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);
			}

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

			if (initForm.getIdioma() == null) { // venimos del cambio de
												// idioma obtenemos
				// el
				// idioma de la aplicacion no el de
				// tramitagune
				idioma = LocaleContextHolder.getLocale().getLanguage();

			} else { // Si se llega de tramitagune
				// Se cambia el idioma para que se entre en la aplicacion
				// con el que llega como parametro
			}
			model.addAttribute("lenguaje", "es");
			model.addAttribute("nombreExpediente", nombreExpediente);

			// Primero obtengo la lista de participaciones de mi BBDD,
			// ya
			// actualiza previamente desde el webServic
			List<VistaDatosExpediente> listaParticipantesParticipacion = relExpTerService
					.findParticipaciones(expediente.getIdExpediente());
			RelExpTerController.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();

								}

							}

						}

					}
				}

			}

			// 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]", initForm.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", initForm.getFolderNumber());
			return new ModelAndView("folderNoExiste");
		}

	}

	/**
	 * Operacion CRUD Delete. Borrado del registro correspondiente al
	 * identificador especificado.
	 *
	 * @param idRelExpTer
	 *            Integer Identificador del objeto que se desea eliminar.
	 * @return RelExpTer Bean eliminado.
	 */
	@RequestMapping(value = "/{idRelExpTer}", method = RequestMethod.DELETE)
	@ResponseStatus(value = HttpStatus.OK)
	public @ResponseBody RelExpTer remove(@PathVariable Integer idRelExpTer) {
		RelExpTer relExpTer = new RelExpTer();
		relExpTer.setIdRelExpTer(idRelExpTer);
		this.relExpTerService.remove(relExpTer);
		RelExpTerController.logger.info("[DELETE] : RelExpTer borrado correctamente");
		return relExpTer;
	}

	/*
	 * METODOS COMPONENTE RUP_TABLE
	 * 
	 */

	/**
	 * Metodo de presentacion del RUP_TABLE.
	 * 
	 * @param model
	 *            Model
	 * @return String
	 */
	@RequestMapping(value = "/maint", method = RequestMethod.GET)
	public String getFormEdit(Model model) {
		RelExpTerController.logger.info("[GET - View] : relexpter");
		return "relexpter";
	}

	/**
	 * Operacion de filtrado del componente RUP_TABLE.
	 * 
	 * @param filterRelExpTer
	 *            RelExpTer Bean que contiene los parametros de filtrado a
	 *            emplear.
	 * @param jqGridRequestDto
	 *            Dto que contiene los parametros de configuracion propios del
	 *            RUP_TABLE a aplicar en el filtrado.
	 * @return JQGridResponseDto<RelExpTer> Dto que contiene el resultado del
	 *         filtrado realizado por el componente RUP_TABLE.
	 */
	@RequestMapping(value = "/filter", method = RequestMethod.POST)
	public @ResponseBody JQGridResponseDto<RelExpTer> filter(
			@RequestJsonBody(param = "filter") RelExpTer filterRelExpTer,
			@RequestJsonBody JQGridRequestDto jqGridRequestDto) {
		RelExpTerController.logger.info("[POST - filter] : Obtener RelExpTers");
		return this.relExpTerService.filter(filterRelExpTer, jqGridRequestDto, false);
	}

	/**
	 * Operacion de busqueda del componente RUP_TABLE.
	 * 
	 * @param filterRelExpTer
	 *            RelExpTer Bean que contiene los parametros de filtrado a
	 *            emplear.
	 * @param searchRelExpTer
	 *            RelExpTer Bean que contiene los parametros de busqueda a
	 *            emplear.
	 * @param jqGridRequestDto
	 *            Dto que contiene los parametros de configuracion propios del
	 *            RUP_TABLE a aplicar en la búsqueda.
	 * @return TableRowDto<RelExpTer> Dto que contiene el resultado de la
	 *         busqueda realizada por el componente RUP_TABLE.
	 */
	@RequestMapping(value = "/search", method = RequestMethod.POST)
	public @ResponseBody List<TableRowDto<RelExpTer>> search(
			@RequestJsonBody(param = "filter") RelExpTer filterRelExpTer,
			@RequestJsonBody(param = "search") RelExpTer searchRelExpTer,
			@RequestJsonBody JQGridRequestDto jqGridRequestDto) {
		RelExpTerController.logger.info("[POST - search] : Buscar RelExpTers");
		return this.relExpTerService.search(filterRelExpTer, searchRelExpTer, jqGridRequestDto, false);
	}

	/**
	 * Borrado multiple de registros
	 * 
	 * @param filterRelExpTer
	 *            RelExpTer Bean que contiene los parametros de filtrado a
	 *            emplear.
	 * @param jqGridRequestDto
	 *            Dto que contiene los parametros de configuracion propios del
	 *            RUP_TABLE a aplicar en la busqueda.
	 * @return List<String> Lista de los identificadores de los registros
	 *         eliminados.
	 * 
	 */
	@RequestMapping(value = "/deleteAll", method = RequestMethod.POST)
	@ResponseStatus(value = HttpStatus.OK)
	public @ResponseBody List<String> removeMultiple(@RequestJsonBody(param = "filter") RelExpTer filterRelExpTer,
			@RequestJsonBody JQGridRequestDto jqGridRequestDto) {
		RelExpTerController.logger.info("[POST - search] : [POST - removeMultiple] : Eliminar multiples RelExpTers");
		this.relExpTerService.removeMultiple(filterRelExpTer, jqGridRequestDto, false);
		RelExpTerController.logger.info("All entities correctly deleted!");

		return jqGridRequestDto.getMultiselection().getSelectedIds();
	}

	/*
	 * METODOS COMPONENTE RUP_TABLE - JERARQUIA
	 */

	/**
	 * Recupera los hijos de los registros desplegados en la visualizacion
	 * jerarquica.
	 * 
	 * @param filterRelExpTer
	 *            RelExpTer Bean que contiene los parametros de filtrado a
	 *            emplear.
	 * @param jqGridRequestDto
	 *            Dto que contiene los parametros de configuracion propios del
	 *            RUP_TABLE a aplicar en el filtrado.
	 * @return JQGridResponseDto<JerarquiaDto<RelExpTer>> Dto que contiene el
	 *         resultado del filtrado realizado por el componente RUP_TABLE.
	 */
	@RequestMapping(value = "/jerarquiaChildren", method = RequestMethod.POST)
	public @ResponseBody JQGridResponseDto<JerarquiaDto<RelExpTer>> jerarquiaChildren(
			@RequestJsonBody(param = "filter") RelExpTer filterRelExpTer,
			@RequestJsonBody JQGridRequestDto jqGridRequestDto) {
		RelExpTerController.logger.info("[POST - jerarquia] : Obtener RelExpTers jerarquia - Hijos");
		return this.relExpTerService.jerarquiaChildren(filterRelExpTer, jqGridRequestDto);
	}

}
