package com.ejie.ab79.service.expedientes;

import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;

import com.ejie.ab79.clientesWS.ab61WebService.Usuario;
import com.ejie.ab79.comun.Constantes;
import com.ejie.ab79.dao.RelEstInsDao;
import com.ejie.ab79.dao.expedientes.DatosDireccionesDao;
import com.ejie.ab79.dao.expedientes.RelExpDirDao;
import com.ejie.ab79.dao.expedientes.RelExpTerDao;
import com.ejie.ab79.model.expedientes.DatosDirecciones;
import com.ejie.ab79.model.expedientes.DatosTerceros;
import com.ejie.ab79.model.expedientes.RelExpDir;
import com.ejie.ab79.model.expedientes.RelExpTer;
import com.ejie.ab79.model.expedientes.TiposDireccion;
import com.ejie.ab79.model.expedientes.TiposTercero;
import com.ejie.ab79.model.inspecciones.Inspecciones;
import com.ejie.ab79.model.nora.T17Provincia;
import com.ejie.x38.dto.JerarquiaDto;
import com.ejie.x38.dto.TableRequestDto;
import com.ejie.x38.dto.TableResponseDto;
import com.ejie.x38.dto.TableRowDto;

/**
 * RelExpTerServiceImpl  
 * 
 *  
 */

@Service(value = "relExpTerService")
public class RelExpTerServiceImpl implements RelExpTerService {

	@Autowired
	private RelExpTerDao relExpTerDao;
	@Autowired
	private DatosDireccionesDao datosDireccionesDao;
	@Autowired
	private RelEstInsDao relEstInsDao;
	@Autowired
	private RelExpDirDao relExpDirDao;

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

	/**
	 * Guardar ubicacion y direccion del solicitante y si es bec tambien la
	 * puntacion
	 *
	 * @param relExpTerEmp
	 *            RelExpTerEmp Bean que contiene la informacion con la que se va
	 *            a crear el nuevo registro.
	 * @return RelExpTerEmp Bean resultante del proceso de creacion.
	 */
	public DatosDirecciones addDomicilioUbicacionSolicitante(HttpServletRequest request, Model model, Usuario usuario,
			Inspecciones inspeccion) {
		DatosDirecciones datosDireccionesUbicacion = new DatosDirecciones();

		Long idProvinciaUbicacion = 2L;
		Long idMunicipioUbicacion = 2L;
		Long idLocalidadUbicacion = 2L;

		if (inspeccion.getIdOrigenInspeccion().equals(Constantes.ORIGEN_CAMPAINA)
				|| inspeccion.getIdOrigenInspeccion().equals(Constantes.ORIGEN_INSPECCION_OFICIO)
				|| inspeccion.getIdOrigenInspeccion().equals(Constantes.ORIGEN_BUZON_FRAUDE)) {

			Long idTipoDireccionUbicacion = 1L;
			idTipoDireccionUbicacion = Constantes.ID_UBICACION_INVERSION;

			if (null != request.getParameter("idDireccionUbicacionInversion")
					&& !"".equals(request.getParameter("idDireccionUbicacionInversion"))) {
				datosDireccionesUbicacion
						.setIdDireccion(Integer.parseInt(request.getParameter("idDireccionUbicacionInversion")));
			}

			String establecimiento = request.getParameter("establecimiento");
			String identificadorEstablecimiento = request.getParameter("numeroRegistroUbicacion");
			String direccionUbicacion = request.getParameter("direccionUbicacion");
			String numeroUbicacion = request.getParameter("numeroUbicacion");
			String pisoUbicacion = request.getParameter("pisoUbicacion");
			String complementoDireccion = request.getParameter("complementoDireccionUbicacion");

			String letraUbicacion = request.getParameter("letraUbicacion");
			String escaleraUbicacion = request.getParameter("escaleraUbicacion");
			String codigoPostalUbicacion = request.getParameter("codigoPostalUbicacion");

			if (null != request.getParameter("idProvinciaUbicacion")
					&& !"".equalsIgnoreCase(request.getParameter("idProvinciaUbicacion"))) {
				idProvinciaUbicacion = Long.parseLong(request.getParameter("idProvinciaUbicacion"));
				RelExpTerServiceImpl.logger.info("idProvinciaUbicacion = " + idProvinciaUbicacion);
				datosDireccionesUbicacion.setIdProvincia(idProvinciaUbicacion);
				T17Provincia provincia = new T17Provincia();
				provincia.setId(request.getParameter("idProvinciaUbicacion"));
				datosDireccionesUbicacion.setProvincia(provincia);
			}

			if (null != request.getParameter("idMunicipioUbicacion")
					&& !"".equalsIgnoreCase(request.getParameter("idMunicipioUbicacion"))) {
				idMunicipioUbicacion = Long.parseLong(request.getParameter("idMunicipioUbicacion"));
				RelExpTerServiceImpl.logger.info("idMunicipioUbicacion = " + idMunicipioUbicacion);
				datosDireccionesUbicacion.setIdMunicipio(idMunicipioUbicacion);
			}

			if (null != request.getParameter("idLocalidadUbicacion")
					&& !"".equalsIgnoreCase(request.getParameter("idLocalidadUbicacion"))) {
				idLocalidadUbicacion = Long.parseLong(request.getParameter("idLocalidadUbicacion"));
				RelExpTerServiceImpl.logger.info("idLocalidadUbicacion = " + idLocalidadUbicacion);
				datosDireccionesUbicacion.setIdLocalidad(idLocalidadUbicacion);
			}

			TiposDireccion tiposDireccionUbicacion = new TiposDireccion();
			tiposDireccionUbicacion.setIdTipoDireccion(idTipoDireccionUbicacion);

			datosDireccionesUbicacion.setTiposDireccion(tiposDireccionUbicacion);
			datosDireccionesUbicacion.setCodigoPostal(codigoPostalUbicacion);
			datosDireccionesUbicacion.setDireccion(direccionUbicacion);
			datosDireccionesUbicacion.setEscalera(escaleraUbicacion);
			datosDireccionesUbicacion.setEstablecimiento(establecimiento);
			datosDireccionesUbicacion.setIdentificadorEstablecimiento(identificadorEstablecimiento);
			datosDireccionesUbicacion.setComplementoDireccion(complementoDireccion);
			datosDireccionesUbicacion.setLetra(letraUbicacion);
			datosDireccionesUbicacion.setNumero(numeroUbicacion);
			datosDireccionesUbicacion.setPiso(pisoUbicacion);
			datosDireccionesUbicacion.setUsuarioRegistro(usuario.getUsuario());
			datosDireccionesUbicacion.setUsuarioUltmodificacion(usuario.getUsuario());

			boolean hayCambiosDireccionUbicacion = this.cambiosDireccion(datosDireccionesUbicacion);

			RelExpTerServiceImpl.logger.info("Ubicacion Inversion = " + datosDireccionesUbicacion);

			if (hayCambiosDireccionUbicacion) {
				if (datosDireccionesUbicacion.getIdDireccion() != null) {
					this.datosDireccionesDao.updateByIdDireccion(datosDireccionesUbicacion);
				} else {
					this.datosDireccionesDao.add(datosDireccionesUbicacion);

					RelExpDir relExpDir = new RelExpDir();
					relExpDir.setIdDireccion(datosDireccionesUbicacion.getIdDireccion());
					relExpDir.setIdExpediente(inspeccion.getExpediente().getIdExpediente());
					relExpDir.setUsuarioRegistro(usuario.getUsuario());
					this.relExpDirDao.add(relExpDir);
				}
			}

		}

		return datosDireccionesUbicacion;

	}

	private boolean cambiosDireccion(DatosDirecciones datosDireccion) {
		return ((datosDireccion.getEstablecimiento() != null && !"".equals(datosDireccion.getEstablecimiento()))
				|| (datosDireccion.getIdentificadorEstablecimiento() != null
						&& !"".equals(datosDireccion.getIdentificadorEstablecimiento()))
				|| datosDireccion.getIdProvincia() != null || datosDireccion.getIdMunicipio() != null
				|| datosDireccion.getIdLocalidad() != null
				|| (datosDireccion.getDireccion() != null && !"".equals(datosDireccion.getDireccion()))
				|| (datosDireccion.getNumero() != null && !"".equals(datosDireccion.getNumero()))
				|| (datosDireccion.getEscalera() != null && !"".equals(datosDireccion.getEscalera()))
				|| (datosDireccion.getPiso() != null && !"".equals(datosDireccion.getPiso()))
				|| (datosDireccion.getLetra() != null && !"".equals(datosDireccion.getLetra()))
				|| (datosDireccion.getComplementoDireccion() != null
						&& !"".equals(datosDireccion.getComplementoDireccion()))
				|| (datosDireccion.getCodigoPostal() != null && !"".equals(datosDireccion.getCodigoPostal())));
	}

	/**
	 * Finds a single row in the RelExpTer table.
	 *
	 * @param relExpTer
	 *            RelExpTer
	 * @return RelExpTer
	 */
	public RelExpTer find(RelExpTer relExpTer) {
		return (RelExpTer) this.relExpTerDao.find(relExpTer);
	}

	/**
	 * Deletes a single row in the RelExpTer table.
	 *
	 * @param relExpTer
	 *            RelExpTer
	 */
	@Transactional(rollbackFor = Throwable.class)
	public void remove(RelExpTer relExpTer) {
		this.relExpTerDao.remove(relExpTer);
	}

	/**
	 * Finds a list of rows in the RelExpTer table.
	 *
	 * @param relExpTer
	 *            RelExpTer
	 * @param tableRequestDto
	 *            TableRequestDto
	 * @return List<RelExpTer>
	 */
	public List<RelExpTer> findAll(RelExpTer relExpTer, TableRequestDto tableRequestDto) {
		return (List<RelExpTer>) this.relExpTerDao.findAll(relExpTer, tableRequestDto);
	}

	/**
	 * Finds rows in the RelExpTer table using like.
	 *
	 * @param relExpTer
	 *            RelExpTer
	 * @param tableRequestDto
	 *            TableRequestDto
	 * @param startsWith
	 *            Boolean
	 * @return List<RelExpTer>
	 */
	public List<RelExpTer> findAllLike(RelExpTer relExpTer, TableRequestDto tableRequestDto, Boolean startsWith) {
		return (List<RelExpTer>) this.relExpTerDao.findAllLike(relExpTer, tableRequestDto, startsWith);
	}

	/*
	 * OPERACIONES RUP_TABLE
	 */

	/**
	 * Removes rows from the RelExpTer table.
	 *
	 * @param filterRelExpTer
	 *            RelExpTer
	 * @param tableRequestDto
	 *            TableRequestDto
	 * @param startsWith
	 *            Boolean
	 */
	public void removeMultiple(RelExpTer filterRelExpTer, TableRequestDto tableRequestDto, Boolean startsWith) {
		this.relExpTerDao.removeMultiple(filterRelExpTer, tableRequestDto, startsWith);
	}

	/**
	 * Obtener lista de participaciones y direcciones del solicitante titular
	 * 
	 * 
	 * @param idExpediente
	 *            Integer
	 * 
	 */
	public List<RelExpTer> findParticipaciones(Integer idExpediente, Integer idInspeccion) {

		List<RelExpTer> listaParticipantes = new ArrayList<RelExpTer>();

		if (idExpediente != null) {
			listaParticipantes = this.relExpTerDao.findParticipantes(idExpediente);
		} else {
			listaParticipantes = this.relEstInsDao.findParticipantes(idInspeccion);
		}

		// Participación SOLICITANTE (PARTICIPANT_ID) -> Tipo Tercero = 1
		// -Titular
		// -Representate
		// -Otros Interesados
		// Participación AFECTADO (PARTICIPANT_ID) -> Tipo Tercero = 3
		// -Titular
		// -Representate
		// -Otros Interesados
		// REPERESETANTE LEGAL -> Tipo Tercero = 6
		// PERSONA CONTACTO -> Tipo Tercero = 2
		// DENUNCIADO PROVISIONAL -> Tipo Tercero = 7

		List<RelExpTer> listaParticipaciones = new ArrayList<RelExpTer>();
		String participantIdAnterior = "";
		TiposTercero tipoTerceroAnterior = new TiposTercero();

		RelExpTer participacion = null;
		List<DatosTerceros> listaParticipantesParticipacion = null;

		for (int contadorParticipante = 0; contadorParticipante < listaParticipantes.size(); contadorParticipante++) {

			RelExpTer participante = listaParticipantes.get(contadorParticipante);

			// Si tenemos una PARTICIPACIÓN de DIFERENTE tipo a la anterior hay
			// que crear una participación nueva
			// Si tenemos la misma PARTICIPACIÓN pero con PARTICIPANT_ID
			// DIFERENTE también tenemos que crear una participación nueva
			if ((listaParticipantes.get(contadorParticipante).getTiposTercero()
					.getIdTipoTercero() != tipoTerceroAnterior.getIdTipoTercero())
					|| (participante.getTiposTercero().getIdTipoTercero() == tipoTerceroAnterior.getIdTipoTercero()
							&& participante.getParticipantId() != null
							&& !participante.getParticipantId().equals(participantIdAnterior))) {
				if (participacion != null) {
					listaParticipaciones.add(participacion);
				}
				participacion = new RelExpTer();
				listaParticipantesParticipacion = new ArrayList<DatosTerceros>();
			}

			tipoTerceroAnterior.setIdTipoTercero(participante.getTiposTercero().getIdTipoTercero());
			participantIdAnterior = participante.getParticipantId();

			DatosTerceros datosTercero = new DatosTerceros();

			datosTercero.setIdTercero(participante.getDatosTerceros().getIdTercero());
			datosTercero.setDocumento(participante.getDatosTerceros().getDocumento());
			datosTercero.setTipoDocumento(participante.getDatosTerceros().getTipoDocumento());
			String nombre = "";
			if (participante.getDatosTerceros().getNombre() != null) {
				nombre = participante.getDatosTerceros().getNombre().replaceAll("[\"]", "");
			}
			String apellido1 = "";
			if (participante.getDatosTerceros().getApellido1() != null) {
				apellido1 = participante.getDatosTerceros().getApellido1().replaceAll("[\"]", "");
			}
			String apellido2 = "";
			if (participante.getDatosTerceros().getApellido2() != null) {
				apellido2 = participante.getDatosTerceros().getApellido2().replaceAll("[\"]", "");
			}

			datosTercero.setNombre(nombre);
			datosTercero.setApellido1(apellido1);
			datosTercero.setApellido2(apellido2);
			datosTercero.setTipoParticipante(participante.getDatosTerceros().getTipoParticipante());
			if (participante.getDatosTerceros().getDatoDireccion().getIdDireccion() != null) {
				if (participante.getDatosTerceros().getTipoParticipante() == Constantes.PARTICIPANTE_REPRESENTANTE) {
					participacion.setTipoParticipanteCastellano(Constantes.REPRESENTANTE_CAS);
					participacion.setTipoParticipanteEuskera(Constantes.REPRESENTANTE_EUS);

				} else {
					participacion.setTipoParticipanteCastellano(Constantes.TITULAR_CAS);
					participacion.setTipoParticipanteEuskera(Constantes.TITULAR_EUS);
				}
				participacion.setUbicacionDireccionPostal(participante.getDatosTerceros().getDatoDireccion());
			}

			listaParticipantesParticipacion.add(datosTercero);

			participacion.setIdRelExpTer(participante.getIdRelExpTer());
			participacion.setParticipantId(participante.getParticipantId());
			participacion.setIdTipoParticipacion(participante.getTiposTercero().getIdTipoTercero());
			participacion.setTipoParticipacionCastellano(participante.getTiposTercero().getDescripcionCastellano());
			participacion.setTipoParticipacionEuskera(participante.getTiposTercero().getDescripcionEuskera());
			if (participacion.getIdSubtipoParticipacion() == null) {
				if (participante.getSubtipoTercero() != null) {
					participacion.setIdSubtipoParticipacion(participante.getSubtipoTercero().getIdSubtipoTercero());
					participacion.setSubtipoParticipacionCastellano(
							participante.getSubtipoTercero().getDescripcionCastellano());
					participacion
							.setSubtipoParticipacionEuskera(participante.getSubtipoTercero().getDescripcionEuskera());
				}
			}

			participacion.setListaDatosTerceros(listaParticipantesParticipacion);
			if (contadorParticipante == listaParticipantes.size() - 1) {
				if (participacion != null) {
					listaParticipaciones.add(participacion);
				}
			}
		}

		return listaParticipaciones;

	}

	/**
	 * Filter method in the RelExpTer table.
	 *
	 * @param filterRelExpTer
	 *            RelExpTer
	 * @param tableRequestDto
	 *            TableRequestDto
	 * @param startsWith
	 *            Boolean
	 * @return TableResponseDto<RelExpTer>
	 */
	public TableResponseDto<RelExpTer> filter(RelExpTer filterRelExpTer, TableRequestDto tableRequestDto,
			Boolean startsWith) {
		List<RelExpTer> listaRelExpTer = this.relExpTerDao.findAllLike(filterRelExpTer, tableRequestDto, false);
		Long recordNum = this.relExpTerDao.findAllLikeCount(filterRelExpTer != null ? filterRelExpTer : new RelExpTer(),
				false);

		TableResponseDto<RelExpTer> usuarioDto = new TableResponseDto<RelExpTer>(tableRequestDto, recordNum,
				listaRelExpTer);

		if (tableRequestDto.getMultiselection().getSelectedIds() != null) {
			List<TableRowDto<RelExpTer>> reorderSelection = this.relExpTerDao.reorderSelection(filterRelExpTer,
					tableRequestDto, startsWith);
			usuarioDto.setReorderedSelection(reorderSelection);
			usuarioDto.addAdditionalParam("reorderedSelection", reorderSelection);
			usuarioDto.addAdditionalParam("selectedAll", tableRequestDto.getMultiselection().getSelectedAll());
		}
		if (tableRequestDto.getSeeker().getSelectedIds() != null) {
			tableRequestDto.setMultiselection(tableRequestDto.getSeeker());
			List<TableRowDto<RelExpTer>> reorderSeeker = this.relExpTerDao.reorderSelection(filterRelExpTer,
					tableRequestDto, startsWith);
			usuarioDto.setReorderedSeeker(reorderSeeker);
			usuarioDto.addAdditionalParam("reorderedSeeker", reorderSeeker);
		}
		return usuarioDto;
	}

	/**
	 * Searches rows in the RelExpTer table.
	 *
	 * @param filterRelExpTer
	 *            RelExpTer
	 * @param searchRelExpTer
	 *            RelExpTer
	 * @param tableRequestDto
	 *            TableRequestDto
	 * @param startsWith
	 *            Boolean
	 * @return List<TableRowDto<RelExpTer>>
	 */
	public List<TableRowDto<RelExpTer>> search(RelExpTer filterRelExpTer, RelExpTer searchRelExpTer,
			TableRequestDto tableRequestDto, Boolean startsWith) {
		return this.relExpTerDao.search(filterRelExpTer, searchRelExpTer, tableRequestDto, startsWith);
	}

	/**
	 * Reorder the selection made in RelExpTer table.
	 *
	 * @param filterRelExpTer
	 *            RelExpTer
	 * @param tableRequestDto
	 *            TableRequestDto
	 * @param startsWith
	 *            Boolean
	 * @return Object
	 */
	public Object reorderSelection(RelExpTer filterRelExpTer, TableRequestDto tableRequestDto, Boolean startsWith) {
		return this.relExpTerDao.reorderSelection(filterRelExpTer, tableRequestDto, startsWith);
	}

	/*
	 * OPERACIONES RUP_TABLE JERARQUIA
	 */

	/**
	 * Finder method for siblings rows in the hierarchical the RelExpTer table.
	 *
	 * @param filterRelExpTer
	 *            RelExpTer
	 * @param tableRequestDto
	 *            TableRequestDto
	 * @return TableResponseDto<JerarquiaDto<RelExpTer>>
	 */
	public TableResponseDto<JerarquiaDto<RelExpTer>> jerarquiaChildren(RelExpTer filterRelExpTer,
			TableRequestDto tableRequestDto) {
		TableResponseDto<JerarquiaDto<RelExpTer>> tableResponseDto = new TableResponseDto<JerarquiaDto<RelExpTer>>();
		tableResponseDto.addAdditionalParam(TableResponseDto.CHILDREN,
				this.relExpTerDao.findAllChild(filterRelExpTer, tableRequestDto));
		return tableResponseDto;
	}

	/**
	 * Exporta Datos al clipBoard
	 *
	 */
	public List<RelExpTer> getMultiple(RelExpTer filterRelExpTer, TableRequestDto tableRequestDto, Boolean startsWith) {
		return this.relExpTerDao.getMultiple(filterRelExpTer, tableRequestDto, startsWith);
	}

	public RelExpTer updateSubtipo(RelExpTer relexpter) {
		return this.relExpTerDao.updateSubtipo(relexpter);
	}

}
