package com.ejie.ab79.service;

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.DatosTercerosDao;
import com.ejie.ab79.dao.inspecciones.CampainasInspeccionDao;
import com.ejie.ab79.dao.inspecciones.InspeccionesDao;
import com.ejie.ab79.model.RelEstIns;
import com.ejie.ab79.model.expedientes.DatosDirecciones;
import com.ejie.ab79.model.expedientes.DatosTerceros;
import com.ejie.ab79.model.expedientes.TiposDireccion;
import com.ejie.ab79.model.inspecciones.CampainasInspeccion;
import com.ejie.ab79.model.inspecciones.Inspecciones;
import com.ejie.ab79.model.nora.T17Provincia;
import com.ejie.ab79.service.inspecciones.InspeccionesService;
import com.ejie.x38.dto.JerarquiaDto;
import com.ejie.x38.dto.TableRequestDto;
import com.ejie.x38.dto.TableResponseDto;
import com.ejie.x38.dto.TableRowDto;

/**
 * RelEstInsServiceImpl  
 * 
 *  
 */

@Service(value = "relEstInsService")
public class RelEstInsServiceImpl implements RelEstInsService {

	@Autowired
	private RelEstInsDao relEstInsDao;
	@Autowired
	private DatosDireccionesDao datosDireccionesDao;
	@Autowired
	private InspeccionesDao inspeccionesDao;
	@Autowired
	private CampainasInspeccionDao campainasInspeccionDao;
	@Autowired
	private DatosTercerosDao datosTerceroDao;
	@Autowired
	private InspeccionesService inspeccionesService;

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

	/**
	 * Inserts a single row in the RelEstIns table.
	 *
	 * @param relEstIns
	 *            RelEstIns
	 * @return RelEstIns
	 */
	@Override
	@Transactional(rollbackFor = Throwable.class)
	public RelEstIns add(RelEstIns relEstIns) {
		return this.relEstInsDao.add(relEstIns);
	}

	/**
	 * Updates a single row in the RelEstIns table.
	 *
	 * @param relEstIns
	 *            RelEstIns
	 * @return RelEstIns
	 */
	@Override
	@Transactional(rollbackFor = Throwable.class)
	public RelEstIns update(RelEstIns relEstIns) {
		return this.relEstInsDao.update(relEstIns);
	}

	/**
	 * Finds a single row in the RelEstIns table.
	 *
	 * @param relEstIns
	 *            RelEstIns
	 * @return RelEstIns
	 */
	@Override
	public RelEstIns find(RelEstIns relEstIns) {
		return this.relEstInsDao.find(relEstIns);
	}

	/**
	 * Deletes a single row in the RelEstIns table.
	 *
	 * @param relEstIns
	 *            RelEstIns
	 */
	@Override
	@Transactional(rollbackFor = Throwable.class)
	public void remove(RelEstIns relEstIns) {
		this.relEstInsDao.remove(relEstIns);
	}

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

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

	/*
	 * OPERACIONES RUP_TABLE
	 */

	/**
	 * Removes rows from the RelEstIns table.
	 *
	 * @param filterRelEstIns
	 *            RelEstIns
	 * @param tableRequestDto
	 *            TableRequestDto
	 * @param startsWith
	 *            Boolean
	 */
	@Override
	public void removeMultiple(RelEstIns filterRelEstIns, TableRequestDto tableRequestDto, Boolean startsWith) {
		this.relEstInsDao.removeMultiple(filterRelEstIns, tableRequestDto, startsWith);
	}

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

		TableResponseDto<RelEstIns> usuarioDto = new TableResponseDto<RelEstIns>(tableRequestDto, recordNum,
				listaRelEstIns);

		if (tableRequestDto.getMultiselection().getSelectedIds() != null) {
			List<TableRowDto<RelEstIns>> reorderSelection = this.relEstInsDao.reorderSelection(filterRelEstIns,
					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<RelEstIns>> reorderSeeker = this.relEstInsDao.reorderSelection(filterRelEstIns,
					tableRequestDto, startsWith);
			usuarioDto.setReorderedSeeker(reorderSeeker);
			usuarioDto.addAdditionalParam("reorderedSeeker", reorderSeeker);
		}
		return usuarioDto;
	}

	/**
	 * Searches rows in the RelEstIns table.
	 *
	 * @param filterRelEstIns
	 *            RelEstIns
	 * @param searchRelEstIns
	 *            RelEstIns
	 * @param tableRequestDto
	 *            TableRequestDto
	 * @param startsWith
	 *            Boolean
	 * @return List<TableRowDto<RelEstIns>>
	 */
	@Override
	public List<TableRowDto<RelEstIns>> search(RelEstIns filterRelEstIns, RelEstIns searchRelEstIns,
			TableRequestDto tableRequestDto, Boolean startsWith) {
		return this.relEstInsDao.search(filterRelEstIns, searchRelEstIns, tableRequestDto, startsWith);
	}

	/**
	 * Reorder the selection made in RelEstIns table.
	 *
	 * @param filterRelEstIns
	 *            RelEstIns
	 * @param tableRequestDto
	 *            TableRequestDto
	 * @param startsWith
	 *            Boolean
	 * @return Object
	 */
	@Override
	public Object reorderSelection(RelEstIns filterRelEstIns, TableRequestDto tableRequestDto, Boolean startsWith) {
		return this.relEstInsDao.reorderSelection(filterRelEstIns, tableRequestDto, startsWith);
	}

	/*
	 * OPERACIONES RUP_TABLE JERARQUIA
	 */

	/**
	 * Finder method in the hierarchical the RelEstIns table.
	 *
	 * @param filterRelEstIns
	 *            RelEstIns
	 * @param tableRequestDto
	 *            TableRequestDto
	 * @param startsWith
	 *            Boolean
	 * @return TableResponseDto<JerarquiaDto<RelEstIns>>
	 */
	@Override
	public TableResponseDto<JerarquiaDto<RelEstIns>> jerarquia(RelEstIns filterRelEstIns,
			TableRequestDto tableRequestDto, Boolean startsWith) {
		List<JerarquiaDto<RelEstIns>> listaRelEstIns = this.relEstInsDao.findAllLikeJerarquia(filterRelEstIns,
				tableRequestDto);
		Long recordNum = this.relEstInsDao.findAllLikeCountJerarquia(filterRelEstIns, tableRequestDto);
		return new TableResponseDto<JerarquiaDto<RelEstIns>>(tableRequestDto, recordNum, listaRelEstIns);
	}

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

	/**
	 * Exporta Datos al clipBoard
	 *
	 */
	@Override
	public List<RelEstIns> getMultiple(RelEstIns filterRelEstIns, TableRequestDto tableRequestDto, Boolean startsWith) {
		return this.relEstInsDao.getMultiple(filterRelEstIns, tableRequestDto, startsWith);
	}

	@Override
	public RelEstIns findByInspeccion(Inspecciones inspecciones) {
		return this.relEstInsDao.findByInspeccion(inspecciones);
	}

	@Override
	@Transactional
	public void guardarSinExpediente(HttpServletRequest request, Model model, Usuario usuario, Integer idInspeccion) {

		DatosDirecciones datosDireccion = new DatosDirecciones();

		Long idProvinciaUbicacion = 1L;
		Long idMunicipioUbicacion = 1L;
		Long idLocalidadUbicacion = 1L;

		// Recogemos los valores de los datos introducidos
		String idDireccion = 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 letraUbicacion = request.getParameter("letraUbicacion");
		String escaleraUbicacion = request.getParameter("escaleraUbicacion");
		String codigoPostalUbicacion = request.getParameter("codigoPostalUbicacion");
		String complementoDireccionUbicacion = request.getParameter("complementoDireccionUbicacion");

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

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

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

		TiposDireccion tiposDireccionUbicacion = new TiposDireccion();
		tiposDireccionUbicacion.setIdTipoDireccion(Constantes.ID_UBICACION_INVERSION);

		if (null != idDireccion && !"".equals(idDireccion)) {
			datosDireccion.setIdDireccion(Integer.parseInt(idDireccion));
		}
		datosDireccion.setTiposDireccion(tiposDireccionUbicacion);
		datosDireccion.setCodigoPostal(codigoPostalUbicacion);
		datosDireccion.setDireccion(direccionUbicacion);
		datosDireccion.setEscalera(escaleraUbicacion);
		datosDireccion.setEstablecimiento(establecimiento);
		if (null != identificadorEstablecimiento && !"".equals(identificadorEstablecimiento)) {
			datosDireccion.setIdentificadorEstablecimiento(identificadorEstablecimiento);
		}
		datosDireccion.setLetra(letraUbicacion);
		datosDireccion.setNumero(numeroUbicacion);
		datosDireccion.setPiso(pisoUbicacion);
		datosDireccion.setComplementoDireccion(complementoDireccionUbicacion);

		Inspecciones inspeccion = new Inspecciones();
		inspeccion.setIdInspeccion(idInspeccion);
		inspeccion = this.inspeccionesDao.find(inspeccion);

		// Buscamos la relación con la inspección
		RelEstIns relEstIns = this.relEstInsDao.findByInspeccion(inspeccion);

		if (relEstIns.getIdTercero() != null) {
			datosDireccion.setDatosTerceros(new DatosTerceros(relEstIns.getIdTercero()));
		}

		boolean hayCambiosDireccion = this.cambiosDireccion(datosDireccion);

		if (hayCambiosDireccion) {
			if (datosDireccion.getIdDireccion() != null) {
				// Update
				datosDireccion.setUsuarioUltmodificacion(usuario.getUsuario());
				this.datosDireccionesDao.updateByIdDireccion(datosDireccion);
			} else {
				// Insert
				datosDireccion.setUsuarioRegistro(usuario.getUsuario());
				datosDireccion = this.datosDireccionesDao.add(datosDireccion);
			}
		}
		relEstIns.setIdDireccion(datosDireccion.getIdDireccion());

		// Generamos el título => (provincia) [identificadorCampaina] nombre
		// apellido1 apellido2
		CampainasInspeccion campaina = new CampainasInspeccion();
		campaina.setIdCampaina(inspeccion.getCampaina().getIdCampaina());
		campaina = this.campainasInspeccionDao.find(campaina);

		inspeccion.setCampaina(campaina);

		DatosTerceros datosTercero = new DatosTerceros();
		datosTercero.setIdTercero(relEstIns.getIdTercero());
		datosTercero = this.datosTerceroDao.find(datosTercero);

		if (inspeccion.getIdOrigenInspeccion().equals(Constantes.ORIGEN_CAMPAINA)
				|| inspeccion.getIdOrigenInspeccion().equals(Constantes.ORIGEN_INSPECCION_OFICIO)
				|| inspeccion.getIdOrigenInspeccion().equals(Constantes.ORIGEN_BUZON_FRAUDE)) {
			String titulo = this.inspeccionesService.crearTitulo(inspeccion, datosTercero, datosDireccion);
			relEstIns.setTitulo(titulo);
		}

		relEstIns.setUsuarioUltModificacion(usuario.getUsuario());

		this.relEstInsDao.update(relEstIns);

	}

	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.getCodigoPostal() != null && !"".equals(datosDireccion.getCodigoPostal())));
	}

	@Override
	public void removeByInspeccion(Inspecciones inspeccion) {
		this.relEstInsDao.removeByInspeccion(inspeccion);
	}

	@Override
	public void eliminarTercero(DatosTerceros datosTercero) {
		this.relEstInsDao.eliminarTercero(datosTercero);
	}

	@Override
	public void actualizarTituloInspeccion(RelEstIns relEstIns) {
		this.relEstInsDao.actualizarTituloInspeccion(relEstIns);
	}

}
